Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ USE_HTTPS=true

DOMAIN=your.domain.here
EMAIL=your@email.here
# If you use letsencrypt and get https directly to nginx, use https mode,
# if you have something in front of nginx, like traefik/ngrok/apache that handles cerfiticates and
# you want to pass just http to nginx, use reverse_proxy mode. Same for local development, you can
# use reverse_proxy config to allow testing/development without ssl certificate.
#
# if you define PORT, it is used as what port is mapped to http port. In case you need to redefine
# https port, you need to modify docker-compose.yml or add override file for port-mapping yourself.
#
# If this is not defined, we default to https mode
#
# docker compose NGINX setup: https, reverse_proxy
NGINX_SETUP=https

# Instance default language (see options at bookwyrm/settings.py "LANGUAGES"
LANGUAGE_CODE="en-us"
Expand All @@ -18,7 +30,9 @@ DEFAULT_LANGUAGE="English"

# Specify when the site is served from a port that is not the default
# for the protocol (80 for HTTP or 443 for HTTPS).
# Probably only necessary in development.
#
# This tells what port to listen for example reverse_proxy mode, you shouldn't need to set it other
# cases.
# PORT=1333

STATIC_ROOT=static/
Expand Down
8 changes: 7 additions & 1 deletion bookwyrm/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,13 @@
CSRF_COOKIE_SECURE = True

PORT = env.int("PORT", 443 if USE_HTTPS else 80)
if (USE_HTTPS and PORT == 443) or (not USE_HTTPS and PORT == 80):

# If we are behind reverse_proxy, we can assume that protocol://domain should point to correct webserver that routes to our nginx
if (
(USE_HTTPS and PORT == 443)
or (not USE_HTTPS and PORT == 80)
or (env("NGINX_SETUP", "https") == "reverse_proxy")
):
NETLOC = DOMAIN
else:
NETLOC = f"{DOMAIN}:{PORT}"
Expand Down
3 changes: 3 additions & 0 deletions bw-dev
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ case "$CMD" in
initdb)
initdb "$@"
;;
init_ssl)
$DOCKER_COMPOSE --file ./docker-compose-init_letsencrypt.yml up --exit-code-from=certbot
;;
resetdb)
prod_error
$DOCKER_COMPOSE rm -svf
Expand Down
28 changes: 28 additions & 0 deletions docker-compose-init_letsencrypt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
services:
nginx:
image: nginx:1.25.2
ports:
- "80:80"
- "443:443"
networks:
- main
environment:
- DOMAIN=${DOMAIN}
volumes:
- ./nginx/locations:/etc/nginx/conf.d/locations
- ./nginx/server_config:/etc/nginx/conf.d/server_config
- ./nginx/server_name:/etc/nginx/conf.d/server_name
- ./nginx/ssl_bootstrap:/etc/nginx/templates/default.conf.template
- ./certbot/conf:/etc/nginx/ssl
- ./certbot/data:/var/www/certbot
certbot:
image: certbot/certbot:latest
command: certonly --webroot --webroot-path=/var/www/certbot --keep-until-expiring --email ${EMAIL} --agree-tos --no-eff-email -d ${DOMAIN}
depends_on:
- nginx
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/logs:/var/log/letsencrypt
- ./certbot/data:/var/www/certbot
networks:
main:
24 changes: 22 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,35 @@ services:
image: nginx:1.25.2
restart: unless-stopped
ports:
- "1333:80"
- "${PORT:-80}:80"
- "${PORT:-443:443}"
depends_on:
- web
networks:
- main
environment:
- DOMAIN=${DOMAIN}
volumes:
- ./nginx:/etc/nginx/conf.d
- ./nginx/${NGINX_SETUP:-https}.conf:/etc/nginx/templates/default.conf.template
- ./nginx/locations:/etc/nginx/conf.d/locations
- ./nginx/server_config:/etc/nginx/conf.d/server_config
- ./nginx/server_name:/etc/nginx/conf.d/server_name
- ./nginx/99-autoreload.sh:/docker-entrypoint.d/99-autoreload.sh
- ./certbot/conf:/etc/nginx/ssl
- ./certbot/data:/var/www/certbot
- static_volume:/app/static
- media_volume:/app/images
certbot:
image: certbot/certbot:latest
entrypoint: /bin/sh -c "trap exit TERM; while [ "$NGINX_SETUP" = "https" ];do certbot renew --webroot --webroot-path=/var/www/certbot; sleep 1d & wait $${!}; done"
environment:
- USE_HTTPS=${USE_HTTPS}
depends_on:
- nginx
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/logs:/var/log/letsencrypt
- ./certbot/data:/var/www/certbot
db:
image: postgres:13
env_file: .env
Expand Down
5 changes: 5 additions & 0 deletions nginx/99-autoreload.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
while true; do
sleep 1d
nginx -t && nginx -s reload
done &
84 changes: 84 additions & 0 deletions nginx/https.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
include /etc/nginx/conf.d/server_config;

upstream web {
server web:8000;
}
upstream flower{
server flower:8888;
}

server {
listen [::]:80;
listen 80;

include /etc/nginx/conf.d/server_name;

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

# redirect http to https
return 301 https://${DOMAIN}$request_uri;
}


server {
access_log /var/log/nginx/access.log cache_log;

listen [::]:443 ssl;
listen 443 ssl;

http2 on;

include /etc/nginx/conf.d/server_name;

client_max_body_size 3M;

if ($host != "${DOMAIN}") {
return 301 $scheme://${DOMAIN}$request_uri;
}

# SSL code
ssl_certificate /etc/nginx/ssl/live/${DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/${DOMAIN}/privkey.pem;

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

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
#include /etc/nginx/mime.types;
#default_type application/octet-stream;

gzip on;
gzip_disable "msie6";

proxy_read_timeout 1800s;
chunked_transfer_encoding on;

# store responses to anonymous users for up to 1 minute
proxy_cache bookwyrm_cache;
proxy_cache_valid any 1m;
add_header X-Cache-Status $upstream_cache_status;

# ignore the set cookie header when deciding to
# store a response in the cache
proxy_ignore_headers Cache-Control Set-Cookie Expires;

# PUT requests always bypass the cache
# logged in sessions also do not populate the cache
# to avoid serving personal data to anonymous users
proxy_cache_methods GET HEAD;
proxy_no_cache $cookie_sessionid;
proxy_cache_bypass $cookie_sessionid;

include /etc/nginx/conf.d/locations;

}

82 changes: 0 additions & 82 deletions nginx/production

This file was deleted.

19 changes: 0 additions & 19 deletions nginx/reverse_proxy

This file was deleted.

3 changes: 3 additions & 0 deletions nginx/development → nginx/reverse_proxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ server {
access_log /var/log/nginx/access.log cache_log;

listen 80;
include /etc/nginx/conf.d/server_name;

http2 on;

sendfile on;
tcp_nopush on;
Expand Down
1 change: 1 addition & 0 deletions nginx/server_name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
server_name ${DOMAIN};
11 changes: 11 additions & 0 deletions nginx/ssl_bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
server {
listen [::]:80;
listen 80;

include /etc/nginx/conf.d/server_name;

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