Search code examples
dockerdocker-composedockerfiledocker-registrydockerhub

Why on another machine my docker-compose app is throwing error about missing files if I included every file in my docker image?


I wanted to ask about some errors in my docker-compose app that I cannot comprehend. I am not sure If I am making some kind of code mistake or I am misunderstanding whole concept of docker compose.

Here are things that I am doing:

  1. I built docker-compose on laptop A - everything is working

  2. In docker-compose.yml I changed name if my image to mynick/myimage:test

  3. I pushed my "custom" image to docker hub using docker-compose push

  4. I copied my docker-compose.yml file and .env file to laptop B

  5. I did docker-compose --env-file env up

  6. Every image was successfully downloaded from docker hub and my app started

  7. After boot up of my app I am seeing errors about missing files and directories from my main app folder (which also had docker-compose and docker file inside so it should include everything already?)

And errors that I see in step 7 are for example "missing alembic.ini file". And when I manually copy it to laptop B (folder when is docker-compose.yml located) then I am seeing error "FAILED: Path doesn't exist: '/my_app/alembic"

I find it weird because my custom image had command "COPY . /my_app" so as far as I understand it should copy all the files inside the image, so it should have all the files and exactly the same folder structure?

And this folder structure looks similar to this: My folder structure looks like that:

->my_app
----alembic.ini
---->alembic
-------->versions
------------.keep
--------various_stuff
----main.py
----Dockerfile
----docker-compose.yml
----various_stuff

My Dockerfile:

FROM python:3-slim-buster
ENV PYTHONUNBUFFERED=1
WORKDIR /myapp
COPY requirements.txt requirements.txt
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt
COPY . /myapp
CMD 0.0.0.0:$PORT

My docker-compose.yml:

version: "3.8"

services:
  database:
    container_name: postgresql_db
    image: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}

  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
    ports:
      - "5050:80"
    depends_on:
      - database

  myapp:
    container_name: myapp
    build: .
    image: myapp:main
    command: bash -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000"
    volumes:
      - .:/myapp
    ports:
      - "8000:8000"
    depends_on:
      - database
    restart: always

  migration:
    image: myapp:main
    command: bash -c "alembic revision --autogenerate -m 'New Migration'"
    volumes:
      - .:/myapp
    depends_on:
      - myapp

  upgrade_head:
    image: myapp:main
    command: bash -c "alembic upgrade head"
    volumes:
      - .:/myapp
    depends_on:
      - migration

And my docker-compose.yml after I change it to run on other computers:

version: "3.8"

services:
  database:
    container_name: postgresql_db
    image: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}

  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
    ports:
      - "5050:80"
    depends_on:
      - database

  myapp:
    container_name: myapp
    build: .
    image: dockerhubnick/myappimage:latest
    command: bash -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000"
    volumes:
      - .:/myapp
    ports:
      - "8000:8000"
    depends_on:
      - database
    restart: always

  migration:
    image: dockerhubnick/myappimage:latest
    command: bash -c "alembic revision --autogenerate -m 'New Migration'"
    volumes:
      - .:/myapp
    depends_on:
      - myapp

  upgrade_head:
    image: dockerhubnick/myappimage:latest
    command: bash -c "alembic upgrade head"
    volumes:
      - .:/myapp
    depends_on:
      - migration

Currently I am not sure if I am making some code related program, or I misunderstood how docker-compose works?


Solution

  • The problem is the volume directive in the second docker-compose.yml file. It is overwriting the files that you copied into the image with the contents of the local directory. You don't notice a difference on the first laptop, because the local directory contains the same files that get copied into the image. But on the second laptop you get an error, because the project files are missing.

    Remove the volume directives in the docker-compose.yml file for the second laptop, and the errors should disappear. Without the volume, the files that you copied into the image will be used as excepted.