Infrastructure Setup
Byconvo uses a modern containerized infrastructure with Kamal 2 for orchestration and GitHub Actions for CI/CD.
Server Configuration
Server Details:
- IP Address:
157.90.150.53 - Operating System: Linux with Docker
- Docker Version: Installed via official convenience script
- Access: SSH with key-based authentication
Applications Running
All three applications run on the same server with Kamal managing the container orchestration:
| Service | Domain | Container Port | Public Port |
|---|---|---|---|
| Monolith | app.byconvo.com | 3000 | 443 (HTTPS) |
| Website | byconvo.com, www.byconvo.com | 3000 | 443 (HTTPS) |
| Docs | docs.byconvo.com | 3000 | 443 (HTTPS) |
Kamal 2 Configuration
Kamal 2.2.1 is used for zero-downtime deployments, SSL management, and container orchestration.
Proxy Configuration
Each application uses Kamal’s built-in proxy (Traefik) for:
- SSL/TLS Termination: Automatic Let’s Encrypt certificates
- Health Checks: Endpoint monitoring every 10 seconds
- Load Balancing: Zero-downtime rolling deploys
- Host-based Routing: Multiple apps on single server
Health Check Endpoints
All applications expose a /up endpoint:
- Interval: 10 seconds
- Timeout: 10 seconds
- Path:
/up
Health checks ensure containers are ready before routing traffic.
Docker Registry
Registry: Docker Hub
Username: rutenisr
Authentication: Access token via KAMAL_REGISTRY_PASSWORD
Images
rutenisr/monolith- Rails applicationrutenisr/www- Marketing websiterutenisr/docs- Documentation siterutenisr/monolith-build-cache- Build cache for monolith
Build Configuration
All applications build for amd64 architecture:
builder:
arch: amd64The monolith uses registry caching for faster builds:
builder:
cache:
type: registry
image: rutenisr/monolith-build-cache
options: mode=maxSSL/TLS Configuration
Automatic Certificates
Kamal proxy automatically provisions Let’s Encrypt certificates for all domains:
- âś…
app.byconvo.com - âś…
byconvo.com - âś…
www.byconvo.com - âś…
docs.byconvo.com
Cloudflare Integration
If using Cloudflare:
- Set SSL/TLS encryption mode to “Full”
- This enables end-to-end encryption (Cloudflare ↔ Server)
- Kamal proxy handles SSL termination at the server
GitHub Actions Secrets
Required secrets for CI/CD:
| Secret | Purpose | Used By |
|---|---|---|
DOCKER_USERNAME | Docker Hub username | All apps |
DOCKER_PASSWORD | Docker Hub access token | All apps |
SSH_PRIVATE_KEY | Server SSH key | All apps |
SERVER_IP | Server IP address | All apps |
RAILS_MASTER_KEY | Rails encrypted credentials | Monolith only |
Secret Management
Secrets are stored in GitHub repository settings and injected during deployment:
env:
KAMAL_REGISTRY_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}Kamal loads secrets from .kamal/secrets file created during CI:
# Example .kamal/secrets format
KAMAL_REGISTRY_PASSWORD=<token>
RAILS_MASTER_KEY=<32-char-hex-key>Storage Volumes
Monolith Storage
The monolith uses a named Docker volume for persistent data:
volumes:
- "monolith_storage:/rails/storage"This stores:
- SQLite database files
- Active Storage uploads
- Other persistent data
Asset Bridging
Rails assets are bridged between deployments to avoid 404s:
asset_path: /rails/publicThis ensures in-flight requests work during rolling deployments.
Networking
Docker Network
Kamal creates an isolated Docker network for all containers on the same server.
Port Mapping
- Internal container port:
3000(Next.js/Rails) - External port:
443(HTTPS via Kamal proxy) - Health check port: Same as container port
Host Resolution
The Kamal proxy routes traffic based on the Host header:
app.byconvo.com→ monolith containerbyconvo.comorwww.byconvo.com→ www containerdocs.byconvo.com→ docs container
Monitoring & Health
Container Health Checks
Each app runs health checks every 10 seconds. If a container fails health checks:
- Traffic is stopped to that container
- Previous version continues serving requests
- Failed deployment is logged
Deployment Strategy
Zero-downtime rolling deploys:
- New container starts
- Health check passes
- Traffic switches to new container
- Old container stops
SSH Access
Direct server access via SSH:
Kamal commands can be run from the repository:
cd apps/monolith
kamal app logs -f # Follow logs
kamal app exec --interactive --reuse "bin/rails console"Environment Configuration
Production Environment
All apps run in production mode:
env:
clear:
RAILS_ENV: production # Rails only
NODE_ENV: production # All appsApp-Specific Variables
Monolith:
env:
clear:
SOLID_QUEUE_IN_PUMA: true
secret:
- RAILS_MASTER_KEYwww & docs:
- No special environment variables required
- Use Next.js standalone output mode
Disaster Recovery
Backup Strategy
Database & Files (Monolith):
- SQLite database in
monolith_storagevolume - Manual backups recommended for production use
- Consider volume snapshots or off-server backups
Docker Images:
- All images stored in Docker Hub
- Each deployment creates a new versioned image
- Rollback available via
kamal rollback
Rollback Procedure
If a deployment fails or needs rollback:
cd apps/<app-name>
kamal rollbackThis reverts to the previous working image.