---
title: "Deploy Saleor"
description: "Open-source commerce backend for building your own online store"
category: "Other"
url: https://railway.com/deploy/saleor-store
---

# Deploy Saleor

Open-source commerce backend for building your own online store

**[Deploy Saleor on Railway](https://railway.com/template/saleor-store)**

- **Creator:** A3A
- **Category:** Other
- **Total deploys:** 1

## Template content

### saleor-api https://raw.githubusercontent.com/saleor/saleor-dashboard/3.23.28/assets/images/logo-dark-small.svg

- **Source:** https://github.com/gridalpha/saleor-railway
- **Public domain:** Yes

### Redis https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/redis.svg

- **Image:** redis:8.2
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --save 60 1 --dir $RAILWAY_VOLUME_MOUNT_PATH"`

### saleor-dashboard https://raw.githubusercontent.com/saleor/saleor-dashboard/3.23.28/assets/images/logo-dark-small.svg

- **Image:** ghcr.io/saleor/saleor-dashboard:3.23
- **Health check:** /
- **Public domain:** Yes

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### saleor-beat https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/celery.png

- **Source:** https://github.com/gridalpha/saleor-railway

### mailpit https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/mailpit.svg

- **Image:** axllent/mailpit:latest
- **Health check:** /livez
- **Public domain:** Yes

### saleor-worker https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/celery.png

- **Source:** https://github.com/gridalpha/saleor-railway

## Buckets

- **saleor-media**

## Documentation

![Saleor logo](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQDLQe8zStWkF_iSVtgIASvfd4j9971_Nx79bJYOfs0pg&s)

# 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.

![Diagram of the Saleor API, worker, beat, dashboard and datastores on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1787696537/saleor-architecture.png)

## 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`.

![Saleor dashboard listing three live coffee products with thumbnails](https://res.cloudinary.com/rroe4rtk/image/upload/v1787696540/saleor-product-catalog.png)

![Saleor product page showing media, category and channel availability](https://res.cloudinary.com/rroe4rtk/image/upload/v1787696546/saleor-product-detail.png)

![Saleor GraphQL playground returning catalogue prices for the default channel](https://res.cloudinary.com/rroe4rtk/image/upload/v1787696548/saleor-graphql-playground.png)

## 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](https://github.com/gridalpha/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](https://github.com/saleor/saleor) and [saleor/saleor-dashboard](https://github.com/saleor/saleor-dashboard), BSD-3-Clause
- Docs: [docs.saleor.io](https://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.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/saleor-store
