Ruddra.com

Serve Static Files by Nginx from Django using Docker

Serve Static Files by Nginx from Django using Docker

This is more of a follow up post of my previous article.

Before I start, I am assuming you have successfully deployed django using docker and nginx, but having some problems serving static files.

Steps

No worries, it is easy. Just follow these steps:

1. In your django settings.py file, add static file directory i.e. STATIC_ROOT=/static. So what it will do is, when you run collectstatic command(python manage.py collectstatic), it will store the static files in your /static directory of OS.

2. Now in docker-compose.yml folder, lets add a configuration like this:

version: "2"
services:
  nginx:
    image: nginx:latest
    container_name: NGINXDOCKERNAME
    ports:
      - "8000:8000"
    volumes:
      - ./src:/src
      - ./config/nginx:/etc/nginx/conf.d
      - /static:/static  <--- HERE
    depends_on:
      - web
  web:
    build: .
    container_name: DJANGOXDOCKERNAME
    command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn mydjango.wsgi -b 0.0.0.0:8000"
    depends_on:
      - db
    volumes:
      - ./src:/src
      - /static:/static    <---- HERE
    expose:
      - "8000"

  db:
    image: postgres:latest
    container_name: PSQLDOCKERNAME

FYI the command argument of the docker compose is same as CMD of Dockerfile. So we can move this inside Dockerfile if we want to(i.e.: CMD python manage.py makemigrations;python manage.py migrate;gunicorn mydjango.wsgi -b 0.0.0.0:8000).

What it will do is that, two containers web and nginx will share a directory named /static.

3. Now lets add few lines in nginx’s config file, i.e mydjango.conf:

upstream web {
  ip_hash;
  server web:8000;
}

server {

    location /static/ {
        autoindex on;
        alias /static/;
    }

    location / {
        proxy_pass http://web/;
    }
    listen 8000;
    server_name localhost;
}

So what it will do is, any request to url like yourhost:yourport/static/* this comes to nginx, it will serve data from /static directory.

4. Now lets run the following command:

docker exec DOCKERNAME /bin/sh -c "python manage.py collectstatic --noinput"

Or update the command key’s value in compose to:

command: bash -c "python manage.py collectstatic --no-input && python manage.py makemigrations && python manage.py migrate && gunicorn mydjango.wsgi -b 0.0.0.0:8000"

It will put static files in /static directory and thats should do the trick. Whenever you hit url with /static will serve static files from that folder. Similarly you can serve media files too. Codes have been updated here at: https://github.com/ruddra/docker-django Cheers!!


Update

If you are interested to run distributed tasks using celery in Docker with Django, then please read this post.

Last updated: Apr 05, 2024


← Previous
Deploy Django, Gunicorn, NGINX, Postgresql using Docker

How easily you can deploy Django with NGINX, Postgresql, Gunicorn in Docker

Next →
Docker: Use Celery in Django(Redis as Broker)

In previous two posts, we have deployed Django with Postgres, Nginx, now its time to do some async …

Share Your Thoughts
M↓ Markdown