Deploy Saleor
Open-source commerce backend for building your own online store
saleor-api
Just deployed
Redis
Just deployed
/data
saleor-dashboard
Just deployed
Just deployed
/var/lib/postgresql/data
saleor-beat
Just deployed
/app/beat
mailpit
Just deployed
/data
saleor-worker
Just deployed
saleor-media
Bucket
Just deployed
Deploy and Host Saleor on Railway
Saleor is an open-source, GraphQL-native commerce platform for teams whose storefront, mobile app and internal tools should share one API rather than one theme engine. Catalogue, channels, stock, checkout, orders, promotions and payment orchestration sit behind one typed GraphQL endpoint, and the admin dashboard is just another client of it. It suits anyone building a custom storefront in Next.js, Astro or Swift.
Deploy Saleor on Railway and you get the production shape, not a single container: a uvicorn API, a Celery worker for webhooks, exports and mail, a beat scheduler, the React dashboard, Postgres, Redis, object storage for media, and a capture-only inbox for reading what the store sends before you wire a real relay. Media uploads go straight to the bucket and are served through signed URLs, so nothing depends on local disk. Self-host Saleor this way and all that is left to build is the storefront.

Getting Started with Saleor on Railway
Set SALEOR_ADMIN_EMAIL and SALEOR_ADMIN_PASSWORD before deploying — the first staff account is created from them during the first migration, and there are no default credentials to change afterwards. The first boot builds Saleor's full schema, so give it a couple of minutes, then open the dashboard URL and sign in. Go to Catalog → Products → Create Product, pick the seeded Default Type and save; use Manage channels to add it to the Default Channel, choose a category, and add a priced variant so it is sellable. Upload an image under Media — the thumbnail comes from the bucket through a signed URL, which confirms object storage is wired. Then open the API's /graphql/ URL and run { products(first: 3, channel: "default-channel") { edges { node { name } } } } to confirm the API answers anonymously, exactly as your storefront will. Password resets and order confirmations land in the Mailpit inbox, behind MP_UI_AUTH.



