Skip to main content
The simplest way to run Spree on AWS is the single-node topology: one EC2 instance running the Docker image, one RDS database. No clusters, no load balancers, no task definitions — a complete production store for roughly the cost of a t3.small and a small RDS instance. Need auto-scaling, zero-downtime deploys, or CI/CD-driven infrastructure? That’s the ECS Fargate guide — it runs the same Docker image, so you can start here and graduate later without rework.

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 5432 from the EC2 instance’s security group
  • Note the endpoint, username, and password — they become your DATABASE_URL
Spree also runs on RDS MySQL/MariaDB and both Aurora flavors — see Database Configuration. RDS takes automated daily backups by default, so the database needs no extra care.

2. Launch the Instance

Launch an EC2 instance (Ubuntu 24.04 or Amazon Linux 2023) and open ports 80 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 stock ghcr.io/spree/spree:latest image to start. Then create a docker-compose.yml on the instance:
docker-compose.yml
The database is migrated automatically on boot. Once DNS resolves, your store is live at 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:
This restarts the container with a few seconds of downtime — the point at which that matters is a good signal to consider ECS Fargate and its rolling deploys.

Scaling on One Box

Before reaching for a cluster:
  • Bigger instance — a t3.medium or t3.large carries substantial traffic; resizing is a stop/start
  • Split the worker — add a second service to the compose file with command: bin/jobs, and set SOLID_QUEUE_IN_PUMA: "false" on web (split mode)
  • Scale the database — RDS resizes independently, and read replicas are a console click

Next Steps