Deploy Spree
Open-source eCommerce platform with a REST API and admin dashboard
spree
Just deployed
Just deployed
/var/lib/postgresql/data
meilisearch
Just deployed
/meili_data
mailpit
Just deployed
/data
spree-worker
Just deployed
spree-storage
Bucket
Just deployed
Deploy and Host Spree on Railway
Spree is an open-source headless commerce platform built on Ruby on Rails, under the BSD 3-Clause licence. It ships a REST API, a TypeScript SDK, a React admin dashboard and a production-ready Next.js storefront, so brands, B2B wholesalers and marketplaces can run a real store with no platform fees and no vendor lock-in. Teams self-host Spree when a hosted platform cannot express their pricing or checkout: price lists per customer group, per-country markets, gift cards and digital products are all in the open-source core.
Deploy Spree on Railway and this template wires the production shape for you. The spree service runs Puma, the admin dashboard and the REST API. spree-worker is a dedicated Solid Queue process handling emails, image processing, imports, webhooks and search indexing off the request path. Postgres holds the catalogue and orders and — because Spree uses the Solid stack — the job queue, cache and Action Cable messages, so there is no Redis to run. meilisearch gives typo-tolerant product search, mailpit captures outbound email, and a Railway bucket holds product images through Active Storage.

Getting Started with Spree on Railway
Set ADMIN_EMAIL and ADMIN_PASSWORD before you click Deploy — Spree's first-boot seed reads them once and creates your administrator account. Leave them blank and it prints a one-time claim link in the logs instead, which is not what you want on a public URL. When the deploy is green, open the app's domain: / redirects to /admin. Start at Products → New Product, give it a name, price, SKU and stock count, then drop an image into the Media panel — the upload goes straight to your Railway bucket, and the thumbnail confirms object storage is wired. Create a draft order from Orders → New Order to check pricing and inventory. Invite a colleague from Settings → Users: the invitation lands in the Mailpit inbox on its own domain, proving the worker and mail path work end to end. Visit /jobs for the Solid Queue dashboard.

