I have a Django app whose Docker build is two stages:
- 1st stage uses a Node image to compile static assets using Gulp. This stage creates the
node_modules
directory and a folder namedbuild
. - 2nd stage is supposed to copy files from the previous stage and install the python dependencies.
My problem is that the new folders created by the 1st stage aren't being carried over.
Here's the Dockerfile:
# Dockerfile
# STAGE 1: Compile static assets
# ----------------------------
FROM node:17-slim as client-builder
ARG APP_HOME=/code
WORKDIR ${APP_HOME}
COPY . ${APP_HOME}
# npm's post-install script will use GulpJs to compile the static
# assets into a folder named "build"
RUN npm install && npm cache clean --force
# STAGE 2: Add python dependencies
# ----------------------------
FROM python:3.10-slim as python-build-stage
ARG APP_HOME=/code
ARG USERNAME=docker
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV POETRY_NO_INTERACTION 1
ENV POETRY_VIRTUALENVS_CREATE false
ENV POETRY_CACHE_DIR "/var/cache/pypoetry"
ENV POETRY_HOME "/usr/local"
WORKDIR ${APP_HOME}
# Create the user
RUN addgroup --system ${USERNAME} \
&& adduser --system --ingroup ${USERNAME} ${USERNAME}
# Install apt packages
RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages
build-essential \
# psycopg2 dependencies
libpq-dev \
# dev utils
git zsh
# Copy project files
COPY --from=client-builder --chown=${USERNAME}:${USERNAME} ${APP_HOME} ${APP_HOME}
# Install python dependencies
RUN pip install --upgrade pip
RUN pip install poetry
RUN poetry install --no-interaction --no-ansi
# Set default shell
RUN chsh -s $(which zsh)
# Set user
USER ${USERNAME}
Things I tried
- The first stage runs correctly. Gulp.js is able to run, so
node_modules
must have been created correctly. I tried to debug the first stage and saw all files being created correctly. - Also tried running as root
- I also tried to "log" the contents of the workspace with
RUN ls . >> /tmp/ls.txt
and the contents of the file list surprised me:
I can see the folders being listed there:
But when I ls
the actual workspace, I don't see anything:
What is happening?
Docker-compose
I forgot to mention, I'm using docker-compose to build and start these images:
version: '3.10'
services:
db.postgres:
image: "postgres"
env_file: .env
volumes:
- postgres_data:/var/lib/postgresql/data/
ports:
- 5432:5432
web:
build: .
command: >
zsh -c "python3 /code/manage.py migrate &&
python3 /code/manage.py runserver 0.0.0.0:8000"
env_file: .env
volumes:
- .:/code
ports:
- 8000:8000
depends_on:
- db.postgres
restart: on-failure:5
volumes:
postgres_data:
CodePudding user response:
The problem here is that during the build process you're installing
things into the /code
directory:
ARG APP_HOME=/code
...
COPY --from=client-builder --chown=${USERNAME}:${USERNAME} \
${APP_HOME} ${APP_HOME}
But in your docker-compose.yaml
, you're masking the /code
directory by mounting your local directory on top of it:
web:
...
volumes:
- .:/code
That means anything placed there during the build process will be hidden.
One solution is to mount your local directory somewhere other than
/code
(and then update your code/config/whatever to be aware of the
new mountpoint).