23
Production HTTPS Setup
Linden Crandall edited this page 2025-02-12 20:10:57 +00:00

Production HTTPS Setup How to Secure Your Applications with HTTPS Using Docker, NGINX, and Let's Encrypt

  • First cd to project where the repo is intialized cd /home/lasthour/repositories/automatisch
  • Create an env file, and add the env vars and save the file: sudo nano .env. Get name from Tony. Make sure to update the IPV6_SUBNET var to to a range that isn't already in use:

ex):

ENABLE_IPV6=true
MAIN_HTTP_PORT=7757
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443
HOST=automatisch.lasthourhosting.org
PROTOCOL=http
APP_ENV=production
REDIS_HOST=redis
POSTGRES_HOST=postgres
POSTGRES_DATABASE=automatisch
POSTGRES_USERNAME=automatisch_user
POSTGRES_PASSWORD=automatisch_password
ENCRYPTION_KEY=REDACTED
WEBHOOK_SECRET_KEY=REDACTED
APP_SECRET_KEY=REDACTED
SSL_CERT_EMAIL=support@shilohcode.com
SSL_SELF_SIGNED_CRT=shiloh_automatisch.local.crt
SSL_SELF_SIGNED_KEY=shiloh_automatisch.local.key
IPV6_SUBNET=2001:db8:2::/64
  • change .env file's owner and group to lasthour: sudo chown lasthour:lasthour .env
  • In docker-compose.yml, uncomment production nginx and certbot services:
  nginx:
    image: nginx:latest
    depends_on:
      - main      
    restart: unless-stopped
    volumes:
      - ./https/nginx/automatisch_letsencrypt_nginx.conf:/etc/nginx/conf.d/automatisch_letsencrypt_nginx.conf
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    ports:
      - ${NGINX_HTTP_PORT}:${NGINX_HTTP_PORT}
      - ${NGINX_HTTPS_PORT}:443
  
  certbot:
     image: certbot/certbot:latest
     command: certonly --webroot -w /var/www/certbot --keep-until-expiring --email ${SSL_CERT_EMAIL} -d ${HOST} --agree-tos
     volumes:
       - ./certbot/conf:/etc/letsencrypt
       - ./certbot/www:/var/www/certbot

  • Comment out local https nginx service:
  # for local https development using self-signed certs via openssl
  # nginx:
  #   image: nginx:latest
  #   depends_on:
  #     - main    
  #   ports:
  #     - "443:443"
  #   volumes:
  #     - ./https/certs/${SSL_SELF_SIGNED_CRT}:/etc/nginx/certs/${SSL_SELF_SIGNED_CRT}:ro
  #     - ./https/certs/${SSL_SELF_SIGNED_KEY}:/etc/nginx/certs/${SSL_SELF_SIGNED_KEY}:ro
  #     - ./https/nginx/automatisch_self_signed_nginx.conf:/etc/nginx/conf.d/
  • Edit the automatisch_letsencrypt_nginx.conf file and replace <HOSTNAME> with the domain name (i.e. automatisch.lasthourhosting.org)and save before continuing:
sudo nano https/nginx/automatisch_letsencrypt_nginx.conf
# initial nginx conf file needed when running certbot container the first time to generate ssl certs
# replace <HOSTNAME> with your DNS i.e.automatisch.lasthourhosting.org

server {
    
    # nginx http port
    listen 80;
    listen [::]:80;         
    server_name <HOSTNAME>;

    location / {
        
        # Forward to Automatisch site which is running on port 7757
        proxy_pass http://main:7757;
    }               

    location ~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }        
}
  • Run sudo docker compose up to generate SSL cert. You should see something like this in the console, note the .pem key locations and the cert expiration date:
certbot-1   | Successfully received certificate.
certbot-1   | Certificate is saved at: /etc/letsencrypt/live/automatisch.lasthourhosting.org/fullchain.pem
certbot-1   | Key is saved at:         /etc/letsencrypt/live/automatisch.lasthourhosting.org/privkey.pem
certbot-1   | This certificate expires on 2025-05-09.
certbot-1   | These files will be updated when the certificate renews.
  • After the containers are built and you see this line:
main-1      | 2025-02-11 15:58:06:586 [info]: Server is listening on http://automatisch.lasthourhosting.org:7757

stop the containers: ctrl+c

  • There should be a new /certbot folder created at the project root, and the cert and key .pem files should be created at /etc/letsencrypt/live
  • Give lasthour user and group access to the /certbot folder:
sudo chown -R lasthour:lasthour certbot
  • Overwrite the automatisch_letsencrypt_nginx.conf file with the secondary_automatisch_letsencrypt_nginx.conf file's contents which has the 443 https and SSL configs:
cp https/nginx/secondary_automatisch_letsencrypt_nginx.conf https/nginx/automatisch_letsencrypt_nginx.conf
  • Replace entries again with the DNS and save before continuing:
server {
    # nginx http port
    listen 80;
    listen [::]:80;        
    server_name <HOSTNAME>;

    location ~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    return 301 https://$host$request_uri;
}

server {

    # nginx https port
    listen      443 ssl;
    listen      [::]:443 ssl;
    http2 	    on;
    # use ssl letsencrypt certs
    ssl_certificate      /etc/letsencrypt/live/<HOSTNAME>/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/<HOSTNAME>/privkey.pem;
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1h;
    server_name <HOSTNAME>;

    location / {
        # Forward to Automatisch site which is running on port 7757
        proxy_pass http://main:7757/;
        proxy_http_version 1.1;
        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 https;            
    }               



    location ~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }        

}    
  • Then rebuild the containers: docker compose up -d. After it is rebuilt we should be able to pull up Automatisch at the DNS with a valid SSL cert bound to it
  • You can use user@automatisch.io and sample to login. Please do not forget to change your email and password from the settings page.

Cronjob for auto SSL Cert renewals

  • Locate Docker binary: whereis docker or sudo whereis docker
  • It should be in /usr/bin/docker, but wherever it is on the system, run crontab -e and enter this task to renew the ssl cert, replace /path/to/docker-compose.yml with the actual path where the docker-compose.yml file is: 0 5 1 */2 * /usr/bin/docker compose -f /path/to/docker-compose.yml up certbot