Setting up SSL on nginx
05 August 2024
After setting up my Gitea server and my file server, I wanted a quick way to test any WebGPU or WebXR apps that I’ve made. Neither of these will run on website that don’t support SSL, so I decided to set that up real quick.
Setting up certbot
To start things off, I found a general guide on doing that here.
To summarize, I needed to set up Let’s Encrypt’s certbot which would set up
an ACME challenge, which
needed to be accessible on http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>,
where TOKEN describes an automatically generated token by certbot.
Using the site above as a general guide, I added certbot to my nginx
container’s docker-compose.yml:
version: "3"
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
volumes:
- <host-path-to-shared-folder>:/srv/www/files:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certbot/www/:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
depends_on:
- webserver
Then I ran the command:
docker-compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d \<domain-name\>
This calls on certbot to create an ACME challenge in the /var/www/certbot/
folder. certbot then attempts to access this file through the given domain
name, and it’s considered a success if it can find it. Meanwhile, we’ve made
the volumes that certbot writes to accessible to our nginx webserver.
Of course, the nginx configuration file also needed to be changed accordingly:
events {}
http {
include mime.types;
server {
listen 80;
listen [::]:80;
server_name <domain-name>;
server_tokens off;
location /.well-known/acme-challenge/ {
allow all;
root /var/www/certbot/;
}
location / {
return 301 https://<domain-name>$request_uri;
}
}
server {
listen 443 default_server ssl;
listen [::]:443 ssl;
http2 on;
server_name <domain-name>;
ssl_certificate /etc/nginx/ssl/live/<domain-name>/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/<domain-name>/privkey.pem;
location /files {
root <host-path-to-shared-folder>;
autoindex on;
}
location ~ ^/(git)($|/) {
client_max_body_size 512M;
rewrite ^ $request_uri;
rewrite ^/git$ /git/ permanent;
rewrite ^(/git)?(/.*) $2 break;
proxy_pass http://172.17.0.1:18202$uri;
# other common HTTP headers, see the "Nginx" config section above
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
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;
}
}
}
To summarize what this does, it makes certbot’s ACME challenge folder
accessible through my domain. Once the domain has passed the ACME challenge,
it writes the SSL configuration files to a given folder, which I also make
accessible to the nginx container. nginx then uses this to certify the server.
Other than that, nginx also now redirects all http requests to their
equivalent https address. The flow can be traced back by examining the
configs above and checking which folders map to which volumes.
Next steps
My Gitea server still doesn’t support SSH, and I really should use networks to point my nginx container to the Gitea container. I’ll also need to check on why LFS uploads don’t work as fast as they should. Other than that, I’d say that this is all in at least a perfectly usable state and I’m quite happy with the current set up.
