What You’ll Create
1. Create the Database (RDS)
Create an RDS PostgreSQL instance in the AWS console:- Same VPC as your EC2 instance will use
- Public access: no — instead, allow inbound port
5432from the EC2 instance’s security group - Note the endpoint, username, and password — they become your
DATABASE_URL
2. Launch the Instance
Launch an EC2 instance (Ubuntu 24.04 or Amazon Linux 2023) and open ports80 and 443 in its security group. Give it a stable web address: associate an Elastic IP (so the instance’s IP survives restarts) and create a DNS record for your domain — e.g. an A record for store.example.com — pointing at it. HTTPS depends on this: Caddy can only obtain a certificate once the domain resolves to the instance.
Then install Docker:
3. Run Spree
Build your project’s image and push it to a registry the instance can pull from (ECR or any other) — or use the stockghcr.io/spree/spree:latest image to start. Then create a docker-compose.yml on the instance:
docker-compose.yml
https://store.example.com — admin at /admin, background jobs running inside the web container (combined mode).
Updating
Deploying a new version is a pull and a restart:Scaling on One Box
Before reaching for a cluster:- Bigger instance — a
t3.mediumort3.largecarries substantial traffic; resizing is a stop/start - Split the worker — add a second service to the compose file with
command: bin/jobs, and setSOLID_QUEUE_IN_PUMA: "false"onweb(split mode) - Scale the database — RDS resizes independently, and read replicas are a console click
Next Steps
- Asset Storage — store uploads in S3
- Set environment variables — SMTP, Sentry, etc.
- Configure CDN — CloudFront in front of your assets
- Deploy the storefront — the Next.js storefront ships separately, typically to Vercel
- ECS Fargate — when you outgrow one box

