diff --git a/.env.sample b/.env.sample index b474d9f..ec1441d 100644 --- a/.env.sample +++ b/.env.sample @@ -1,29 +1,42 @@ TYPE=parasol-static-site DOMAIN=parasol-static-site.example.com -#EXTRA_DOMAIN=',`www.parasol-static-site.example.com`' +#EXTRA_DOMAINS=',`www.parasol-static-site.example.com`' LETS_ENCRYPT_ENV=production COMPOSE_FILE="compose.yml" # **NOTE** Please change this value to your repo HUGO_GIT_URL=ssh://git@codeberg.org:eotl/example-repo.git -# optionally configure git branch -#HUGO_GIT_BRANCH=staging +# optionally configure git branch for main domain +#HUGO_GIT_BRANCH=branch -# Configrue hugo build mode (takes precedence over the config file) -HUGO_BASEURL=https://${DOMAIN} +# optionally deploy staging subdomain from this branch +#COMPOSE_FILE="$COMPOSE_FILE:compose.staging.yml" +#HUGO_GIT_BRANCH_STAGING=staging +#EXTRA_DOMAINS="$EXTRA_DOMAINS,`staging.$DOMAIN`" + +# Configure hugo build mode (takes precedence over the config file) +HUGO_BASEURL=${DOMAIN} HUGO_ENVIRONMENT=production # set the used Hugo version optionally, otherwise the version defined in site-badger is used #HUGO_VERSION=0.143.1 -# HTTP Basic Auth protected /deploy endpoint +# HTTP Basic Auth protection #COMPOSE_FILE="$COMPOSE_FILE:compose.auth.yml" -#AUTH_ENABLED=1 #AUTH_USERNAME=foobar +# Enable protection for /deploy endpoint +#AUTH_ENABLED=1 +# Enable protection for / endpoint (whole site) +#AUTH_SITE_ENABLED=1 +# Enable protection for /deploy endpoint for staging site +#AUTH_STAGING_ENABLED=1 +# Enable protection for / endpoint (whole staging site) +#AUTH_SITE_STAGING_ENABLED=1 #SECRET_AUTH_PASSWORD_VERSION=v1 # Private repository deployment #COMPOSE_FILE="$COMPOSE_FILE:compose.private.yml" +#COMPOSE_FILE="$COMPOSE_FILE:compose.private.staging.yml" #PRIVATE_ENABLED=1 #SECRET_DEPLOY_KEY_VERSION=v1 # generate=false #WHD_HOOK_TIMEOUT=10 diff --git a/README.md b/README.md index ee608dd..8668d82 100644 --- a/README.md +++ b/README.md @@ -33,30 +33,30 @@ This will deploy a **public website** built from a Hugo site stored in a **git r ### Public Site & Public Repo -The default deployment is a **fully public** site and **public git repository.** +The default deployment is a **fully public** site and served from a **public git repository.** * `/`: the Hugo site is served -* `/deploy`: triggers `webhookd` to re-build the site, includes publicly viewable build logs. ⚠️ **Be aware that misuse could lead to constant CPU usage on your server, as /deploy is not rate limited. This mode is not recommended** +* `/deploy`: triggers `webhookd` to re-build the site, includes publicly viewable build logs. ⚠️ **Be aware that misuse could lead to constant CPU usage on your server and factually DDoS the site, as /deploy is not rate limited. This mode is not recommended. Add basic auth to all /deploy endpoints!** +### Additional staging deployment -### Use HTTP Basic Auth for `/deploy` endpoint +Additionally to the deployment of the regular site, a staging deployment can be activated. This will be served at the `staging` subdomain. +To activate it set the branch from which the site shall be built with `HUGO_GIT_BRANCH_STAGING` and activate the compose file and the `EXTRA_DOMAINS`. -To enable a password protected /deploy endpoint, uncomment the -following lines in your `.env` file: +### HTTP Basic Auth Protection -``` -COMPOSE_FILE="$COMPOSE_FILE:compose.auth.yml" -AUTH_ENABLED=1 -AUTH_USERNAME=foobar -SECRET_AUTH_PASSWORD_VERSION=v1 -``` +To enable a password protection for your site, uncomment the lines after `# HTTP Basic Auth protection` in your `.env` file: +4 different endpoints can be protected: the `/deploy` endpoints of the default site and the staging site. Also the default site and the staging site can be protected as a whole. Set the corresponding env vars as needed. -Then run `abra app secret generate -a ` command. +Then run `abra app secret generate example.org auth_password v1` command. Note the generated password to be able to access the protected endpoints later. This password is used for all 4 possible endpoints. +Also set a user name in `AUTH_USERNAME`. -### Use automatic deployment with your GIT instance +In case you protect one or both deploy endpoints with basic auth, you need to give the username password combination to your git service. -Depending on which git platform you use, adding the auth information might be a little different. This is how it works with Forgejo/Codeberg. -Generate a bas64 coded token for the protected endpoint: +#### Automatic deployment with protected endpoints with your GIT instance + +Depending on which git platform you use, adding the auth information might be a little different. This is how it works with Forgejo/Codeberg. Do this also for the deploy endpoint of the staging site if you actevated it. +Generate a base64 coded token for the protected endpoint: ``` echo -n ':' | base64 ``` @@ -65,9 +65,9 @@ Create a webhook which triggers the endpoint /deploy on push events Basic ``` -### Us a Private Repository +### Use a Private Repository -If you enable the following lines in your `.env` file: +Enable the following lines in your `.env` file: ``` COMPOSE_FILE="$COMPOSE_FILE:compose.private.yml" @@ -81,7 +81,7 @@ Then you need to generate a SSH key: $ ssh-keygen -a 100 -t ed25519 -C ``` -Then, insert the secret: +Then, insert the private key as a secret: ``` $ abra secret insert deploy_key v1 -f -t diff --git a/abra.sh b/abra.sh index 557d3a7..0d8ff9d 100644 --- a/abra.sh +++ b/abra.sh @@ -1,6 +1,6 @@ export APP_ENTRYPOINT_VERSION=v1 export BADGER_ENTRYPOINT_VERSION=v2 -export DEFAULT_CONF_VERSION=v2 +export DEFAULT_CONF_VERSION=v3 export SSH_CONF_VERSION=v1 export SSH_DEPLOY_KEY_VERSION=v1 export WEBHOOKD_SCRIPT_VERSION=v3 diff --git a/compose.private.staging.yml b/compose.private.staging.yml new file mode 100644 index 0000000..506e083 --- /dev/null +++ b/compose.private.staging.yml @@ -0,0 +1,14 @@ +--- +version: "3.8" + +services: + badger-staging: + configs: + - source: ssh_conf + target: /root/.ssh/config + - source: ssh_deploy_key + target: /root/.ssh/deploy + mode: 0400 + secrets: + - deploy_key + diff --git a/compose.staging.yml b/compose.staging.yml new file mode 100644 index 0000000..d38642f --- /dev/null +++ b/compose.staging.yml @@ -0,0 +1,40 @@ +--- +version: "3.8" + +services: + app: + volumes: + - nginx-data-staging:/usr/share/nginx/website-staging + + badger-staging: + image: git.coopcloud.tech/toolshed/site-badger:0.3.0 + environment: + - CUSTOM_DEPLOY_ENABLED + - CUSTOM_DEPLOY_SCRIPT + - HUGO_GIT_URL + - HUGO_GIT_BRANCH=${HUGO_GIT_BRANCH_STAGING} + - HUGO_PUBLIC_DIR=/usr/share/nginx/website-staging + - HUGO_WORKING_DIR=/root/website-staging + - HUGO_VERSION + - PRIVATE_ENABLED + - WHD_SCRIPTS=/root/scripts + - WHD_HOOK_TIMEOUT=${WHD_HOOK_TIMEOUT:-10} + - HUGO_ENVIRONMENT + - HUGO_BASEURL=https://staging.${HUGO_BASEURL} + command: webhookd + entrypoint: /entrypoint.sh + networks: + - internal + configs: + - source: webhookd_script + target: /root/scripts/deploy.sh + mode: 0555 + - source: badger_entrypoint + target: /entrypoint.sh + mode: 0555 + volumes: + - nginx-data-staging:/usr/share/nginx/website-staging + +volumes: + nginx-data-staging: + diff --git a/compose.yml b/compose.yml index eb60db7..e84b286 100644 --- a/compose.yml +++ b/compose.yml @@ -48,7 +48,7 @@ services: - WHD_SCRIPTS=/root/scripts - WHD_HOOK_TIMEOUT=${WHD_HOOK_TIMEOUT:-10} - HUGO_ENVIRONMENT - - HUGO_BASEURL + - HUGO_BASEURL=https://${HUGO_BASEURL} command: webhookd entrypoint: /entrypoint.sh networks: diff --git a/default.conf.tmpl b/default.conf.tmpl index 505e4f4..c54439e 100644 --- a/default.conf.tmpl +++ b/default.conf.tmpl @@ -5,6 +5,10 @@ server { index index.html; location / { + {{ if eq (env "AUTH_SITE_ENABLED") "1" }} + auth_basic "Site access restricted"; + auth_basic_user_file /etc/nginx/.htpasswd; + {{ end }} try_files $uri $uri/index.html =404; } @@ -31,3 +35,41 @@ server { proxy_pass http://badger:8080; } } + +server { + listen 80; + server_name staging.{{ env "DOMAIN" }}; + root /usr/share/nginx/website-staging; + index index.html; + + location / { + {{ if eq (env "AUTH_SITE_STAGING_ENABLED") "1" }} + auth_basic "Site access restricted"; + auth_basic_user_file /etc/nginx/.htpasswd; + {{ end }} + try_files $uri $uri/index.html =404; + } + + # Media: images, icons, video, audio, HTC + location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|mp3|ogg|ogv|webm|htc)$ { + expires 1M; + access_log off; + # max-age must be in seconds + add_header Cache-Control "max-age=2629746, public"; + } + + # CSS and Javascript + location ~* \.(?:css|js|ttf|otf|woff2|woff)$ { + expires 1y; + access_log off; + add_header Cache-Control "max-age=31556952, public"; + } + + location /deploy { + {{ if eq (env "AUTH_STAGING_ENABLED") "1" }} + auth_basic "Administrator’s Area"; + auth_basic_user_file /etc/nginx/.htpasswd; + {{ end }} + proxy_pass http://badger-staging:8080; + } +}