About Hosting Spree
Spree is API-first: the admin dashboard, the Next.js storefront, a mobile app and a point of sale all talk to the same REST API, so you can start with one backend and add channels later. Self-hosting earns its keep when you need to own customer and order data outright, or when your pricing rules are too specific for a SaaS product.
- Sales channels, markets and multi-currency cross-border selling
- B2B price lists, customer groups and gated catalogues
- Promotions engine, gift cards, store credit and digital products
- Stripe, Adyen and PayPal payment plugins bundled in the image
Web and worker run the same image; the web service hands jobs over by setting SOLID_QUEUE_IN_PUMA=false. Meilisearch switches on purely by the presence of MEILISEARCH_URL, so it needs no code change. Mailpit is capture-only — swap it for a real provider before you take orders.
Why Deploy Spree on Railway
Standing up six moving parts by hand is a day of work.
- Every service, volume and connection string pre-wired
- Managed Postgres with backups, and no Redis to operate
- Private networking between app, worker, search and mail
- HTTPS domain issued automatically for the admin and API
- Scale by raising replicas or worker threads
- Usage-based pricing with no per-order commerce fees
Common Use Cases
- A direct-to-consumer brand running the Next.js storefront against a self-hosted API
- B2B wholesale with negotiated price lists per customer group and gated catalogues
- A headless backend for a mobile app or point of sale sharing one catalogue
Dependencies for Spree
ghcr.io/spree/spree— the Rails application, admin dashboard and REST APIghcr.io/railwayapp-templates/postgres-ssl:18— catalogue, orders, jobs, cache, Action Cablegetmeili/meilisearch:v1.53— product search index with facets and typo toleranceaxllent/mailpit:v1.31— SMTP sink and web inbox for outbound mail- Railway object storage — product images and attachments via Active Storage
Postgres is the only hard dependency; Solid Queue, Solid Cache and Solid Cable all live inside it, which is why there is no separate queue or cache. Meilisearch earns its place once a catalogue passes roughly a thousand products, and Mailpit makes order mail visible from day one instead of silently disappearing.
Environment Variables Reference
| Variable | Service | Purpose |
|---|---|---|
DATABASE_URL | spree, spree-worker | Postgres connection string |
SECRET_KEY_BASE | spree | Signs sessions and cookies; shared with the worker |
RAILS_HOST | spree, spree-worker | Public host used in emails and image URLs |
ADMIN_EMAIL / ADMIN_PASSWORD | spree | First administrator, created at first boot |
MISSION_CONTROL_* | spree | Basic auth for the /jobs dashboard |
SOLID_QUEUE_IN_PUMA | spree | false while a dedicated worker runs |
WEB_CONCURRENCY | spree | Puma processes; each needs about 1 GB |
MEILISEARCH_URL / MEILISEARCH_API_KEY | spree, spree-worker | Enables the Meilisearch search provider |
SMTP_HOST / SMTP_PORT | spree, spree-worker | Outbound mail; unset disables delivery |
CLOUDFLARE_* | spree, spree-worker | Bucket credentials for uploads |
Deployment Dependencies
- Source: github.com/spree/spree
- Image: ghcr.io/spree/spree
- Storefront: github.com/spree/storefront
- Docs: spreecommerce.org/docs
Hardware Requirements for Self-Hosting Spree
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2–4 vCPU |
| RAM | 1 GB | 4 GB across web, worker and search |
| Storage | 5 GB Postgres volume | 10 GB plus object storage for media |
| Runtime | Ruby 4.0 / Rails 8.1 (in the image) | Same, plus PostgreSQL 18 |
Raise WEB_CONCURRENCY only alongside memory, and never set it to auto: it counts the machine's cores, not your container's limit.
Self-Hosting Spree with Docker
The official image runs migrations on boot and needs only a database. The following is a minimal Docker Compose file:
services:
postgres:
image: postgres:18-alpine
environment:
POSTGRES_HOST_AUTH_METHOD: trust
volumes: [pg:/var/lib/postgresql/data]
web:
image: ghcr.io/spree/spree:latest
environment:
DATABASE_URL: postgres://postgres@postgres:5432/spree_production
SECRET_KEY_BASE: replace-with-a-long-random-string
RAILS_HOST: localhost:3000
ADMIN_EMAIL: you@example.com
ADMIN_PASSWORD: choose-a-strong-password
ports: ["3000:3000"]
volumes: { pg: }
To split background processing out, set SOLID_QUEUE_IN_PUMA=false on the web service and run the same image with a different command:
docker run --rm -e DATABASE_URL=... -e SECRET_KEY_BASE=... \
ghcr.io/spree/spree:latest ./bin/jobs
To customise the store instead, scaffold it with npx create-spree-app@latest my-store, run spree eject, and build the backend/Dockerfile it produces.
How Much Does Spree Cost to Self-Host?
Spree's core is free and open source under the BSD 3-Clause licence, with no per-order or per-transaction fees — you keep the code, the data and the infrastructure. A paid Enterprise Edition adds extra modules and SLA-backed support, but nothing here depends on it. On Railway you pay only for the compute, storage and bandwidth used, so a small store costs a few dollars a month and grows with traffic rather than with revenue.
FAQ
What is Spree?
Spree is an open-source headless commerce platform written in Ruby on Rails. It ships a REST API, a TypeScript SDK, a React admin dashboard and an optional Next.js storefront, and powers direct-to-consumer brands, B2B wholesalers and marketplaces.
What does this Railway template deploy?
Five services — the Spree web application, a background worker, PostgreSQL, Meilisearch and Mailpit — plus an object storage bucket for media. Every connection string, volume and domain is configured before the first boot.
Why does the template include a separate worker service?
Spree runs emails, image processing, imports, webhooks and search indexing as background jobs. Keeping them in spree-worker means a large import cannot slow down checkout. Drop the service and set SOLID_QUEUE_IN_PUMA=true to run everything in one container.
Do I need Redis to self-host Spree?
No. Solid Queue, Solid Cache and Solid Cable all store their data in PostgreSQL — one fewer service to operate and back up.
How do I create the first admin user in self-hosted Spree?
Set ADMIN_EMAIL and ADMIN_PASSWORD before the first deploy; the seed creates the account. Further administrators are invited from Settings → Users.
How do I send real emails from Spree instead of using Mailpit?
Point SMTP_HOST, SMTP_PORT, SMTP_USERNAME and SMTP_PASSWORD at any provider — Resend, Postmark, Mailgun or Amazon SES — and set the store's From address under Settings → Emails.
Template Content
meilisearch
getmeili/meilisearch:v1.53mailpit
axllent/mailpit:v1.31spree-worker
ghcr.io/spree/spree:5.6.1spree-storage
Bucket
