Django application deployement with Docker
I am trying to deploy my django app with docker. But when it come to excute my script to be sure that the databse (postgres) is ready, I allways get this error : chmod: /app/scripts/wait-for-it.sh: Permission denied and then the container stop running.
This is my dockerfile :
# Stage 1: Base build stage
FROM python:3.13-slim AS builder
# Create the app directory
RUN mkdir /api
# Set the working directory
WORKDIR /api
# Set environment variables to optimize Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpcre3-dev \
libssl-dev \
python3-dev \
libpango1.0-dev \
libcairo2-dev \
libpq-dev \
bash \
fontconfig \
fonts-dejavu-core \
fonts-droid-fallback \
fonts-freefont-ttf \
fonts-liberation \
&& rm -rf /var/lib/apt/lists/*
# Install dependencies first for caching benefit
RUN pip install --upgrade pip
RUN mkdir /requirements
COPY ./requirements/. ./requirements/.
RUN set -e; \
pip3 install --upgrade pip && \
pip3 install uwsgi && \
pip3 install --default-timeout=100 --no-cache-dir -r ./requirements/stage.txt
# Stage 2: Production stage
FROM python:3.13-slim
RUN useradd -m -r -g www-data app_user && \
mkdir /api && \
chown -R app_user /api
# Copy the Python dependencies from the builder stage
COPY --from=builder /usr/local/lib/python3.13/site-packages/ /usr/local/lib/python3.13/site-packages/
COPY --from=builder /usr/local/bin/ /usr/local/bin/
# Set the working directory
WORKDIR /api
# Copy application code
COPY --chown=app_user:app_user . .
RUN chown -R app_user:www-data /api
# Set environment variables to optimize Python
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
RUN chown app_user:www-data ./config/uwsgi && \
mkdir -p /run/uwsgi && \
chown app_user:www-data /run/uwsgi
# Switch to non-root user
USER app_user
# Expose the application port
EXPOSE 8000
# Make entry file executable
RUN chmod +x /api/config/scripts/wait-for-it.sh
# Verify if postgress ready !
CMD ["/api/config/scripts/wait-for-it.sh"]
This is my api service in my yml file :
services:
api:
image: "${MY_API_IMAGE_FROM_ENV}"
restart: always
command: >
sh -c "/api/config/scripts/wait-for-it.sh db:5432
&& python /api/project/manage.py makemigrations
&& python /api/project/manage.py migrate
&& uwsgi --ini /api/config/uwsgi/uwsgi.stage.ini"
volumes:
- .:/api
- uwsgi_socket:/run/uwsgi
- /var/log/project:/api/logs
environment:
- DJANGO_SETTINGS_MODULE=project.settings.stage
- POSTGRES_USER=${BACKEND_USER_DB}
- POSTGRES_PASSWORD=${BACKEND_PASSWORD_DB}
- POSTGRES_DB=${BACKEND_DB_NAME}
- POSTGRES_PORT= ${BACKEND_PORT_DB}
env_file:
- .env
depends_on:
- db
networks:
- app_network
container_name: api
I thought the problem come from the user priveleges so I try to create a user and give it the permissions to execute the script. But till getting this error in the app container.
It sounds like your script /app/scripts/wait-for-it.sh has permissions set to only be executable by your user on your local machine (not Docker), and so when the docker user tries to run it, you get a permission denied
error. To test this theory, you can try the following from your local machine:
sudo chmod 777 /app/scripts/wait-for-it.sh
This will set the permissions for this script to be executable by all users. (Note, this is not ideal and shouldn't be left as a permanent setting, just as a test.) If you are still getting a permissions error, you can be a little more heavy-handed by setting allow-all permissions on the entire directory, and all files contained within:
sudo chmod -R 777 /app/
But this is REALLY open and rather insecure, so I'd be cautious using this, and be sure to set permissions back to least-access once you've got your docker container working.
It can be helpful to create a user inside the docker container and then you can edit the permissions of your folders/files to only allow that user to execute scripts from them, which is significantly more secure than leaving everything on full permissions for everyone. This page has some useful information on the chmod
command, how to read the notation for granting permission, and how you can grant certain permissions only to a specific user or group of users.