Configurations

Configurations

How to configure services and systems. All services follow standard patterns for consistency and maintainability.

Docker Compose Patterns

Standard Service Pattern

Every service uses this basic structure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
x-environment: &shared-environment
  TZ: "Europe/Moscow"

name: service-name

services:
  service:
    container_name: service-name
    image: image:tag
    volumes:
      - ./@tier1/config:/config:ro
      - ./@tier2/data:/data
      - ./@tier3/cache:/cache
    environment:
      <<: *shared-environment
      SERVICE_VAR: ${SERVICE_VAR:?error}
    networks:
      enclave:
        ipv4_address: 10.x.y.2
      root-proxy: {}
    restart: unless-stopped
    labels:
      - "traefik.http.routers.service.rule=Host(`service.domain.com`)"

networks:
  enclave:
    name: service-enclave
    internal: true
    ipam:
      config:
        - subnet: 10.x.y.0/24
  root-proxy:
    external: true

Network Configuration

Network Types

  • Enclave: service-enclave (internal communication)
  • Direct: service-direct (external connectivity)
  • Proxy: root-proxy (web access through Traefik)
  • Socket: root-socket (Docker API access)

IP Ranges

1
2
3
4
# Node-specific ranges
daedalus: 10.0.x.0/24, 172.20.x.0/24
helios:   10.2.1.0/24, 192.168.1.0/24 (macvlan)
icarus:   10.1.x.0/24, 172.20.x.0/24

Common Service Configurations

Web Service with Database

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
services:
  app:
    networks:
      - enclave
      - root-proxy
    environment:
      DATABASE_URL: postgresql://user:pass@database:5432/db
    labels:
      - "traefik.http.routers.app.rule=Host(`app.domain.com`)"
      
  database:
    networks:
      - enclave
    volumes:
      - ./@tier2/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD:?error}

Service with External Access

1
2
3
4
5
6
7
8
9
services:
  app:
    networks:
      - enclave
      - direct
    ports:
      - "25565:25565"  # Exposed port
    volumes:
      - ./@tier2/data:/data

Environment Variables

Standard Variables

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Common to all services
TZ="Europe/Moscow"
NODE_NAME="hostname"

# Service URLs
SERVICE_URL="https://service.domain.com"

# Telegram notifications
TELEGRAM_BOT_TOKEN="your-bot-token"
TELEGRAM_CHAT_ID="your-chat-id"

Security Variables

1
2
3
4
# Use error-on-undefined pattern
DATABASE_PASSWORD=${DB_PASSWORD:?error}
API_KEY=${API_KEY:?error}
SECRET_KEY=${SECRET_KEY:?error}

Firewall Configuration

Host-Specific Setup

Firewall is configured through host-specific scripts that handle node environment and OS considerations:

1
2
3
4
5
6
# Recommended: Use host-specific script
cd node/.host
./10-ufw

# Direct script usage (also works)
.scripts/ops/envsubst-ufw ./.host/ufw/rules ./.host/ufw/host.rules

Host Script Pattern

Create node/.host/.scripts/10-ufw for node-specific firewall setup:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/env bash
source "$(git -C "$(dirname "$0")" rev-parse --show-toplevel)/.scripts/bootstrap.sh"

setup_ufw_config() {
    local ufw_dir="$REPO_ROOT/$NODE/.host/ufw"
    if [[ -d "$ufw_dir" ]]; then
        log_info "Applying UFW configuration for $NODE..."
        "$SCRIPTS_ROOT/ops/envsubst-ufw" "$ufw_dir/rules" "$ufw_dir/host.rules"
    fi
}

init_service "ufw" "ufw" "setup_ufw_config"

UFW Rule Files

Create rule files in node/.host/ufw/:

Service rules (rules/service.rules):

1
2
3
4
# Docker service rules
allow service-name 80/tcp
allow service-name 443/tcp
deny service-name 23/tcp

Host rules (host.rules):

1
2
3
4
5
# Host-level UFW rules
allow from 192.168.1.0/24 to any port 22
allow 80/tcp
allow 443/tcp
limit ssh

SSL/TLS Configuration

Traefik ACME

1
2
3
4
5
6
7
command:
  - "--certificatesresolvers.cloudflare.acme.dnschallenge=true"
  - "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
  - "--certificatesresolvers.cloudflare.acme.email=${ACME_EMAIL:?error}"

labels:
  - "traefik.http.routers.service.tls.certresolver=cloudflare"

Backup Configuration

Rclone Setup

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
services:
  rclone-tier1:
    image: rclone/rclone:latest
    volumes:
      - ./@tier1:/data/tier1:ro
      - ./rclone/config:/config/rclone:ro
    command: sync /data/tier1 remote:backup/tier1

  rclone-tier2:
    image: rclone/rclone:latest
    volumes:
      - ./@tier2:/data/tier2:ro
      - ./rclone/config:/config/rclone:ro
    command: sync /data/tier2 remote:backup/tier2

Cron Configuration

Host-Specific Setup

Similar to firewall, cron is configured through host-specific scripts:

1
2
3
4
5
6
# Recommended: Use host-specific script
cd node/.host
./20-cron

# Direct script usage
.scripts/ops/envsubst-crontab ./.host/cron/crontab

Host Script Pattern

Create node/.host/.scripts/20-cron:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/env bash
source "$(git -C "$(dirname "$0")" rev-parse --show-toplevel)/.scripts/bootstrap.sh"

setup_cron_config() {
    local crontab_file="$REPO_ROOT/$NODE/.host/cron/crontab"
    if [[ -f "$crontab_file" ]]; then
        log_info "Applying cron configuration for $NODE..."
        "$SCRIPTS_ROOT/ops/envsubst-crontab" "$crontab_file"
    fi
}

init_service "cron" "cron" "setup_cron_config"

Standard Cron Jobs

1
2
3
4
5
6
7
8
# Backup (daily at 2 AM)
0 2 * * * cd $REPO_ROOT && .scripts/ops/sync-tiers $NODE $TELEGRAM_BOT_URL

# Updates (weekly)
0 3 * * 0 apt update && apt upgrade -y

# Cleanup (weekly)
0 1 * * 6 docker system prune -af

Resource Management

Standard Limits

1
2
3
4
5
6
7
deploy:
  resources:
    limits:
      memory: 1G
      pids: 200
    reservations:
      memory: 256M

Logging

1
2
3
4
5
logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

Health Checks

Standard Health Check

1
2
3
4
5
6
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 60s

Database Health Check

1
2
3
4
healthcheck:
  test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
  interval: 30s
  retries: 3

These patterns provide a solid foundation for configuring any service consistently across all nodes, with proper consideration for node-specific environments and requirements.

Last updated on