From 173e4f89a0291466097ab7975b427e2f277410a9 Mon Sep 17 00:00:00 2001 From: Bauke Date: Sat, 10 Jun 2023 13:08:46 +0200 Subject: [PATCH] Add the production document. --- PRODUCTION.md | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 PRODUCTION.md diff --git a/PRODUCTION.md b/PRODUCTION.md new file mode 100644 index 0000000..6ec143b --- /dev/null +++ b/PRODUCTION.md @@ -0,0 +1,117 @@ +# Production Overview + +This document details how the production instance of Tildes Statistics at [ts.bauke.xyz](https://ts.bauke.xyz) is put together. + +## Compose + +The Compose setup uses a shared network for every service so no ports ever need to be exposed, helps with making sure UFW and Docker play nice together. Then three services are created, namely: + +* `tildes-statistics-app`, the main Tildes Statistics CLI, pulled from `git.bauke.xyz/tildes-community/tildes-statistics:latest`. +* `tildes-statistics-db`, a PostgreSQL 14 instance from the official image. +* `tildes-statistics-netlify`, an unofficial Netlify CLI image (because there is no official one). + +The `tildes-statistics-app` and `tildes-statistics-netlify` services share the `data` volume so the CLI can build the website and then Netlify can publish it. The `tildes-statistics-db` service has its own `db` volume so data is persisted. + +```yaml +# compose.yaml +version: "3" + +networks: + shared-network: + external: true + +services: + tildes-statistics-app: + image: "git.bauke.xyz/tildes-community/tildes-statistics:latest" + hostname: "tildes-statistics-app" + container_name: "tildes-statistics-app" + restart: "no" + depends_on: + - "tildes-statistics-db" + environment: + DATABASE_URL: "${DATABASE_URL}" + USER_AGENT: "${USER_AGENT}" + networks: + - "shared-network" + volumes: + - "data:/public" + + tildes-statistics-db: + image: "postgres:14" + hostname: "tildes-statistics-db" + container_name: "tildes-statistics-db" + restart: "unless-stopped" + mem_limit: "200m" + environment: + POSTGRES_DB: "${POSTGRES_DB}" + POSTGRES_USER: "${POSTGRES_USER}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" + networks: + - "shared-network" + volumes: + - "db:/var/lib/postgresql/data" + + tildes-statistics-netlify: + image: "williamjackson/netlify-cli" + hostname: "tildes-statistics-netlify" + container_name: "tildes-statistics-netlify" + restart: "no" + depends_on: + - "tildes-statistics-db" + environment: + NETLIFY_AUTH_TOKEN: "${NETLIFY_AUTH_TOKEN}" + networks: + - "shared-network" + volumes: + - "data:/project" + +volumes: + data: + db: +``` + +## Environment + +The `.env` file is loaded in by Docker Compose and the variables are replaced in the `compose.yaml` file for each service. + +```sh +# .env + +# The User-Agent string for HTTP requests, replace the email with yours. +USER_AGENT="Tildes Statistics (Production, your-email@example.org)" + +# The full PostgreSQL connection string for the Tildes Statistics CLI. +DATABASE_URL="postgres://username:password@localhost:5432/database" + +# The connection details for the PostgreSQL service. +# Make sure these match the DATABASE_URL. +POSTGRES_DB="database" +POSTGRES_USER="username" +POSTGRES_PASSWORD="password" + +# The Netlify token to authenticate with. +# https://docs.netlify.com/cli/get-started/#authentication +NETLIFY_AUTH_TOKEN="" +``` + +## Crontab + +The server is set to the UTC timezone so using Cron, deploy the website once a day at 12:00. + +```txt +# crontab -e +# Change $USER to your username if you're copying this. +00 12 * * * cd "/home/$USER/tildes-statistics" && ./deploy.sh +``` + +## Deployment + +The `deploy.sh` script then creates the snapshot for today, builds the website and publishes it to Netlify. + +```sh +#!/usr/bin/env bash + +docker compose run tildes-statistics-app tildes-statistics --no-migrate snapshot create +docker compose run tildes-statistics-app tildes-statistics --no-migrate web build +docker compose run tildes-statistics-netlify deploy --dir . --message "Automated daily 12:00 UTC deployment." --prod --site tildes-statistics +```