1
votes

I'm deploying my Django/Nginx/Gunicorn webapp to EC2 instance using docker-compose. EC2 instance has static IP where mywebapp.com / www.mywebapp.com points to, and I've completed the certbot verification (site works on port 80 over HTTP) but now trying to get working over SSL.

Right now, HTTP (including loading static files) is working for me, and HTTPS dynamic content (from Django) is working, but static files are not. I think my nginx configuration is wonky.

I tried copying the location /static/ block to the SSL server context in the nginx conf file, but that caused SSL to stop working altogether, not just static files over SSL.

Here's the final docker-compose.yml:

services:
  certbot:
    entrypoint: /bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h &
      wait $${!}; done;'
    image: certbot/certbot
    volumes:
      - /home/ec2-user/certbot/conf:/etc/letsencrypt:rw
      - /home/ec2-user/certbot/www:/var/www/certbot:rw
  nginx:
    command: /bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done
      & nginx -g "daemon off;"'
    depends_on:
      - web
    image: xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/xxxxxxxx:latest
    ports:
      - 80:80/tcp
      - 443:443/tcp
    volumes:
      - /home/ec2-user/certbot/conf:/etc/letsencrypt:rw
      - static_volume:/usr/src/app/public:rw
      - /home/ec2-user/certbot/www:/var/www/certbot:rw
  web:
    entrypoint: gunicorn mywebapp.wsgi:application --bind 0.0.0.0:7000"
    image: xxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/xxxxxxxx:latest
    volumes:
      - static_volume:/usr/src/app/public:rw
version: '3.0'
volumes:
  static_volume: {}

nginx.prod.conf:

upstream mywebapp {
    # web is the name of the service in the docker-compose.yml
    # 7000 is the port that gunicorn listens on
    server web:7000;
}

server {
    listen 80;
    server_name mywebapp;
    location / {
        proxy_pass       http://mywebapp;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header Host               $host;
        proxy_redirect   off;
    }
    location /static/ {
        alias /usr/src/app/public/;
    }
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    # https://github.com/wmnnd/nginx-certbot/blob/master/data/nginx/app.conf
    listen 443    ssl;
    server_name   mywebapp;
    server_tokens off;

    location / {
        proxy_pass          http://mywebapp;
        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    }

    # generated with help of certbot
    ssl_certificate     /etc/letsencrypt/live/mywebapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mywebapp.com/privkey.pem;
    include             /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam         /etc/letsencrypt/ssl-dhparams.pem;
}

and finally the nginx service Dockerfile:

FROM nginx:1.15.12-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx.prod.conf /etc/nginx/conf.d

I simply build, push to ECR on local machine then docker-compose pull and run with docker-compose up -d on the EC2 instance.

The error I see in docker-compose logs is:

nginx_1    | 2019/05/09 02:30:34 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xx, server: mywebapp, request: "GET / HTTP/1.1", upstream: "http://192.168.111.3:7000/", host: "ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com"

And I'm not sure what's going wrong. I'm trying to get both dynamic content (gunicorn) and static content (from: /usr/src/app/public) served correctly under HTTPS using the certs I've generated and verified.

Anyone know what I might be doing wrong?

1
So move this location /static/ to 443 conf part.Ivan Starostin
Error message is saying that nginx cannot connect to your app. And this is not related to other location definitions.Ivan Starostin
what does that mean?lollercoaster

1 Answers

1
votes

Check your configuration file with nginx -T - are you seeing the correct configuration? Is your build process pulling in the correct conf?

It's helpful to just debug this on the remote machine - docker-compose exec nginx sh to get inside and tweak the conf from there and nginx -s reload. This will speed up your iteration cycles debugging an SSL issue.