- wget not available in Docmost Node.js image → switch to curl
- Ansible now checks Docker health status instead of exec-ing into container
- Increased healthcheck start_period to 60s and retries to 10 for DB migrations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
First deploy needs time for DB migrations and initial setup.
30×10s = 300s gives enough buffer for cold start.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ansible evaluates Jinja2 expressions even in YAML comments, causing
'outline_mcp_image is undefined' error. Removed the entire block since
outline-mcp is no longer relevant (replaced Outline with Docmost).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On a fresh DB Outline shows a blank login page because there is no team
and emailSigninEnabled = false. Add idempotent Ansible tasks that:
1. Create the 'Visual' team if none exists
2. Set guestSignin=true so email magic-link login works
Triggered by: server rebuild lost Outline DB (no backup existed).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rotate ci_deploy_pubkey to new ed25519 key (old key lost after
server rebuild; Forgejo secret SSH_PRIVATE_KEY updated to match)
- Increase plane-api start_period 60s→120s, retries 5→10 to give
Django time to run DB migrations after backup restore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These custom images (discord-bot, walava-web) are built by their own
repos' CI/CD and pushed to git.walava.io registry. On a fresh server
Forgejo hasn't run yet so images don't exist — bootstrap chicken/egg.
Re-enable after Forgejo is up and images are pushed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
outline-mcp uses git.walava.io/jack/outline-mcp:latest which doesn't
exist in Forgejo registry yet (Forgejo itself wasn't running).
Comment out the service; re-enable after building the image.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Manages main + tools servers and S3 buckets (walava-backup, walava-outline).
Includes mon server resource for import + destroy workflow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Monitoring stack (Prometheus, AlertManager, Grafana, Loki, Uptime Kuma)
moved from main to tools server. Prometheus now scrapes main exporters
over network (ip_main:9100/8080). Promtail pushes logs to ip_tools:3100.
Traefik routes for dash/status.walava.io updated to ip_tools. discord-bot
PROMETHEUS_URL updated to http://ip_tools:9090.
Outline S3 fix: remove AWS_S3_ACL=private (Timeweb doesn't support
per-object ACLs — caused upload failures). Add CORS configuration task
for browser-side presigned uploads.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Outline needs proxy network for SMTP (Resend) and S3 (Timeweb).
n8n needs proxy network for external API calls in workflows.
Both were only on backend (internal:true) so DNS/TCP to internet was blocked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tools-server (85.193.83.9) has outbound SMTP ports 465/587 blocked by VPS
provider. Added tecnativa/postfix-relay container on main server that relays
to smtp.resend.com:587. Outline now uses ip_main:1025 as SMTP host.
- UFW rule: allow port 1025 from ip_tools only
- Remove stale authelia_image from docker pull list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add outline-mcp service to tools docker-compose (was running unmanaged)
- Update OUTLINE_URL from csrx.ru → walava.io via domain_wiki variable
- Bind port 8765 to 127.0.0.1 only (was 0.0.0.0 — security improvement)
- Add vault_outline_mcp_api_key to vault + alias in main.yml
- Remove stale authelia_* aliases from main.yml (authelia removed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- domain_base changed to walava.io
- domain_n8n now auto.walava.io
- Added domain_landing for walava.io root
- Added walava-web landing page container + Traefik route
- Updated Cloudflare token/zone_id for walava.io account
- Updated ACME email to walava@tutamail.com
- Fixed discord-bot image to use domain_base variable
- DNS records already created in Cloudflare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ensures removed services (vaultwarden, mailserver, snappymail)
are automatically stopped on next deploy.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents the 'meta json: readObjectStart' error on fresh deploys.
Existing hooks already fixed via direct DB update.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add vault_forgejo_api_token (Personal Access Token with write:repository)
- Ansible task now creates Discord webhook on both jack/infra and jack/discord-bot
- Webhooks already created manually for this deploy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Added vault_openrouter_api_key for n8n AI automations
- Added openrouter_api_key alias in main.yml
- Removed vault_syncthing_basic_auth_htpasswd (Syncthing was removed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Container was on backend (internal: true) only — couldn't resolve
discord.com for webhook notifications. Added proxy network which
has outbound internet access.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Leftover after Vaultwarden removal caused CI/CD deploy to fail with
'vaultwarden_admin_token is undefined' during .env template rendering.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without these env vars Next.js SSR renders with wrong base URL causing
React hydration error #418 — server/client HTML mismatch on first render.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SnappyMail defaulted to localhost:143 for IMAP. Create csrx.ru.json
domain config pointing to the mailserver container (shared front network):
- IMAP: mailserver:993 SSL
- SMTP: mailserver:587 STARTTLS with auth
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
djmaze/snappymail does not reliably apply SNAPPYMAIL_ADMIN_PASSWORD.
Instead: read current hash from application.ini, verify it against vault
password using password_verify() in container PHP, update only if wrong.
Idempotent — no restart if password is already correct.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace broken PHP require path with docker restart to let entrypoint
apply SNAPPYMAIL_ADMIN_PASSWORD env var (path /var/www/snappymail/index.php
does not exist in djmaze/snappymail image)
- Move snappymail from webmail-internal to mail-internal so it can reach
mailserver for IMAP/SMTP connections
- Remove unused webmail-internal network
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The SNAPPYMAIL_ADMIN_PASSWORD env var may not apply if the container
started when data dir had wrong permissions. Now sets password directly
via RainLoop PHP API after every deploy — idempotent and reliable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Timeweb S3 doesn't support per-object storage class via API parameter.
Cold storage is configured at bucket level in Timeweb control panel.
Also: make S3 upload failures explicit (exit 1) instead of silently ignored.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>