Merge branch 'feature/caddy'

This commit is contained in:
Hubert Van De Walle 2020-05-05 17:13:26 +02:00
commit c703af8187
8 changed files with 126 additions and 160 deletions

51
caddy/Caddyfile Normal file
View File

@ -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}
}

52
caddy/Caddyfile.prod Normal file
View File

@ -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}
}

6
caddy/Dockerfile Normal file
View File

@ -0,0 +1,6 @@
FROM caddy:2.0.0
COPY caddy/Caddyfile.prod /etc/caddy/Caddyfile
# Copy main website
COPY frontend/dist /site

View File

@ -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:

View File

@ -1,9 +0,0 @@
version: '2.2'
services:
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot

View File

@ -119,6 +119,10 @@ export default {
},
},
},
generate: {
fallback: '404.html',
},
/*
** Build configuration
*/

View File

@ -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

View File

@ -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/;
}
}