# Serving django static files in nginx docker

**URL:** <https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969>\
**Category:** Deployment\
**Created:** [August 18, 2024, 5:02pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969 "2024-08-18T17:02:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 18, 2024, 5:02pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/1 "2024-08-18T17:02:49Z")

</div>

Hey all, I am at a loss – I’ve gone through all the posts related to my problem, but I still cannot get my static css and js files to format my content in my Django site when running via docker and nginx.

Here are some relevant configurations from my `settings.py` file:

```auto
DEBUG = True
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'web.apps.WebConfig',
    'django_recaptcha'
]
WSGI_APPLICATION = 'portfolio.wsgi.application'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

```

Here is my `Dockerfile`:

```auto
FROM python:3.11-slim

WORKDIR opt/django/
COPY pyproject.toml .
RUN python -m pip install . -I --no-cache-dir

COPY ./portfolio/ ./portfolio/

WORKDIR portfolio/

RUN python manage.py collectstatic --noinput
RUN python manage.py makemigrations
RUN python manage.py migrate

EXPOSE 8000

CMD ["gunicorn", "portfolio.wsgi:application", "--bind", "0.0.0.0:8000"]

```

Here is my `docker-compose.yml`:

```auto
#version: '3.8'

services:
  web:
    build:
      context: .
      dockerfile: ./docker/Dockerfile_django
    container_name: webserver
    volumes:
      - static_data:/opt/django/portfolio/static
    expose:
      - "8000"
    ports:
      - "8000:8000"
    depends_on:
      - db

  db:
    image: postgres:15
    container_name: db_postgres
    expose:
      - "5432"
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - static_data:/opt/django/portfolio/static
    depends_on:
      - web

volumes:
  postgres_data:
  static_data:

```

And finally, here is my `nginx.conf`:

```events

http {
    server {
        listen 80;
        server_name localhost;

        location /static {
            alias /opt/django/portfolio/static;
            autoindex on;
            access_log /var/log/nginx/static_access.log;
            error_log /var/log/nginx/static_error.log debug;
        }

        # skip favicon.ico
        location /favicon.ico {
            access_log off;
            return 204;
        }

        location / {
            proxy_pass http://web:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        error_log /var/log/nginx/error.log debug;

    }
}

```

I see no errors in my logs, and nginx is reporting 200’s when I make a GET to a url in the project. When I visit `http://127.0.0.1/static/website/style.css` I can see the css. I’ve cleared my cache. When I go to `/opt/django/portfolio/collectstatic` in my web and nginx containers, I can see the static files. I have also tried updating permissions on the static files by running: `chmod -R 755 /opt/django/portfolio/static/website/style.css` in both the nginx and web containers.

My project is structured like this:

```auto
 - portfolio/
   - nginx/
     - nginx.conf
   - portfolio/
     - portfolio/
       - settings.py
       - ...
     - web/
       - js/
         - somejs.js
         - someotherjs.js
       - website/
         - style.css
       - admin.py
       - apps.py
       - forms.py
       - models.py
       - tests.py
       - ...

```

What am I missing? Below is a snippet of the logs from my nginx container. Is the timeout indicative of anything?

```auto
nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:51:06 +0000] "GET / HTTP/1.1" 200 2458 "http://0.0.0.0/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:51:08 +0000] "GET /about HTTP/1.1" 200 2304 "http://0.0.0.0/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:51:39 +0000] "GET /about HTTP/1.1" 200 2304 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:52:04 +0000] "GET /tictactoe/ HTTP/1.1" 200 5181 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:52:05 +0000] "GET /tictactoe/?difficulty=All HTTP/1.1" 200 155 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 2024/08/18 16:52:06 [info] 29#29: *1 client timed out (110: Connection timed out) while waiting for request, client: 192.xxx.xx.x, server: 0.0.0.0:80
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:52:39 +0000] "GET /about HTTP/1.1" 200 2304 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:52:55 +0000] "GET /about HTTP/1.1" 200 2304 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.xxx.xx.x - - [18/Aug/2024:16:53:05 +0000] "GET / HTTP/1.1" 200 2458 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 18, 2024, 5:11pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/2 "2024-08-18T17:11:50Z")

</div>

Welcome @fredonia88 !

This:

> [@fredonia88](#):
>
> `RUN python manage.py makemigrations`

Should be run before you ever get to this point. You don’t want to be creating migrations arbitrarily when the container is being built. This is something that should be done in development and checked in to your repository.

These commands:

> [@fredonia88](#):
>
> ```auto
> RUN python manage.py collectstatic --noinput
> RUN python manage.py migrate
> 
> ```

need to run at run time, not docker build time. These commands should be in the script that runs when the container is executed.

One way of doing this is to replace this:

> [@fredonia88](#):
>
> `CMD ["gunicorn", "portfolio.wsgi:application", "--bind", "0.0.0.0:8000"]`

With a CMD directive to run a script containing all three commands. (The collectstatic, migrate and gunicorn commands.)

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 18, 2024, 6:26pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/3 "2024-08-18T18:26:38Z")

</div>

> [@fredonia88](#):
>
> RUN python manage.py makemigrations

Thanks for the speedy reply @KenWhitesell !

I made the suggested changes, but am still not seeing any formatting.

Here is my new `Dockerfile`:

```auto
FROM python:3.11-slim

WORKDIR opt/django/
COPY pyproject.toml .
RUN python -m pip install . -I --no-cache-dir

COPY ./portfolio/ ./portfolio/

WORKDIR portfolio/

COPY start.sh /start.sh

RUN chmod +x /start.sh

EXPOSE 8000

CMD ["/start.sh"]

```

Here’s the new script to run the commands:

```auto
#!/bin/bash

# collect static files and migrate
python manage.py collectstatic --noinput
python manage.py migrate

# start gunicorn server
gunicorn portfolio.wsgi:application --bind 0.0.0.0:8000

```

No changes made to `nginx.conf` or `docker-compose.yml`. Any other ideas? I don’t see anything in the logs:

```auto
nginx | 192.xxx.xx.x - - [18/Aug/2024:18:24:51 +0000] "GET /about HTTP/1.1" 200 2304 "http://127.0.0.1/contact" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
nginx | 192.1xxx.xx.x - - [18/Aug/2024:18:24:52 +0000] "GET / HTTP/1.1" 200 2458 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 18, 2024, 6:31pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/4 "2024-08-18T18:31:39Z")

