all repos

onasty @ ac9bab3

a one-time notes service
11 files changed, 250 insertions(+), 2 deletions(-)
chore: add deploy suite (#210)

Author: Oleksandr Smirnov olexsmir@gmail.com
Committed by: GitHub noreply@github.com
Committed at: 2025-09-12 14:41:21 +0300
Parent: 10fe031
A deploy/.env.example

Not showing binary file.

A deploy/README.md

@@ -0,0 +1,22 @@

+# Deploy + +>[!IMPORTANT] Before deploying: +> 1. Set the environment variables in `docker-compose.yml` and `docker-compose.monitoring.yml` before running them. +> 1. Set your domain in `../infra/caddy/Caddyfile`. + +Building the frontend app, so it can be served: +```bash +./build.sh +``` + +Run the containers: +```bash +docker compose up -d +``` + +Run the monitoring suite: +```bash +docker compose up -d -f docker-compose.monitoring.yml +``` + +The monitoring suite is not added to the Caddyfile, so you would need to be in the same network to access it.
A deploy/build.sh

@@ -0,0 +1,11 @@

+#!/usr/bin/env bash +set -e + +echo "📦 Building frontend..." +cd ../web +task install +task build + +echo "📂 Copying frontend files..." +rm -rf ../deploy/frontend/* +cp -r dist/* ../deploy/frontend/
A deploy/docker-compose.monitoring.yml

@@ -0,0 +1,63 @@

+services: + prometheus: + image: prom/prometheus:latest + container_name: onasty-prometheus + user: root + volumes: + - onasty-prometheus:/prometheus + - ../infra/prometheus:/etc/prometheus + ports: + - 9090:9090 + networks: [onasty] + restart: unless-stopped + + grafana: + image: grafana/grafana:11.1.6 + container_name: onasty-grafana + user: root + environment: + - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} + volumes: + - onasty-grafana:/var/lib/grafana + - ../infra/grafana/datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml + - ../infra/grafana/dashboards.yml:/etc/grafana/provisioning/dashboards/dashboards.yml + - ../infra/grafana/dashboards:/etc/grafana/provisioning/dashboards + ports: + - 3000:3000 + networks: [onasty] + restart: unless-stopped + depends_on: + - prometheus + + loki: + image: grafana/loki:3.2.0 + command: ["--pattern-ingester.enabled=true", "-config.file=/etc/loki/config.yaml"] + ports: + - 3100:3100 + volumes: + - onasty-loki:/loki + - ../infra/loki/config.yaml:/etc/loki/config.yaml:ro + networks: [onasty] + restart: unless-stopped + + promtail: + image: grafana/promtail:3.0.0 + command: -config.file=/etc/promtail/config.yaml + volumes: + - ../infra/promtail/config.yaml:/etc/promtail/config.yaml:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + - /var/lib/docker/containers:/var/lib/docker/containers:ro + networks: [onasty] + restart: unless-stopped + depends_on: + - loki + +networks: + onasty: + external: true + +volumes: + onasty-prometheus: + onasty-grafana: + onasty-loki:
A deploy/docker-compose.yml

@@ -0,0 +1,133 @@

+services: + caddy: + image: caddy:2.7-alpine + container_name: onasty-caddy-prod + ports: + - "80:80" + - "443:443" + volumes: + - ../infra/caddy:/etc/caddy:ro + - ./frontend:/srv/frontend # frontend dist + - caddy_data:/data + networks: [onasty] + restart: unless-stopped + depends_on: + - core + + core: + image: onasty:core # TODO: use registry link + container_name: onasty-core-prod + ports: + - 8000:8000 + - 8001:8001 + environment: + - APP_ENV=prod + - APP_URL + - NATS_URL=nats:4222 + - CORS_ALLOWED_ORIGINS + - CORS_MAX_AGE + - HTTP_PORT + - HTTP_WRITE_TIMEOUT + - HTTP_READ_TIMEOUT + - HTTP_HEADER_MAX_SIZE_MB + - POSTGRESQL_DSN + - REDIS_ADDR + - REDIS_PASSWORD + - REDIS_DB + - CACHE_NOTE_TTL + - CACHE_USERS_TTL + - PASSWORD_SALT + - NOTE_PASSWORD_SALT + - JWT_SIGNING_KEY + - JWT_ACCESS_TOKEN_TTL + - JWT_REFRESH_TOKEN_TTL + - VERIFICATION_TOKEN_TTL + - RESET_PASSWORD_TOKEN_TTL + - CHANGE_EMAIL_TOKEN_TTL + - GOOGLE_CLIENTID + - GOOGLE_SECRET + - GOOGLE_REDIRECTURL + - GITHUB_CLIENTID + - GITHUB_SECRET + - GITHUB_REDIRECTURL + - METRICS_PORT + - METRICS_ENABLED + - LOG_LEVEL + - LOG_FORMAT + - LOG_SHOW_LINE + - RATELIMITER_TTL + - RATELIMITER_RPS + - RATELIMITER_BURST + - SLOW_RATELIMITER_TTL + - SLOW_RATELIMITER_RPS + - SLOW_RATELIMITER_BURST + restart: unless-stopped + networks: [onasty] + depends_on: + - mailer + - redis + - postgres + - nats + + mailer: + image: onasty:mailer # TODO: use registry link + container_name: onasty-mailer-prod + ports: + - 8002:8002 + environment: + - APP_URL + - FRONTEND_URL + - NATS_URL + - MAILGUN_FROM + - MAILGUN_DOMAIN + - MAILGUN_API_KEY + - LOG_LEVEL + - LOG_FORMAT + - LOG_SHOW_LINE + - METRICS_PORT + - METRICS_ENABLED + restart: unless-stopped + networks: [onasty] + depends_on: + - nats + + nats: + image: nats:2.10 + container_name: onasty-nats-prod + ports: + - 4222:4222 + restart: unless-stopped + networks: [onasty] + + redis: + image: redis:7.4-alpine + container_name: onasty-redis-prod + command: redis-server --appendonly yes + ports: + - 6379:6379 + restart: unless-stopped + networks: [onasty] + volumes: + - onasty-redis:/data + + postgres: + image: postgres:16-alpine + container_name: onasty-postgres-prod + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: onasty + volumes: + - onasty-postgres:/var/lib/postgresql/data + ports: + - 5432:5432 + networks: [onasty] + restart: unless-stopped + +volumes: + onasty-postgres: + onasty-redis: + caddy_data: + +networks: + onasty:
A deploy/frontend/.gitignore

@@ -0,0 +1,2 @@

+/* +!/.gitignore
M docker-compose.yml

@@ -18,7 +18,7 @@ image: onasty:core

container_name: onasty-core build: context: . - dockerfile: Dockerfile + dockerfile: core.Dockerfile env_file: .env ports: - 8000:8000

@@ -35,7 +35,7 @@ image: onasty:mailer

container_name: onasty-mailer build: context: . - dockerfile: ./mailer/Dockerfile + dockerfile: mailer.Dockerfile env_file: ./mailer/.env depends_on: - runtime

@@ -66,6 +66,7 @@ - 5432:5432

nats: image: nats:2.10 + container_name: onasty-nats ports: - 4222:4222
A infra/caddy/Caddyfile

@@ -0,0 +1,16 @@

+your.domain.name { + encode gzip + + reverse_proxy /api/* core:8000 + + root * /srv/frontend + try_files {path} /index.html + file_server + + header { + Strict-Transport-Security max-age=31536000; + X-Content-Type-Options nosniff + X-Frame-Options DENY + X-XSS-Protection "1; mode=block" + } +}
A web.Dockerfile

Not showing binary file.