Skip to content

Deployment

Deployment

HCP supports multiple deployment methods: Docker, Kamal, and traditional hosting.

Docker Deployment

Prerequisites

  • Docker 24+
  • Docker Compose 2.20+ (for development)
  • Server with 2GB+ RAM

Production Build

Terminal window
# Build image
docker build -t hcp:latest .
# Run container
docker run -d \
-p 80:80 \
-e RAILS_MASTER_KEY=<master_key> \
-e DATABASE_URL=<db_url> \
--name hcp \
hcp:latest

Docker Compose (Development)

Terminal window
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f web
# Run commands
docker-compose exec web bin/rails console

Environment Variables

VariableRequiredDescription
RAILS_MASTER_KEYYesEncryption key from config/master.key
DATABASE_URLYesPostgreSQL connection string
REDIS_URLNoRedis for caching (defaults to built-in)
RAILS_ENVNoproduction (default) or development

Production Dockerfile

# syntax=docker/dockerfile:1
FROM ruby:3.3-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y build-essential libpq-dev
COPY Gemfile Gemfile.lock ./
RUN bundle config set --local deployment 'true' && \
bundle config set --local without 'development test' && \
bundle install
COPY . .
RUN SECRET_KEY_BASE=dummy bundle exec rails assets:precompile
FROM ruby:3.3-slim AS runtime
WORKDIR /app
RUN apt-get update && apt-get install -y libpq-dev && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app /app
COPY --from=builder /usr/local/bundle /usr/local/bundle
ENV RAILS_ENV=production
ENV RAILS_SERVE_STATIC_FILES=true
EXPOSE 80
ENTRYPOINT ["./bin/docker-entrypoint"]
CMD ["./bin/thrust", "./bin/rails", "server"]

Kamal Deployment

Kamal is the recommended deployment method for production.

Installation

Terminal window
gem install kamal

Configuration

Create .kamal/deploy.yml:

service: hcp
image: benmacdonald/hcp
servers:
web:
- 192.168.1.100
- 192.168.1.101
proxy:
ssl: true
host: hcp.example.com
registry:
server: ghcr.io
username: benmacdonald
password:
- KAMAL_REGISTRY_PASSWORD
env:
secret:
- RAILS_MASTER_KEY
- DATABASE_URL
clear:
RAILS_ENV: production
RAILS_SERVE_STATIC_FILES: true
builder:
multiarch: false
args:
RUBY_VERSION: "3.3"

Deploy Commands

Terminal window
# Setup server (first time)
kamal setup
# Deploy
kamal deploy
# View logs
kamal logs
# Run console
kamal console
# Check status
kamal details
# Rollback
kamal rollback

SSL/TLS

Kamal automatically provisions SSL certificates via Let’s Encrypt when ssl: true is configured.

Cloud Deployment

Render.com

  1. Create new Web Service
  2. Connect GitHub repository
  3. Settings:
    • Runtime: Docker
    • Dockerfile Path: ./Dockerfile
    • Plan: Standard ($7+/month)
  4. Environment variables:
    • RAILS_MASTER_KEY
    • DATABASE_URL (from Render PostgreSQL)
  5. Deploy

Railway

Terminal window
# Install Railway CLI
npm install -g @railway/cli
# Login
railway login
# Link project
railway link
# Deploy
railway up

DigitalOcean App Platform

  1. Create App
  2. Select Docker source
  3. Configure environment variables
  4. Deploy

Database Setup

PostgreSQL

-- Create database
CREATE DATABASE hcp_production;
-- Create user
CREATE USER hcp WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE hcp_production TO hcp;

Connection URL

postgresql://hcp:secure_password@localhost:5432/hcp_production

Migrations

Terminal window
# Docker
docker-compose exec web bin/rails db:migrate
# Kamal
kamal exec 'bin/rails db:migrate'

Monitoring

Health Checks

Built-in health endpoint:

GET /up
Response: 200 OK (if healthy)

Logging

Kamal/Rails logs to stdout by default. Use external log aggregation:

  • Datadog
  • Papertrail
  • LogDNA

Metrics

Track key metrics:

  • Request count/latency
  • Database connections
  • Background job queue depth
  • Error rates

Backup & Recovery

Database Backups

Terminal window
# Automated daily backup
pg_dump $DATABASE_URL | gzip > backup-$(date +%Y%m%d).sql.gz
# Restore
gunzip < backup-20240115.sql.gz | psql $DATABASE_URL

Asset Storage

  • All assets are compiled into Docker image
  • No persistent storage required for uploads
  • Store backups externally (S3, etc.)

Security Checklist

  • Master key stored securely (not in repo)
  • Database credentials rotated regularly
  • SSL/TLS enabled
  • Firewall rules configured
  • Automated security updates enabled
  • Database backups encrypted
  • Access logs monitored

Next: Troubleshooting