</div>

What I’m not seeing are any requests for those css files.

Please show the view for any one view that is supposed to be referencing a css file, along with the template being rendered.

Also look at the error log, along with checking the docker logs for those containers.

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 18, 2024, 7:09pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/5 "2024-08-18T19:09:26Z")

</div>

Here is the home view:

```auto
class HomeView(View):
    template_name = 'home.html'

    def get(self, request):

        return render(request, self.template_name)

```

Here is the url pattern:

```auto
urlpatterns = [
    path('', HomeView.as_view(), name="home")
    ...

```

Finally, here is `home.html`:

```auto
{% extends 'base.html' %}

{% load static %}
<head>
  <link rel="stylesheet", type="text/css", href="{% static 'website/style.css' %}">
</head>

{% block content %}

<p style="margin-left: 40px; text-align: left;">
<br>
Here is some content!
</p>

{% endblock %}

```

In the nginx docker logs, I do see these:

```auto
2024-08-18 13:21:50 2024/08/18 18:21:50 [info] 29#29: *1 client 192.xxx.xx.x closed keepalive connection
2024-08-18 13:22:07 2024/08/18 18:22:07 [info] 29#29: *4 client timed out (110: Connection timed out) while waiting for request, client: 192.xxx.xx.x, server: 0.0.0.0:80

```

My `static_error.log` in `/var/log/nginx/` is empty, but the `static_access.log` shows entries. Here are two:

