tildes-statistics/PRODUCTION.md

118 lines
3.6 KiB
Markdown
Raw Permalink Normal View History

2023-06-10 11:08:46 +00:00
# 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
```