-
Notifications
You must be signed in to change notification settings - Fork 0
Sp7 stats fixes #5
base: main
Are you sure you want to change the base?
Changes from all commits
681888b
ebffd4e
132c89c
e0dfda1
5f640b7
70bfc0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,15 +3,17 @@ version: '3.9' | |
| services: | ||
| nginx: | ||
| build: https://github.com/specify/nginx-with-github-auth.git#main | ||
| # build: | ||
| # context: ~/nginx-with-github-auth | ||
| ports: | ||
| - '80:80' | ||
| - '443:443' | ||
| volumes: | ||
| - './sp7-stats/config/auth.conf:/etc/nginx/auth.conf:ro' | ||
| - './sp7-stats/config/nginx.conf:/etc/nginx/conf.d/default.conf:ro' | ||
| - './sp7-stats/:/var/www/:ro' | ||
| - './sp7-stats/config/fullchain.pem:/etc/letsencrypt/live/sp7-stats/fullchain.pem:ro' | ||
| - './sp7-stats/config/privkey.pem:/etc/letsencrypt/live/sp7-stats/privkey.pem:ro' | ||
| - '/etc/letsencrypt:/etc/letsencrypt:ro' | ||
| - './access-logs/:/var/log/nginx/external/:rw' | ||
| networks: | ||
| - nginx | ||
| depends_on: | ||
|
|
@@ -33,6 +35,20 @@ services: | |
| networks: | ||
| - nginx | ||
|
|
||
| certbot: | ||
| image: certbot/certbot | ||
| container_name: certbot | ||
| volumes: | ||
| - '/etc/letsencrypt:/etc/letsencrypt' | ||
| - './sp7-stats/:/var/www/certbot/' | ||
| - '/var/run/docker.sock:/var/run/docker.sock' | ||
| entrypoint: > | ||
| sh -c "trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot --deploy-hook 'docker exec sp7-stats-nginx-1 nginx -s reload'; sleep 12h; done" | ||
|
Comment on lines
+44
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify the hard-coded deploy-hook target used by certbot.
# Expect: the running nginx container name exactly matches sp7-stats-nginx-1.
docker compose ps nginx
docker container inspect sp7-stats-nginx-1 --format '{{.Name}} {{.State.Running}}'Repository: specify/sp7-stats Length of output: 239 🏁 Script executed: #!/bin/bash
set -euo pipefail
git ls-files docker-compose.yml
wc -l docker-compose.yml
sed -n '1,140p' docker-compose.yml
printf '\n-- references --\n'
rg -n "sp7-stats-nginx-1|docker.sock|certbot renew|nginx -s reload|certbot" -S .Repository: specify/sp7-stats Length of output: 2290 🏁 Script executed: #!/bin/bash
set -euo pipefail
wc -l docker-compose.yml
sed -n '1,140p' docker-compose.yml
printf '\n-- references --\n'
rg -n "sp7-stats-nginx-1|docker.sock|certbot renew|nginx -s reload|certbot" -S .Repository: specify/sp7-stats Length of output: 2271 Remove Docker socket access from certbot. The deploy hook also hard-codes 🤖 Prompt for AI Agents |
||
| networks: | ||
| - nginx | ||
| depends_on: | ||
| - nginx | ||
|
|
||
| networks: | ||
| nginx: | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -1,39 +1,81 @@ | ||||
| # Outbound DNS for Lua http requests | ||||
| # resolver 1.1.1.1 8.8.8.8 valid=300s; | ||||
| # resolver_timeout 5s; | ||||
|
|
||||
| # Trust store path on Alpine (nginx:alpine puts the bundle here) | ||||
| # lua_ssl_trusted_certificate /etc/ssl/cert.pem; | ||||
| # lua_ssl_verify_depth 5; | ||||
|
|
||||
| # See https://github.com/specify/nginx-with-github-auth | ||||
| include nginx-with-github-auth/http.conf; | ||||
|
|
||||
| # Redirect HTTP to HTTPs | ||||
| # --- HTTP (port 80) --- | ||||
| server { | ||||
| listen 80 default_server; | ||||
| server_name _; | ||||
| return 301 https://$host$request_uri; | ||||
| listen 80 default_server; | ||||
| listen [::]:80 default_server; | ||||
|
|
||||
| server_name stats.specifycloud.org sp7-stats.specifycloud.org; | ||||
|
|
||||
| # Serve ACME challenge over HTTP without redirect | ||||
| location ^~ /.well-known/acme-challenge/ { | ||||
| root /var/www/; | ||||
| try_files $uri =404; | ||||
| } | ||||
|
|
||||
| # Everything else: redirect to HTTPS | ||||
| location / { | ||||
| return 301 https://$host$request_uri; | ||||
| } | ||||
| } | ||||
|
|
||||
| # --- HTTPS (port 443) --- | ||||
| server { | ||||
| listen 443 ssl default_server; | ||||
| listen 443 ssl default_server; | ||||
| listen [::]:443 ssl default_server; | ||||
|
|
||||
| server_name stats.specifycloud.org sp7-stats.specifycloud.org; | ||||
|
|
||||
| # Use the certbot-standard live path for THIS domain name | ||||
| ssl_certificate /etc/letsencrypt/live/sp7-stats.specifycloud.org/fullchain.pem; | ||||
| ssl_certificate_key /etc/letsencrypt/live/sp7-stats.specifycloud.org/privkey.pem; | ||||
|
|
||||
| ssl_session_cache shared:SSL:10m; | ||||
| ssl_session_timeout 5m; | ||||
| ssl_prefer_server_ciphers on; | ||||
|
|
||||
| include auth.conf; | ||||
| include nginx-with-github-auth/server.conf; | ||||
|
|
||||
| ssl_certificate /etc/letsencrypt/live/sp7-stats/fullchain.pem; | ||||
| ssl_certificate_key /etc/letsencrypt/live/sp7-stats/privkey.pem; | ||||
| ssl_session_cache shared:SSL:10m; | ||||
| ssl_session_timeout 5m; | ||||
| ssl_prefer_server_ciphers on; | ||||
| index index.php index.html; | ||||
| keepalive_timeout 70; | ||||
| error_log /var/log/nginx/error.log; | ||||
| access_log /var/log/nginx/access.log; | ||||
| root /var/www/; | ||||
|
|
||||
| include auth.conf; | ||||
| include nginx-with-github-auth/server.conf; | ||||
| access_log /var/log/nginx/external/access.log combined; | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Keep the external stats log scoped to Line 55 mirrors every HTTPS request into the host-mounted external log, while Proposed change- access_log /var/log/nginx/external/access.log combined;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||
|
|
||||
| index index.php index.html; | ||||
| server_name sp7-stats; | ||||
| keepalive_timeout 70; | ||||
| error_log /var/log/nginx/error.log; | ||||
| access_log /var/log/nginx/access.log; | ||||
| root /var/www/; | ||||
| location = /capture { | ||||
| # Allow browser JS to call this cross-origin | ||||
| add_header 'Access-Control-Allow-Origin' '*' always; | ||||
| add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always; | ||||
| add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always; | ||||
| add_header 'Access-Control-Max-Age' 86400 always; | ||||
|
|
||||
| location ~ ^/.+\.php$ { | ||||
| include nginx-with-github-auth/location.conf; | ||||
| # Handle preflight (some browsers/frameworks trigger this) | ||||
| if ($request_method = OPTIONS) { | ||||
| return 204; | ||||
| } | ||||
|
|
||||
| include fastcgi_params; | ||||
| fastcgi_pass php:9000; | ||||
| fastcgi_index index.php; | ||||
| fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; | ||||
| } | ||||
| access_log /var/log/nginx/external/access.log combined; | ||||
| add_header Content-Type text/plain; | ||||
| return 204; | ||||
| } | ||||
|
|
||||
| location ~ ^/.+\.php$ { | ||||
| include nginx-with-github-auth/location.conf; | ||||
| include fastcgi_params; | ||||
| fastcgi_pass php:9000; | ||||
| fastcgi_index index.php; | ||||
| fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; | ||||
| } | ||||
| } | ||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
Add an initial certificate bootstrap path.
Line 46 only runs
certbot renew, which requires an existing cert. On a fresh Ubuntu 24 host with empty/etc/letsencrypt, nginx will try to load the live cert files before certbot can create them, so startup can fail. Add a one-timecertbot certonly --webroot ... -d stats.specifycloud.org -d sp7-stats.specifycloud.orgbootstrap or a documented temp-cert flow before nginx starts.🤖 Prompt for AI Agents