About Hosting Saleor
Saleor is API-only by design: you model the catalogue and the commercial rules in Saleor, and your frontend talks GraphQL to it. Extensions are external apps that receive webhooks and call back in, so a misbehaving integration cannot take the core down with it.
- Native multi-channel — per-channel currency, pricing, stock, availability and tax
- Flexible order model — split payments, partial fulfilment, multi-warehouse stock, returns
- Promotion engine — catalogue and order discounts, vouchers, gift cards
- Payment orchestration — a transaction API any gateway implements
- Typed, introspectable API — subscription webhook payloads and a built-in playground
Self-hosting means four moving parts. The API answers GraphQL and serves thumbnails. The Celery worker does what must not block a request: webhooks, exports, invoices, mail, price recalculation. Beat fires recurring jobs — expiring checkouts, releasing reservations, refreshing search vectors. Postgres holds every record, Redis is both cache and broker, and the bucket holds media so the API and worker share it with no shared disk.
Why Deploy Saleor on Railway
Railway removes the orchestration work self-hosting Saleor normally requires.
- Postgres, Redis and object storage provisioned and wired by reference
- API, worker and scheduler as separate services with their own scaling
- Private networking keeps the database, cache and SMTP off the public internet
- The signing key every service shares is generated once, at first boot
- HTTPS domains, health checks and rolling deploys as standard
Common Use Cases
- A headless storefront in Next.js or Astro that queries Saleor directly and deploys separately
- A branded mobile shopping app sharing one catalogue and checkout with the web store
- Multi-market retail: several channels, each with its own currency and price list
- A B2B ordering portal built on Saleor's permissions and customer groups
Dependencies for Saleor
- Saleor API — built from the saleor-railway repository on
ghcr.io/saleor/saleor:3.23; runs uvicorn and owns migrations - Celery worker and beat — the same image in two more roles, around the Redis queue
- Saleor Dashboard —
ghcr.io/saleor/saleor-dashboard:3.23, pointed at the API on start - Postgres — catalogue, orders, customers, the schedule and the shared signing key
- Redis — cache on database 0, Celery broker on database 1
- Object storage bucket — product media and generated exports
- Mailpit —
axllent/mailpit:latest, private SMTP with a protected inbox
Environment Variables Reference
| Variable | Service | Purpose |
|---|---|---|
SALEOR_ADMIN_EMAIL / SALEOR_ADMIN_PASSWORD | API | First staff account, set before deploy |
SECRET_KEY | All three | Django signing key; identical on all three |
ALLOWED_CLIENT_HOSTS | All three | Hosts valid as password-reset and confirmation targets |
ALLOWED_GRAPHQL_ORIGINS | All three | Browser origins allowed to call the API |
AWS_QUERYSTRING_AUTH | All three | Signs media URLs; leave True for private buckets |
SEND_USAGE_TELEMETRY | All three | Set False to stop anonymous usage reporting |
API_URL | Dashboard | GraphQL endpoint the admin talks to |
CELERY_CONCURRENCY | Worker | Prefork pool size; raise for heavy webhook traffic |
Deployment Dependencies
- Source: saleor/saleor and saleor/saleor-dashboard, BSD-3-Clause
- Docs: docs.saleor.io · Runtime: Python 3.12, Django 5.2, Celery 5.5, PostgreSQL 15+, Redis 7+
Keep the API and dashboard on the same 3.x minor line — they release together, and the dashboard is written against a schema version.
Hardware Requirements for Self-Hosting Saleor
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU across API and worker | 4+ vCPU |
| RAM | 2 GB | 4–8 GB |
| Storage | Managed Postgres and bucket | Same |
| Runtime | Python 3.12, Postgres 15+, Redis 7+ | Same, plus a worker replica |
The Celery worker is the part that grows: raise CELERY_CONCURRENCY or add replicas as webhook and export volume rises. Beat must stay at one instance — two schedulers fire every job twice.
Self-Hosting Saleor with Docker
Saleor publishes official images, so a local stack is a short docker-compose.yml:
services:
api:
image: ghcr.io/saleor/saleor:3.23
ports: ["8000:8000"]
environment:
DATABASE_URL: postgres://saleor:saleor@db/saleor
CACHE_URL: redis://cache:6379/0
CELERY_BROKER_URL: redis://cache:6379/1
SECRET_KEY: change-me
ALLOWED_CLIENT_HOSTS: localhost
worker:
image: ghcr.io/saleor/saleor:3.23
command: celery --app=saleor.celeryconf:app worker -B
dashboard:
image: ghcr.io/saleor/saleor-dashboard:3.23
ports: ["9000:80"]
db: { image: postgres:15-alpine, environment: { POSTGRES_USER: saleor, POSTGRES_PASSWORD: saleor } }
cache: { image: valkey/valkey:8.1-alpine }
Then migrate and create the first staff user:
docker compose up -d
docker compose exec api python3 manage.py migrate
docker compose exec -e DJANGO_SUPERUSER_PASSWORD=changeme api \
python3 manage.py createsuperuser --noinput --email you@example.com
DEBUG=False also requires RSA_PRIVATE_KEY, a PEM key Saleor signs every token with. Here it is generated at first boot and shared by all three roles, so there is nothing to create.
Is Saleor Free to Self-Host?
Saleor Core and the dashboard are open source under BSD-3-Clause, with no feature gating, seat limits or transaction fees in the self-hosted build. Saleor Cloud is the paid managed offering; running it yourself costs only infrastructure. On Railway that is five application services plus Postgres, Redis and bucket usage — a small catalogue sits in the low tens of dollars a month.
FAQ
What is Saleor? An open-source commerce platform with a GraphQL-only API. It manages products, channels, stock, checkout, orders, promotions and payments, leaving the storefront to you.
What does this Railway template deploy? A Saleor API, a Celery worker, a beat scheduler, the dashboard, Postgres, Redis, an object storage bucket for media, and Mailpit as private SMTP with a protected inbox.
Why does the template include Redis and a worker? Saleor pushes webhook delivery, exports, invoicing, mail and price recalculation onto Celery. Redis is both the broker those tasks travel through and the cache the API reads — without them, webhooks and email never leave.
How do I connect my own storefront to self-hosted Saleor?
Point your client at the API's /graphql/ URL and add the storefront's origin to ALLOWED_GRAPHQL_ORIGINS. If it also handles password resets, add its host to ALLOWED_CLIENT_HOSTS.
How do I send real email instead of the built-in inbox?
Point EMAIL_URL on the API, worker and scheduler at your provider's SMTP URL — smtp://apikey:KEY@smtp.provider.com:587/?tls=True — and set DEFAULT_FROM_EMAIL to an address on a domain you control.
Template Content
saleor-api
gridalpha/saleor-railwayRedis
redis:8.2saleor-dashboard
ghcr.io/saleor/saleor-dashboard:3.23saleor-beat
gridalpha/saleor-railwaymailpit
axllent/mailpit:latestsaleor-worker
gridalpha/saleor-railwaysaleor-media
Bucket
