Search code examples
djangodockernginxamazon-ecs

Django app deployment through ECS with uWSGI and nginx can't find some files


I'm currently deploying a containerized Django application on Amazon ECS using uWSGI and nginx, but I'm having some issues with my proxy finding some of the static content. When I test a local proxy deployment using docker-compose it works fine, but not when it's deployed through ECS. Here's my settings.py:

# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/static/'
MEDIA_URL = '/static/media/'

STATIC_ROOT = '/vol/web/static'
MEDIA_ROOT = '/vol/web/media'

STATICFILES_DIRS = [
    # '/var/www/static/',
    os.path.join(BASE_DIR, 'core/static'),
]

Here's my proxy config:

server {
    listen ${LISTEN_PORT};

    location /static {
        alias /vol/static;
    }

    location / {
        uwsgi_pass              ${APP_HOST}:${APP_PORT};
        include                 /etc/nginx/uwsgi_params;
        client_max_body_size    10M;
    }
}

Container definition for ECS:

[
    {
        "name": "app",
        "image": "${app_image}",
        "essential": true,
        "memoryReservation": 256,
        "environment": [
            {"name": "DJANGO_SECRET_KEY", "value": "${django_secret_key}"},
            {"name": "DB_HOST", "value": "${db_host}"},
            {"name": "DB_NAME", "value": "${db_name}"},
            {"name": "DB_USER", "value": "${db_user}"},
            {"name": "DB_PASS", "value": "${db_pass}"},
            {"name": "ALLOWED_HOSTS", "value": "${allowed_hosts}"}
        ],
        "logConfiguration": {
            "logDriver": "awslogs",
            "options": {
                "awslogs-group": "${log_group_name}",
                "awslogs-region": "${log_group_region}",
                "awslogs-stream-prefix": "app"
            }
        },
        "portMappings": [
            {
                "containerPort": 9000,
                "hostPort": 9000
            }
        ],
        "mountPoints": [
            {
                "readOnly": false,
                "containerPath": "/vol/web",
                "sourceVolume": "static"
            }
        ]
    },
    {
        "name": "proxy",
        "image": "${proxy_image}",
        "essential": true,
        "portMappings": [
            {
                "containerPort": 8000,
                "hostPort": 8000
            }
        ],
        "memoryReservation": 256,
        "environment": [
            {"name": "APP_HOST", "value": "127.0.0.1"},
            {"name": "APP_PORT", "value": "9000"},
            {"name": "LISTEN_PORT", "value": "8000"}
        ],
        "logConfiguration": {
            "logDriver": "awslogs",
            "options": {
                "awslogs-group": "${log_group_name}",
                "awslogs-region": "${log_group_region}",
                "awslogs-stream-prefix": "proxy"
            }
        },
        "mountPoints": [
            {
                "readOnly": true,
                "containerPath": "/vol/static",
                "sourceVolume": "static"
            }
        ]
    }
]

Some sample logs when deployed locally:

proxy_1  | 172.18.0.1 - - [24/Nov/2020:15:58:01 +0000] "POST /reader/<removed name>-readings/S87ktUMTff8/import HTTP/1.1" 302 0 "http://127.0.0.1:8000/reader/<removed name>-readings/S87ktUMTff8" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"
app_1    | [pid: 14|app: 0|req: 2/10] 172.18.0.1 () {60 vars in 1830 bytes} [Tue Nov 24 15:58:01 2020] POST /reader/<removed name>-readings/S87ktUMTff8/import => generated 0 bytes in 492 msecs (HTTP/1.1 302) 7 headers in 231 bytes (1 switches on core 0)
app_1    | [pid: 13|app: 0|req: 7/11] 172.18.0.1 () {54 vars in 1591 bytes} [Tue Nov 24 15:58:01 2020] GET /reader/<removed name>-readings/S87ktUMTff8 => generated 16879 bytes in 54 msecs (HTTP/1.1 200) 7 headers in 350 bytes (1 switches on core 0)
proxy_1  | 172.18.0.1 - - [24/Nov/2020:15:58:01 +0000] "GET /reader/<removed name>-readings/S87ktUMTff8 HTTP/1.1" 200 16879 "http://127.0.0.1:8000/reader/<removed name>-readings/S87ktUMTff8" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"
proxy_1  | 172.18.0.1 - - [24/Nov/2020:15:58:01 +0000] "GET /static/static/core/css/core.css HTTP/1.1" 304 0 "http://127.0.0.1:8000/reader/<removed name>-readings/S87ktUMTff8" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"
proxy_1  | 172.18.0.1 - - [24/Nov/2020:15:58:02 +0000] "GET /static/static/assets/css/bootstrap.min.css HTTP/1.1" 304 0 "http://127.0.0.1:8000/reader/<removed name>-readings/S87ktUMTff8" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"

Sample logs from CloudWatch:

2020-11-23T14:45:41.920-05:00

2020/11/23 19:45:41 [error] 10#10: *224 open() "/vol/static/static/core/images/homepageLogo.png" failed (2: No such file or directory), client: <removed IP>, server: , request: "GET /static/static/core/images/homepageLogo.png HTTP/1.1", host: "<removed IP>:8000", referrer: "http://<removed IP>:8000/"
2020/11/23 19:45:41 [error] 10#10: *224 open() "/vol/static/static/core/images/homepageLogo.png" failed (2: No such file or directory), client: <removed IP>, server: , request: "GET /static/static/core/images/homepageLogo.png HTTP/1.1", host: "<removed IP>:8000", referrer: "http://<removed IP>:8000/"

2020-11-23T14:45:41.920-05:00

<removed IP> - - [23/Nov/2020:19:45:41 +0000] "GET /static/static/core/images/homepageLogo.png HTTP/1.1" 404 555 "http://<removed IP>:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"
<removed IP> - - [23/Nov/2020:19:45:41 +0000] "GET /static/static/core/images/homepageLogo.png HTTP/1.1" 404 555 "http://<removed IP>:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"

2020-11-23T14:45:41.970-05:00

2020/11/23 19:45:41 [error] 10#10: *224 open() "/vol/static/static/core/css/homepage.css" failed (2: No such file or directory), client: <removed IP>, server: , request: "GET /static/static/core/css/homepage.css HTTP/1.1", host: "<removed IP>:8000", referrer: "http://<removed IP>:8000/"
2020/11/23 19:45:41 [error] 10#10: *224 open() "/vol/static/static/core/css/homepage.css" failed (2: No such file or directory), client: <removed IP>, server: , request: "GET /static/static/core/css/homepage.css HTTP/1.1", host: "<removed IP>:8000", referrer: "http://<removed IP>:8000/"

2020-11-23T14:45:41.970-05:00

<removed IP> - - [23/Nov/2020:19:45:41 +0000] "GET /static/static/core/css/homepage.css HTTP/1.1" 404 555 "http://<removed IP>:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"
<removed IP> - - [23/Nov/2020:19:45:41 +0000] "GET /static/static/core/css/homepage.css HTTP/1.1" 404 555 "http://<removed IP>:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36" "-"

Let me know if there is any additional information that I could provide. Any help would be greatly appreciated! Thanks in advance :)


Solution

  • so I finally figured out what was wrong. For anyone experiencing something similar it was because I hadn't set my ALLOWED_HOSTS on Django to allow the local IP address of the running task and hence it kept rejecting the load balancers health check request.

    I added this to my settings.py:

    from socket import gethostname, gethostbyname
    
    if os.environ.get('AWS_EXECUTION_ENV'):
        ALLOWED_HOSTS.append(gethostbyname(gethostname()))