Retour à la documentation
Deployment

Dedicated Server Setup

Ansible-based infrastructure: base hardening, app deployment, and vault-managed secrets.

12 min de lecture

PlanToCode runs on dedicated servers managed through Ansible playbooks. This document covers the infrastructure setup, security hardening, and deployment process.

Infrastructure Layers

The infrastructure is organized into layers, each managed by dedicated playbooks:

  • Base layer: OS hardening, SSH configuration, firewall rules
  • Database layer: PostgreSQL 17 with replication and backups
  • Cache layer: Redis 7+ for session state and job queues
  • Application layer: Rust server binary with systemd service
  • Proxy layer: Nginx reverse proxy with SSL termination

Server Regions

PlanToCode runs in two regions for geographic redundancy:

  • EU region: Hetzner dedicated server (api-eu.plantocode.com)
  • US region: InterServer dedicated server (api-us.plantocode.com)

Server Requirements

  • Debian 12 or Ubuntu 22.04 LTS
  • 4+ CPU cores, 16GB+ RAM, 200GB+ SSD
  • Public IPv4 with firewall access to ports 22, 80, 443
  • SSH key access for Ansible deployment

Base Hardening

site-base.yml applies security hardening:

  • Disable root SSH login, require key authentication
  • Configure UFW firewall with minimal open ports
  • Install fail2ban for brute force protection
  • Enable automatic security updates
  • Configure audit logging

PostgreSQL Setup

PostgreSQL 17 is configured for production use:

  • Connection pooling with PgBouncer
  • Automated daily backups with pg_dump
  • WAL archiving for point-in-time recovery
  • SSL required for all connections
  • Row-level security for multi-tenant data

Redis Setup

Redis 7+ handles caching and session state:

  • Password authentication required
  • AOF persistence for durability
  • Memory limits with eviction policy
  • TLS encryption for connections

Zero-Downtime Deployment

Deployments use a rolling update strategy:

  • New binary uploaded alongside running version
  • Health check confirms new version is ready
  • Systemd restarts with graceful shutdown
  • Load balancer drains connections during switch
  • Rollback available via previous binary symlink

Quick Start

  1. Clone the infrastructure repository
  2. Copy inventory.example to inventory and configure hosts
  3. Set vault password in .vault_pass
  4. Run: ansible-playbook -i inventory site-base.yml
  5. Run: ansible-playbook -i inventory site-app.yml

Secrets Management

Sensitive configuration uses Ansible Vault:

  • Database credentials
  • API keys for LLM providers
  • SSL certificates and private keys
  • Auth0 client secrets
  • Stripe webhook secrets

Common Operations

  • ansible-playbook -i inventory site-app.yml --tags deploy
  • ansible-playbook -i inventory site-base.yml --tags backup
  • ansible-playbook -i inventory site-app.yml --tags rollback
  • ansible-playbook -i inventory site-base.yml --tags logs

SSL/TLS Configuration

Let's Encrypt provides free SSL certificates:

  • Certbot configured with Nginx plugin
  • Automatic renewal via cron job
  • HSTS headers enabled
  • TLS 1.2+ only, modern cipher suite

Security Checklist

  • All default passwords changed
  • SSH key rotation scheduled
  • Firewall rules audited
  • Security updates automated
  • Backup restoration tested

Disaster Recovery

Recovery procedures for common failure scenarios:

  • Database corruption: Restore from latest pg_dump backup
  • Server failure: Provision new server and run playbooks
  • SSL expiration: Manual certbot renew --force-renewal
  • Security breach: Rotate all credentials, audit logs