```auto
192.xxx.xx.x - - [18/Aug/2024:18:27:59 +0000] "GET /static/website/style.css HTTP/1.1" 304 0 "http://127.0.0.1/contact" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [18/Aug/2024:18:27:59 +0000] "GET /static/js/contact.js HTTP/1.1" 304 0 "http://127.0.0.1/contact" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 18, 2024, 7:17pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/6 "2024-08-18T19:17:12Z")

</div>

> [@fredonia88](#):
>
> ```auto
> 192.xxx.xx.x - - [18/Aug/2024:18:27:59 +0000] "GET /static/website/style.css HTTP/1.1" 304 0 "http://127.0.0.1/contact" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
> 192.xxx.xx.x - - [18/Aug/2024:18:27:59 +0000] "GET /static/js/contact.js HTTP/1.1" 304 0 "http://127.0.0.1/contact" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
> 
> ```

A `304` is a file not-modified condition, which means it’s already cached in your browser and the browser isn’t retrieving it.

Try accessing your page using your browser in “incognito” or “private” mode. You can also try doing a force reload (shift-f5). You can also try clearing your browser cache for your site.

Side note: Please confirm that you are stopping and rebuilding your containers after every change.

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 18, 2024, 9:23pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/7 "2024-08-18T21:23:50Z")

</div>

Sadly, I still don’t see any formatting. I’ve opened a new incognito tab and have been forcing the browser to retrieve the html with command + shift + R (mac). Still no luck. I’ve also tried this in Safari (I’ve been using chrome).

I can confirm I am stopping and rebuilding all containers. In fact, this last go, I deleted everything – dangling images, volumes and builds and rebuilt the image using no cached files.

Here’re more nginx logs:

```auto
2024-08-18 16:15:33 192.xxx.xx.x - - [18/Aug/2024:21:15:33 +0000] "GET /about HTTP/1.1" 200 2304 "http://127.0.0.1/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:15:54 192.xxx.xx.x - - [18/Aug/2024:21:15:54 +0000] "GET /tictactoe/ HTTP/1.1" 200 5181 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:15:54 192.xxx.xx.x - - [18/Aug/2024:21:15:54 +0000] "GET /tictactoe/?difficulty=All HTTP/1.1" 200 155 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:17:10 192.xxx.xx.x - - [18/Aug/2024:21:17:10 +0000] "GET /tictactoe/ HTTP/1.1" 200 5181 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:17:10 192.xxx.xx.x - - [18/Aug/2024:21:17:10 +0000] "GET /tictactoe/?difficulty=All HTTP/1.1" 200 155 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:17:11 192.xxx.xx.x - - [18/Aug/2024:21:17:11 +0000] "GET / HTTP/1.1" 200 2458 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:17:34 192.xxx.xx.x - - [18/Aug/2024:21:17:34 +0000] "GET / HTTP/1.1" 200 2458 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
2024-08-18 16:17:15 2024/08/18 21:17:15 [info] 29#29: *13 client 192.xxx.xx.x closed keepalive connection
2024-08-18 16:17:15 2024/08/18 21:17:15 [info] 29#29: *15 client 192.xxx.xx.x closed keepalive connection

```

Screenshot of the unformatted site:

 ![Screenshot 2024-08-18 at 4.16.22 PM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/f/f/ffd41a41c5796fa39872f45d0ce42e84af845ed5.png)

FWIW: I am using python 3.11 and below are the python package versions I’m using:

```auto
    "asgiref==3.8.1",
    "certifi==2024.7.4",
    "Django==5.0.7",
    "django-recaptcha==4.0.0",
    "gunicorn==22.0.0",
    "packaging==24.1",
    "sqlparse==0.5.1"

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 18, 2024, 9:41pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/8 "2024-08-18T21:41:14Z")

</div>

It’s the static logs that we need to see. We need to verify that nginx is getting requests for those css files and serving them.

In addition to checking the logs, you’ll want to check the data volume to verify that the current css files are in it.

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 12:17am UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/9 "2024-08-19T00:17:05Z")

</div>

