Skip to content

Production Services (Bruno)

Complete documentation of all services running on Bruno (188.34.198.57).


Quick Reference Table

Service URL Container Purpose Recovery Priority
Traefik All HTTPS traefik Reverse proxy + SSL CRITICAL
Infisical secrets.kua.cl infisical Secrets management CRITICAL
PostgreSQL Internal postgres Shared database CRITICAL
Redis Internal redis Shared cache HIGH
Kuanary media.kua.cl kuanary Media CDN API HIGH
imgproxy cdn.kua.cl imgproxy Image optimization MEDIUM
Forgejo git.kua.cl forgejo Self-hosted Git HIGH
Obsidian notes.kua.cl obsidian Note taking MEDIUM
infra-docs docs.kua.cl infra-docs This documentation LOW
Watchtower - watchtower Auto-updates LOW

Traefik - Reverse Proxy

Purpose: Automatic HTTPS reverse proxy with Let's Encrypt SSL certificates

Property Value
Container traefik
Image traefik:v3.6
Ports 80 (HTTP→HTTPS), 443 (HTTPS)
SSL Let's Encrypt TLS Challenge

Version Requirement

Must use Traefik v3.6+ on Ubuntu 24.04 with Docker 29.x. Earlier versions cause Docker API version errors.

Configuration: Part of /root/coder-core/services/production/docker-compose.yml

Recovery: Auto-regenerates SSL certificates on restart

See also: Traefik Documentation


Infisical - Secrets Management

Purpose: Centralized secrets management for all services

Property Value
Containers infisical, postgres, redis
Image infisical/infisical:latest
URL https://secrets.kua.cl
Database PostgreSQL (shared)

Critical Secrets:

  • ENCRYPTION_KEY - UNRECOVERABLE IF LOST
  • AUTH_SECRET - JWT signing
  • Database credentials

Backup Strategy:

  1. Database dumps daily to Storage Box
  2. ENCRYPTION_KEY backed up to 4 locations

Recovery:

# 1. Restore database
ssh root@188.34.198.57 "cat /root/infisical_dump.sql | docker exec -i postgres psql -U kavi main"

# 2. Restart Infisical
ssh root@188.34.198.57 "docker restart infisical"

PostgreSQL - Shared Database

Purpose: PostgreSQL database for Infisical and other services

Property Value
Container postgres
Image postgres:16-alpine
Database Name main
User kavi
Data Location /root/coder-core/services/production/postgres/data

Used By:

  • Infisical (secrets storage)
  • (Future services)

Backup:

ssh root@188.34.198.57 "docker exec postgres pg_dump -U kavi main > /root/db_backup.sql"

Redis - Shared Cache

Purpose: Redis cache for Infisical session management

Property Value
Container redis
Image redis:alpine
Data Location /root/coder-core/services/production/redis/data

Used By:

  • Infisical (session cache)

Recovery: Ephemeral data, no backup needed


Kuanary - Media CDN API

Purpose: Custom-built media API for uploading and serving images via S3 + imgproxy

Property Value
Container kuanary
Build From /root/coder-core/kuanary
URL https://media.kua.cl
Storage Hetzner S3 Object Storage

Dependencies:

  • Hetzner S3 (stores uploaded images)
  • imgproxy (transforms images)

Environment Variables:

  • S3_ACCESS_KEY, S3_SECRET_KEY
  • S3_ENDPOINT, S3_BUCKET
  • IMGPROXY_URL, CDN_URL

Backup: S3 data managed separately, config in Git


imgproxy - Image Optimization

Purpose: On-the-fly image transformation and optimization

Property Value
Container imgproxy
Image darthsim/imgproxy:latest
URL https://cdn.kua.cl

Features:

  • Resize, crop, format conversion
  • S3 integration
  • Signed URLs for security

Environment Variables:

  • IMGPROXY_KEY, IMGPROXY_SALT (signing)
  • AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
  • IMGPROXY_S3_ENDPOINT, IMGPROXY_S3_REGION

Recovery: Stateless service, just restart


Forgejo - Self-Hosted Git

Purpose: Self-hosted Git server (Gitea fork)

Property Value
Container forgejo
Image codeberg.org/forgejo/forgejo:1.21
Web URL https://git.kua.cl
SSH ssh://git@188.34.198.57:2222
Data /mnt/storagebox/git (Storage Box)

Access:

  • HTTPS for web UI (via Traefik)
  • Port 2222 for Git SSH operations

Backup: Repositories stored on Storage Box

Usage:

# Clone a repository
git clone ssh://git@188.34.198.57:2222/kuatecno/coder-core.git

# Or via HTTPS
git clone https://git.kua.cl/kuatecno/coder-core.git

Obsidian - Note Taking

Purpose: Web-based Obsidian for note taking

Property Value
Container obsidian
Image lscr.io/linuxserver/obsidian:latest
URL https://notes.kua.cl
Vaults /mnt/storagebox/obsidian/vaults

Backup: Vaults stored directly on Storage Box

Recovery: Just restart (vaults are on Storage Box)


infra-docs - Documentation

Purpose: This MkDocs documentation site

Property Value
Container infra-docs
Build From /root/coder-core/docs
URL https://docs.kua.cl

Source: ~/coder-core/infra-docs/ (local)

Deployment: Built during docker compose up --build

Recovery: Rebuild from Git repository


Watchtower - Auto Updates

Purpose: Automatically update Docker containers

Property Value
Container watchtower
Image containrrr/watchtower
Schedule Daily at 4 AM

Behavior:

  • Checks for updated images daily
  • Automatically restarts containers with new images
  • Cleans up old images

Service Dependencies

                    ┌─────────┐
                    │ Traefik │ ← All HTTPS traffic
                    └────┬────┘
    ┌────────────────────┼────────────────────┐
    │                    │                    │
┌───┴───┐          ┌─────┴─────┐         ┌────┴────┐
│Infisic│          │  Kuanary  │         │ Forgejo │
│  al   │          │ +imgproxy │         │  (git)  │
└───┬───┘          └───────────┘         └─────────┘
┌───┴────────┐
│ PostgreSQL │
│   Redis    │
└────────────┘

Startup Order

When deploying, services start in this order (handled by depends_on):

  1. PostgreSQL + Redis (healthcheck must pass)
  2. Traefik (networking)
  3. Infisical (depends on postgres + redis)
  4. Kuanary + imgproxy (depends on imgproxy)
  5. Forgejo + Obsidian + infra-docs
  6. Watchtower (last)

Maintenance Commands

Check All Services

ssh root@188.34.198.57 "docker ps --format 'table {{.Names}}\t{{.Status}}'"

View Service Logs

# Traefik
ssh root@188.34.198.57 "docker logs --tail 50 traefik"

# Infisical
ssh root@188.34.198.57 "docker logs --tail 50 infisical"

# Any service
ssh root@188.34.198.57 "docker logs --tail 50 <container_name>"

Restart Services

# Restart single service
ssh root@188.34.198.57 "docker restart <container_name>"

# Restart all services
ssh root@188.34.198.57 "cd /root/coder-core/services/production && docker compose restart"

Deploy Updates

cd ~/coder-core/ansible
ansible-playbook playbooks/deploy-services.yml --limit bruno \
  -e "infisical_client_id=YOUR_ID" \
  -e "infisical_client_secret=YOUR_SECRET"

Check Storage

# Storage Box mount
ssh root@188.34.198.57 "df -h | grep storagebox"

# Local disk
ssh root@188.34.198.57 "df -h /"


Last updated: January 2026 - Bruno (188.34.198.57)