Compare commits

..

2 Commits

Author SHA1 Message Date
Bauke d669bef623
Update SeaORM entities and remove warning exception. 2023-06-10 13:16:54 +02:00
Bauke 173e4f89a0
Add the production document. 2023-06-10 13:08:46 +02:00
6 changed files with 124 additions and 7 deletions

117
PRODUCTION.md Normal file
View File

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

View File

@ -1,8 +1,8 @@
//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "group_data")] #[sea_orm(table_name = "group_data")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]

View File

@ -1,4 +1,4 @@
//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
pub mod prelude; pub mod prelude;

View File

@ -1,4 +1,4 @@
//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
pub use super::group_data::Entity as GroupData; pub use super::group_data::Entity as GroupData;
pub use super::snapshot::Entity as Snapshot; pub use super::snapshot::Entity as Snapshot;

View File

@ -1,8 +1,8 @@
//! SeaORM Entity. Generated by sea-orm-codegen 0.9.3 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
#[sea_orm(table_name = "snapshot")] #[sea_orm(table_name = "snapshot")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]

View File

@ -27,7 +27,7 @@ pub mod utilities;
/// ``` /// ```
/// sea-orm-cli generate entity -o source/entities /// sea-orm-cli generate entity -o source/entities
/// ``` /// ```
#[allow(missing_docs, clippy::derive_partial_eq_without_eq)] #[allow(missing_docs)]
pub mod entities; pub mod entities;
/// The main function. /// The main function.