> [@KenWhitesell](#):
>
> tatic logs that we need to see. We ne

I checked the volume and all the static files are there:

 ![Screenshot 2024-08-18 at 7.07.17 PM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/7/6/76672a5a07ac49edb9432c76ab1901d4d6d389d7.png)

The `static_error.log` in nginx container is empty, but the `static_access.log` has entries. Looks to be retrieving the static files ok (mix of 200 and 304):

```auto
# cat static_access.log
192.xxx.xx.x - - [18/Aug/2024:21:15:27 +0000] "GET /static/js/tictactoe.js HTTP/1.1" 200 7267 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [18/Aug/2024:21:15:30 +0000] "GET /static/js/contact.js HTTP/1.1" 200 471 "http://127.0.0.1/contact" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [18/Aug/2024:21:17:10 +0000] "GET /static/website/style.css HTTP/1.1" 200 2511 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [18/Aug/2024:21:17:10 +0000] "GET /static/js/tictactoe.js HTTP/1.1" 200 7267 "http://127.0.0.1/tictactoe/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [18/Aug/2024:21:17:34 +0000] "GET /static/website/style.css HTTP/1.1" 200 2511 "http://127.0.0.1/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [18/Aug/2024:21:26:39 +0000] "GET /static/website/style.css HTTP/1.1" 304 0 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [19/Aug/2024:00:10:10 +0000] "GET /static/website/style.css HTTP/1.1" 304 0 "http://127.0.0.1/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [19/Aug/2024:00:11:56 +0000] "GET /static/website/style.css HTTP/1.1" 200 2511 "http://127.0.0.1/about" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
192.xxx.xx.x - - [19/Aug/2024:00:12:44 +0000] "GET /static/website/style.css HTTP/1.1" 200 2511 "http://127.0.0.1/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 19, 2024, 12:46am UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/10 "2024-08-19T00:46:48Z")

</div>

Are the contents correct in those static files?

Also, I’m not familiar with the tool you’re using.

Your docker compose file shows that the volume name is `static_data`, but that tool is showing a volume named `portfolio_static_data`?

If you look at the css file in the browser, are you seeing the current contents?

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 1:20am UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/11 "2024-08-19T01:20:44Z")

</div>

Yes, the content in the volume files matches what I have in the repo. The tool I am using is Docker Desktop, running locally on my mac.

I believe it is normal for Docker to prefix volume names with the project name to avoid collisions. To be sure, I added `portfolio_` to the volume names in docker-compose, rebuilt the image and redeployed, but now `portfolio_portfolio_` is appended to the volume name in Docker Desktop.

When I look at the css in the browser, (i.e. I ping `http://127.0.0.1/static/website/style.css` or `http://127.0.0.1/static/js/contact.js`) I can see the plain css or javascript in the browser. It matches what is in my repo.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 19, 2024, 1:46am UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/12 "2024-08-19T01:46:23Z")

</div>

Ok, I’m talking about the css that was loaded by the page when you examine the page using the browser’s developer tools.

If you examine the page, there’s a tab “sources”. If you look at your style.css file in the sources, what do you see?

If you click on an element in the “Elements” tab that should be styled by your “style.css” file, does it show up as being styled by that element?

Also, I just noticed that your link to the stylesheet is not in a block - is it even being rendered in the page? You’ve also got it in a `<head>` element. Is it functional if you have two separate `<head>` elements in the page?  
What does your `base.html` look like?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [August 19, 2024, 1:47am UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/13 "2024-08-19T01:47:31Z")

</div>

Ok, I’m talking about the css that was loaded by the page when you examine the page using the browser’s developer tools.

If you examine the page, there’s a tab “sources”. If you look at your style.css file in the sources, what do you see?

If you click on an element that should be styled in the “Elements” tab, do you see it being styled by your css file?

Also, I just noticed that your link to the stylesheet is not in a block - is it even being rendered in the page? You’ve also got it in a `<head>` element. Is it functional if you have two separate `<head> elements in the page? What does your `base.html` look like?

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 1:48pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/14 "2024-08-19T13:48:05Z")

</div>

OK, your last comment is heading in the right direction.

When I click on sources, I can see the static files:

 ![Screenshot 2024-08-19 at 8.49.50 AM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/0/7/0701768131d0cfa9eb1db841bcab332a331fa547.png)

If I click on an element, all of the generated html looks correct to me despite no css being rendered. For example, my css style sheet contains:

```auto
.bg {
    background-color: black;
}

```

And I can see that element in the html, but it is not being styled (i.e. the background is not black):

 ![Screenshot 2024-08-19 at 8.27.37 AM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/9/3/937e533e6114c42de2e883a9efcd01d7cc65d4eb.jpeg)

However, if I make an entry in the `body` element with `--bs-body-color: black` the background successfully changes to black!

 ![Screenshot 2024-08-19 at 8.40.44 AM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/a/7/a751df24c2ac62ebe2c9700864892dcf1e6bf0b1.jpeg)

In terms of being functional, all of this works locally when I’m running with `DEBUG=True` via `runserver`. Here is the `base.html` file:

 ![Screenshot 2024-08-19 at 8.43.03 AM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/9/1/917401853558299d43866abcf5b358956041183d.png)

And here is the `home.html` page (this is the html being loaded in the first two screenshots):

 ![Screenshot 2024-08-19 at 8.43.11 AM](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/5/e/5ed2aa629d4f847a2f3355217cfbe6f839a7ba20.png)

---

<div class="post-metadata">

**Author:** ![philgyford](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/philgyford/32/14295_2.png) [@philgyford](https://forum.djangoproject.com/u/philgyford)\
**Post date:** [August 19, 2024, 3:21pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/15 "2024-08-19T15:21:49Z")

</div>

Note that you have two commas in this `<link`\>` tag, but they shouldn’t be there. HTML tags don’t have commas in them (unless they’re in quoted attribute values). That might be causing the problem:

> [@fredonia88](#):
>
> ```auto
> <link rel="stylesheet", type="text/css", href="{% static 'website/style.css' %}">
> 
> ```

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 3:50pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/16 "2024-08-19T15:50:05Z")

</div>

Thank you for catching that. I made the update to all html files, but still do not have any formatting (rebuilt image and containers from scratch, and visited site in incognito window).

---

<div class="post-metadata">

**Author:** ![philgyford](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/philgyford/32/14295_2.png) [@philgyford](https://forum.djangoproject.com/u/philgyford)\
**Post date:** [August 19, 2024, 4:09pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/17 "2024-08-19T16:09:01Z")

</div>

An HTML page should only have one `<head>` element. Your `base.html` has two and then you’re trying to add another in your `home.html`.

You should only have one in your `base.html` and then use a block within that which child templates can use to insert extra `<link>` tags etc. Here’s a very basic example:

`base.html`:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  {% load static %}
  <link rel="stylesheet" type="text/css" href="{% static 'bootstrap.css' %}">
  {% block extra_css }
  {% endblock %}
</head>
<body>
  
</body>
</html>

```

`home.html`:

```html
{% extends "base.html" %}
{% load static %}

{% block extra_css %}
  <link rel="stylesheet" type="text/css" href="{% static 'website/style.css' %}">
{% endblock %}

```

NOTE: This isn’t exactly what yours should look like but because you posted images instead of actual code, I can’t copy and paste from your HTML.

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 7:56pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/18 "2024-08-19T19:56:35Z")

</div>

I made those updates. Still no formatting running through nginx!

Here is `base.html`:

```auto
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{% block title %}Portfolio{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="some-sha-key" crossorigin="anonymous">
    <link href="https://fonts.googleapis.com/css?family=Fira Code" rel="stylesheet">
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'website/style.css' %}">
  </head>
  <body class="bg">
    {% include 'navbar.html' %}
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="some-sha-key="anonymous"></script>
  </body>
  </br>
  <div class="container-fluid">
    {% block content %}

    {% endblock %}
  </div>
</html>

```

And here is `home.html`:

```auto
{% extends 'base.html' %}
{% load static %}

{% block content %}
<p style="margin-left: 40px; text-align: left;">
<br>
Hey, I'm so-and-so, Senior Data Engineer based out of some place. Check out my portfolio, and feel free to get in touch.
</p>

{% endblock %}

```

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 8:18pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/19 "2024-08-19T20:18:36Z")

</div>

And here is `navbar.html` if it helps:

```auto
<nav class="navbar navbar-expand-lg">
  <div class="container-fluid">
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
              <li class="nav-item">
                <a class="nav-link nav-custom" aria-current="page" href="{% url 'home' %}">Home</a>
              </li>
          </ul>
          <ul class="navbar-nav ms-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link nav-custom" aria-current="page" href="{% url 'about' %}">About</a>
            </li>
            <li class="nav-item dropdown">
                <a class="nav-link dropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                    Projects
                </a>
                <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown" style="padding: 0;">
                    <li><a class="dropdown-item" href="{% url 'tictactoe' %}">Tic Tac Toe</a></li>
                    <li><a class="dropdown-item" href="{% url 'ercot' %}">Ercot Renewable Energy Demand</a></li>
                    <li><a class="dropdown-item" href="{% url 'bls' %}">Bureau of Labor Statistics</a></li>
                </ul>
            </li>
            <li class="nav-item">
              <a class="nav-link nav-custom" aria-current="page" href="{% url 'contact' %}">Contact</a>
            </li>
          </ul>
      </div>
  </div>
</nav>

```

---

<div class="post-metadata">

**Author:** ![fredonia88](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/fredonia88/32/23299_2.png) [@fredonia88](https://forum.djangoproject.com/u/fredonia88)\
**Post date:** [August 19, 2024, 10:51pm UTC](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969/20 "2024-08-19T22:51:34Z")

</div>

I’m happy to report I solved the issue by adding `include mime.types;` under `location /static {` in my `nginx.conf` file.

Thank you both @KenWhitesell and @philgyford ! I’m not sure I’ll use nginx after this.

[Next page](https://forum.djangoproject.com/t/serving-django-static-files-in-nginx-docker/33969.md?page=2)
