I’m making a Django app and I’m using Docker por production deployment, the application almost runs fine on the VPS(Ubuntu 20.04) except that when I try to run collectstatic with this command:
sudo docker-compose -f docker-compose.prod.yml exec web python manage.py collectstatic --no-input
Always throws this error:
PermissionError: [Errno 13] Permission denied: '/home/app/web/staticfiles/img/app_logo.png'
This is my docker-compose:
version: '3'
services:
db:
restart: unless-stopped
image: "postgres:13.2-alpine"
container_name: db
ports:
- "5432:5432" # HOST:CONTAINER
env_file:
- ./.env.prod
volumes:
- ./pgdata:/var/lib/postgresql/data
web:
container_name: web
restart: unless-stopped
build:
context: .
dockerfile: ./docker/production/Dockerfile
environment:
DJANGO_SETTINGS_MODULE: MyApp.app_settings.production
command: gunicorn MyApp.wsgi:application --bind 0.0.0.0:8000
expose:
- "8000"
env_file:
- ./.env.prod
volumes:
- .:/app # Enable code reload
- ./run/static:/home/app/web/staticfiles
- ./run/media:/home/app/web/mediafiles
depends_on:
- db
nginx:
container_name: nginx
restart: unless-stopped
build: docker/production/nginx
volumes:
- ./run/static:/home/app/web/staticfiles
- ./run/media:/home/app/web/mediafiles
ports:
- "80:80"
- "443:443"
depends_on:
- web
and this is my Dockerfile:
# pull official base image
FROM python:3.8
# create directory for the app user
RUN mkdir -p /home/app
# create the app user
#RUN addgroup -S app && adduser -S app -G app
RUN adduser --system --group app
# create the appropriate directories
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/staticfiles
RUN mkdir $APP_HOME/mediafiles
WORKDIR $APP_HOME
# Own home directory
RUN chown -R app:app $HOME
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
#RUN apk update && apk add libpq
#COPY --from=builder /usr/src/app/wheels /wheels
#COPY --from=builder /usr/src/app/requirements.txt .
#RUN pip install --no-cache /wheels/*
COPY ./requirements.txt $APP_HOME
RUN pip install --no-cache-dir -r requirements.txt
RUN apt-get clean
RUN apt-get update
# Install netcat
RUN apt install -y netcat
# Install wkhtml2pdf
RUN wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb
RUN DEBIAN_FRONTEND=noninteractive apt install -y -q ./wkhtmltox_0.12.6-1.buster_amd64.deb
# copy entrypoint-prod.sh
COPY ./docker/prod/ep.prod.sh $APP_HOME
# execution permissions
RUN ["chmod", "+x", "/home/app/web/ep.prod.sh"]
# copy project
#COPY . $APP_HOME
COPY --chown=app:app . $APP_HOME
# chown all the files to the app user
#RUN chown -R app:app $APP_HOME
# change to the app user
USER app
# run entrypoint.prod.sh
ENTRYPOINT ["/home/app/web/ep.prod.sh"]
I believe that my Dockerfile should have something wrong, but I don’t know exactly what. Anyone can help me?
Edit:
With the answer below, they suggest to run it this way and works fine:
docker exec -it -u 0 [CONTAINER_NAME] python manage.py collectstatic --no-input
Also I found this solution, but I believe that this is not safe, any other suggestion?
chmod a+rwx -R run/
I followed this tutorial: https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
3
Answers
You must add
-u 0
to your command for run as root user:I have been stuck for a few hours on this issue. After making sure all the static directory and Django config are in place and proper privileges via shell onto the container. I was with no success.
After searching for a few hours, came to this document
which says you need to manually
collect static
after demonizing the container.Commands:
The answer may long be solved but reference to future users, who would be in the same issue.
Had the same issue. To avoid docker-compose exec, you can collect the static files while you’re the root user in the DOCKERFILE. The DOCKERFILE should look like :