how can i guarantee docker host volume have the right permission after multiple `docker-compose up` & `docker-compose-down`
Asked Answered
A

1

1

I am developing a Node.js app that uses Postgres as its database. I write a "docker-compose.yml" file for Node.js & Postgres.

I create pgdata directory, Then I write my Dockerfile to build Node.js image:

FROM node:14.15.0

WORKDIR "/usr/src/app"

CMD [ "npm", "start" ]

And this is how I write my "docker-compose.yml" file:

version: "3.7"
services:
  db:
    image: postgres:13
    env_file:
      - ./.env.postgres
    volumes:
      - type: bind
        source: ./pgdata
        target: /var/lib/postgresql/data
        volume:
          nocopy: true
    environment:
      PGDATA: /var/lib/postgresql/data/pgdata
    container_name: ${APP_NAME}-db

  express-app:
    image: ${APP_NAME}-express-app:1
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - type: bind
        source: .
        target: /usr/src/app
        volume:
          nocopy: true
    env_file:
      - ./.env
      - ./.env.postgres
    depends_on:
      - db
    ports:
      - "${APP_PORT}:${DOCKER_CONTAINER_APP_PORT}"
    environment:
      POSTGRES_HOST: db

And then I start my app by running this command: docker-compose up --build and everything was OK. docker build image and create its containers. My app works fine but when I remove its image (node.js image, for some reasons), and run the docker-compose up --build command it throws this error for me:

Building with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/
Building express-app
error checking context: 'can't stat '/home/project1/pgdata/pgdata''.
ERROR: Service 'express-app' failed to build

And after that, I realize that docker create a directory inside the mounted directory (pgdata)

So I check it permission with 'ls -ltrha' and this is the output:

total 12K
drwxr-xr-x  3 mjb              mjb  4.0K FEB   20 12:34 .
drwx------ 19 systemd-coredump root 4.0K FEB   20 12:34 pgdata
drwxr-xr-x  6 mjb              mjb  4.0K FEB   21 12:19 ..
Alexine answered 22/2, 2021 at 11:23 Comment(0)
L
3

When you build a Docker image, the context directory you give (typically the current directory) is sent to the Docker daemon to build. The goal of this is to be able to COPY files from the context directory into the Docker image, so you can have a self-contained image that can run without separately needing the application code mounted in.

In your setup, the database content is stored in ./pgdata, so a subdirectory of the directory you're using as a build context. The data in that directory will be owned by the user in the database container, which frequently won't be the same user as the host user (and that's okay). But now since a different user owns the ./pgdata directory, the image build sequence can't send the build context directory to the Docker daemon, hence the error you get.

You can create a .dockerignore file to tell Docker to exclude the database data from the image build (you will never want this in your image no matter what). Put this in the same directory as the Dockerfile and docker-compose.yml file. It can contain just

# .dockerignore
# Do not copy host's node_modules into the image; we will RUN npm install
node_modules
# Do not copy database storage into the image at all
pgdata
Lewls answered 22/2, 2021 at 11:38 Comment(1)
Thanks. Is there any security reason for this? I think it is to prevent me/hackers to access other users, What do you think? Am I right?Alexine

© 2022 - 2024 — McMap. All rights reserved.