From eae3a9103ad86c94cb55c13b4bd0a24076cd3c3c Mon Sep 17 00:00:00 2001 From: Hubert Van De Walle Date: Tue, 5 May 2020 15:09:14 +0200 Subject: [PATCH] Testing caddy --- caddy/Caddyfile | 51 +++++++++++++++++++++++++++ caddy/Caddyfile.prod | 52 ++++++++++++++++++++++++++++ caddy/Dockerfile | 6 ++++ docker-compose.prod.yml | 24 +++++++------ docker-compose.ssl.yml | 9 ----- frontend/nuxt.config.js | 4 +++ init-letsencrypt.sh | 77 ----------------------------------------- nginx/server.conf | 63 --------------------------------- 8 files changed, 126 insertions(+), 160 deletions(-) create mode 100644 caddy/Caddyfile create mode 100644 caddy/Caddyfile.prod create mode 100644 caddy/Dockerfile delete mode 100644 docker-compose.ssl.yml delete mode 100755 init-letsencrypt.sh delete mode 100644 nginx/server.conf diff --git a/caddy/Caddyfile b/caddy/Caddyfile new file mode 100644 index 0000000..a6a1958 --- /dev/null +++ b/caddy/Caddyfile @@ -0,0 +1,51 @@ +(security) { + header * { + -Server + -Date + + Strict-Transport-Security "max-age=31536000; includeSubDomains" + Content-Security-Policy "default-src 'self' 'unsafe-inline' https://fonts.gstatic.com https://fonts.googleapis.com https://cdn.jsdelivr.net;" + Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer none;gyroscope none;speaker self;vibrate none;fullscreen self;payment none;" + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + X-XSS-Protection "1; mode=block" + Referrer-Policy "origin" + } +} + +localhost { + @static { + path *.css *.js + file + } + + @404 { + expression {http.error.status_code} == 404 + } + + route /* { + reverse_proxy http://localhost:3000 + } + + handle_errors { + rewrite @404 /404.html + reverse_proxy http://localhost:3000 + } + + route /api/* { + uri strip_prefix /api + reverse_proxy http://localhost:8081 + } + + header @static Cache-Control "public, max-age=31536000" + + encode gzip + root * /home/hubert/Workspace/Notes-TFE/frontend/dist + log + + import security +} + +www.localhost { + redir * https://localhost{path} +} diff --git a/caddy/Caddyfile.prod b/caddy/Caddyfile.prod new file mode 100644 index 0000000..5001bae --- /dev/null +++ b/caddy/Caddyfile.prod @@ -0,0 +1,52 @@ +(security) { + header * { + -Server + -Date + + Strict-Transport-Security "max-age=31536000; includeSubDomains" + Content-Security-Policy "default-src 'self' 'unsafe-inline' https://fonts.gstatic.com https://fonts.googleapis.com https://cdn.jsdelivr.net;" + Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer none;gyroscope none;speaker self;vibrate none;fullscreen self;payment none;" + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + X-XSS-Protection "1; mode=block" + Referrer-Policy "origin" + } +} + +simplenotes.be { + @static { + path *.css *.js + file + } + + @404 { + expression {http.error.status_code} == 404 + } + + route /* { + file_server + } + + handle_errors { + rewrite @404 /404.html + file_server + import security + } + + route /api/* { + uri strip_prefix /api + reverse_proxy http://api:8081 + } + + header @static Cache-Control "public, max-age=31536000" + + encode gzip + root * /site + log + + import security +} + +www.simplenotes.be { + redir * https://simplenotes.be{path} +} \ No newline at end of file diff --git a/caddy/Dockerfile b/caddy/Dockerfile new file mode 100644 index 0000000..1844f7e --- /dev/null +++ b/caddy/Dockerfile @@ -0,0 +1,6 @@ +FROM caddy:2.0.0 + +COPY caddy/Caddyfile.prod /etc/caddy/Caddyfile + +# Copy main website +COPY frontend/dist /site diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 69c7506..ecb78ac 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -2,23 +2,21 @@ version: '2.2' services: - nginx: - image: nginx:latest - container_name: notes-nginx + caddy: + build: + context: . + dockerfile: ./caddy/Dockerfile + container_name: notes-caddy environment: - - PUID=1000 - - PGID=1000 - TZ=Europe/Brussels volumes: - - ./frontend/dist:/usr/share/nginx/html - - ./nginx:/etc/nginx/conf.d - - ./data/certbot/conf:/etc/letsencrypt - - ./data/certbot/www:/var/www/certbot + - notes-caddy-data:/data + - notes-caddy-config:/config + depends_on: + - api ports: - 80:80 - 443:443 - depends_on: - - api api: build: ./api @@ -31,3 +29,7 @@ services: depends_on: db: condition: service_healthy + +volumes: + notes-caddy-data: + notes-caddy-config: diff --git a/docker-compose.ssl.yml b/docker-compose.ssl.yml deleted file mode 100644 index e0835b5..0000000 --- a/docker-compose.ssl.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '2.2' - -services: - - certbot: - image: certbot/certbot - volumes: - - ./data/certbot/conf:/etc/letsencrypt - - ./data/certbot/www:/var/www/certbot \ No newline at end of file diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js index 57e9306..4ed03a6 100644 --- a/frontend/nuxt.config.js +++ b/frontend/nuxt.config.js @@ -119,6 +119,10 @@ export default { }, }, }, + + generate: { + fallback: '404.html', + }, /* ** Build configuration */ diff --git a/init-letsencrypt.sh b/init-letsencrypt.sh deleted file mode 100755 index f0ac2e4..0000000 --- a/init-letsencrypt.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -if ! [ -x "$(command -v docker-compose)" ]; then - echo 'Error: docker-compose is not installed.' >&2 - exit 1 -fi - -domains=(simplenotes.be) -rsa_key_size=4096 -data_path="./data/certbot" -email="hubv@protonmail.com" -staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits - -if [ -d "$data_path" ]; then - read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision - if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then - exit - fi -fi - -if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then - echo "### Downloading recommended TLS parameters ..." - mkdir -p "$data_path/conf" - curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf >"$data_path/conf/options-ssl-nginx.conf" - curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem >"$data_path/conf/ssl-dhparams.pem" - echo -fi - -echo "### Creating dummy certificate for $domains ..." -path="/etc/letsencrypt/live/$domains" -mkdir -p "$data_path/conf/live/$domains" -docker-compose run --rm --entrypoint "\ - openssl req -x509 -nodes -newkey rsa:1024 -days 1\ - -keyout '$path/privkey.pem' \ - -out '$path/fullchain.pem' \ - -subj '/CN=localhost'" certbot -echo - -echo "### Starting nginx ..." -docker-compose up --force-recreate -d nginx -echo - -echo "### Deleting dummy certificate for $domains ..." -docker-compose run --rm --entrypoint "\ - rm -Rf /etc/letsencrypt/live/$domains && \ - rm -Rf /etc/letsencrypt/archive/$domains && \ - rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot -echo - -echo "### Requesting Let's Encrypt certificate for $domains ..." -#Join $domains to -d args -domain_args="" -for domain in "${domains[@]}"; do - domain_args="$domain_args -d $domain" -done - -# Select appropriate email arg -case "$email" in -"") email_arg="--register-unsafely-without-email" ;; -*) email_arg="--email $email" ;; -esac - -# Enable staging mode if needed -if [ $staging != "0" ]; then staging_arg="--staging"; fi - -docker-compose run --rm --entrypoint "\ - certbot certonly --webroot -w /var/www/certbot \ - $staging_arg \ - $email_arg \ - $domain_args \ - --rsa-key-size $rsa_key_size \ - --agree-tos \ - --force-renewal" certbot -echo - -echo "### Reloading nginx ..." -docker-compose exec nginx nginx -s reload diff --git a/nginx/server.conf b/nginx/server.conf deleted file mode 100644 index 9574548..0000000 --- a/nginx/server.conf +++ /dev/null @@ -1,63 +0,0 @@ -server { - listen 80; - server_name simplenotes.be; - - location /.well-known/acme-challenge/ { - root /var/www/certbot; - } - - location / { - return 301 https://$host$request_uri; - } -} - -server { - listen 443 ssl http2; - server_name simplenotes.be; - - ssl_certificate /etc/letsencrypt/live/simplenotes.be/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/simplenotes.be/privkey.pem; - - include /etc/letsencrypt/options-ssl-nginx.conf; - ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; - - gzip on; - gzip_vary on; - gzip_min_length 1400; - gzip_proxied expired no-cache no-store private auth; - gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; - gzip_disable "MSIE [1-6]\."; - - location ~* \.(css|js)$ { - root /usr/share/nginx/html; - expires 1m; - add_header Cache-Control "public, max-age=2628000"; - } - - location / { - root /usr/share/nginx/html; - index index.html index.htm; - - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - - # FIXME disable inlines in webpack - add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' https://fonts.gstatic.com https://fonts.googleapis.com https://cdn.jsdelivr.net;"; - - add_header Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer none;gyroscope none;speaker self;vibrate none;fullscreen self;payment none;"; - add_header X-Content-Type-Options "nosniff" always; - add_header X-Frame-Options "DENY" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Referrer-Policy "origin" always; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - - location /api/ { - rewrite ^/api/(.*) /$1 break; - proxy_pass http://api:8081/; - } - -}