{Service Name} — Operations Workbook
Standard: project-standards.md Replace all
{placeholders}and remove this note before committing.
Overview
| Property | Value |
|---|---|
| Service | {service-name} |
| Host | {vps-label} ({ip}) |
| Public URL | https://{hostname}.infra.zintegrowana.online |
| Compose file | services/{service-name}/docker-compose.yml |
| Workbook last reviewed | YYYY-MM-DD |
Brief description: what this service does and why we run it.
Architecture
{diagram: containers, ports, volumes, networks, external dependencies}| Container | Image | Ports | Purpose |
|---|---|---|---|
{container} | {image}:{tag} | {host:container} | {purpose} |
Volumes:
| Volume | Mounted at | Contents |
|---|---|---|
{volume-name} | /path/in/container | {what’s stored} |
Networks: {network-name} — {purpose}
Dependencies: {what this service calls or requires}
Config Management
| File | Location on server | In repo? | Contains secrets? |
|---|---|---|---|
docker-compose.yml | {path} | ✅ services/{name}/ | No |
{config-file} | {path} | ✅ sanitized / ❌ | {yes/no + note} |
.env | {path} | ❌ .env.example only | Yes |
Secret injection:
Describe how secrets get from .env.local → server (e.g., generate-config.sh, direct copy, Ansible).
Credentials (key names only — values NEVER here):
| Key name | Stored in | Used for |
|---|---|---|
{KEY_NAME} | /path/to/.env on {vps} | {purpose} |
Deployment
Fresh install
# 1. Clone repo
git clone https://github.com/radieu/p24-infra /opt/p24-infra
mkdir -p /root/{service-name}
# 2. Create .env
cp /opt/p24-infra/services/{name}/.env.example /root/{service-name}/.env
# fill in secrets
# 3. Generate config (if applicable)
bash /opt/p24-infra/services/{name}/scripts/generate-config.sh
# 4. Start
cd /root/{service-name} && docker compose up -dUpdate (rolling)
cd /opt/p24-infra && git pull
cp /opt/p24-infra/services/{name}/docker-compose.yml /root/{name}/
cd /root/{name} && docker compose up -dBackup
What is backed up:
| Data | Method | Frequency | Destination |
|---|---|---|---|
| {data} | {method} | Daily / Weekly | s3://p24-infra/{service-name}/ |
Run manually:
python3 /root/{name}/scripts/backup.py
tail -20 /var/log/{name}-backup.logCron: 0 2 * * * — daily at 02:00 UTC
Restore
From latest backup
# 1. Download from Wasabi (or use existing dump on server)
# 2. Stop service
cd /root/{name} && docker compose stop {service-container}
# 3. Restore
{restore command}
# 4. Start
docker compose start {service-container}
# 5. Verify
docker logs {container} --tail=30Last tested: YYYY-MM-DD — result: {pass/fail, notes}
Upgrade
# 1. Backup first — always
python3 /root/{name}/scripts/backup.py
# 2. Pull new image
cd /root/{name} && docker compose pull
# 3. Recreate
docker compose up -d
# 4. Check logs
docker logs {container} --tail=50Note: {any migration warnings, schema changes, etc.}
Monitoring & Alerts
| Alert | Severity | Condition | Action |
|---|---|---|---|
{ServiceName}Down | critical | container absent >2min | docker start {container} on {vps} |
{ServiceName}HighRestarts | warning | >2 restarts/hour | check logs |
Blackbox probe: https://{hostname} — checked every 30s.
Healthcheck
# Quick manual check
curl -s -o /dev/null -w "%{http_code}" http://localhost:{port}
docker ps --filter name={container}Password Rotation
| Credential | Key name | Rotation frequency | How to rotate |
|---|---|---|---|
| {credential} | {KEY_NAME} | 90 days | {steps} |
Known Limitations / Standard Exceptions
{If any standard requirement cannot be met, document it here with justification.}
| Requirement | Status | Reason | Compensating control | Target date |
|---|---|---|---|---|
| {requirement} | partial / no | {why} | {what we do instead} | {date or N/A} |