Self-hosted service
saleor/saleor-platform avatar
saleor/saleor-platform

saleor-platform: the local docker-compose stack for Saleor Core, Dashboard and Postgres

All Saleor services started from a single repository with docker-compose.

772 stars959 forksShellBSD-3-Clause

At a glance

What is it?
saleor-platform bundles the Saleor GraphQL API, the Dashboard, Celery worker, Postgres, Valkey, Jaeger and Mailpit into one docker-compose file for local development. It is a developer convenience, and the README states plainly that it is not a production deployment.
Who is it for?
Adopt saleor-platform when you are working on Saleor itself, need the API, the Dashboard and a mail catcher running locally within a few minutes, and do not mind pinned 3.23 images. Do not adopt it as a hosting plan, because the README states the repository is for local development only and is not meant to be deployed in a production environment.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 143 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One compose file replaces assembling a commerce stack by hand

saleor-platform exists for the developer who wants a working Saleor checkout running locally, not for the operator who wants to host one. The repository tree is small and revealing: docker-compose.yml, common.env, backend.env, replica_user.sql, setup-e2e-db.sh, a LICENSE, a README, a .github directory and a .gitignore. There is no application source here at all. The primary language of the repository is Shell, and the only script of that kind is the end to end database setup file. Everything else is a container image.

The README describes the project as the easiest way to start local development with all the major Saleor services, and it lists the Core GraphQL API, the Dashboard, Mailpit as a test email interface, Jaeger for APM, and the necessary databases and cache. The same README closes the door on any other use: the repository is for local development only and is not meant to be deployed in any production environment. So the audience is narrow. Backend and frontend engineers working on Saleor itself, and engineers evaluating the API and the Dashboard locally before deciding where to run them for real.

The compose topology splits the API from the Celery worker and shares one media volume

docker-compose.yml is the entire design, and reading it tells you more than any summary. The api service pulls ghcr.io/saleor/saleor:3.23, publishes port 8000, depends on db, cache and jaeger, and mounts the named volume saleor-media at /app/media.

yaml
  api:
    image: ghcr.io/saleor/saleor:3.23
    ports:
      - 8000:8000

The worker runs the same image with a different command, which is the standard split for a Django application with background jobs.

yaml
  worker:
    image: ghcr.io/saleor/saleor:3.23
    command: celery -A saleor --app=saleor.celeryconf:app worker --loglevel=info -B

The worker mounts the same saleor-media volume, so media written by a background job is visible to the API through the shared path. The db service is library/postgres:15-alpine with POSTGRES_USER=saleor and POSTGRES_PASSWORD=saleor, and it mounts the local replica_user.sql file into the postgres init directory as read only, which is how the replica user is created on first boot. The cache is valkey/valkey:8.1-alpine, and the Dashboard is ghcr.io/saleor/saleor-dashboard:3.23 with port 80 mapped to 9000 on the host. The api, db, cache, worker and jaeger services sit on a network called saleor-backend-tier, while the dashboard joins from outside it as a separate frontend.

Cloning the repository and bringing the stack up in four commands

Docker is the only stated requirement, and the sequence is short enough to read in full. Start by cloning the repository.

shell
git clone https://github.com/saleor/saleor-platform.git

Then move into the cloned directory.

shell
cd saleor-platform

Before anything else starts, the Django schema has to exist. The api service is used in one-off mode for that, and the README calls the step apply Django migrations.

shell
docker compose run --rm api python3 manage.py migrate

The next step seeds example data and creates the admin account.

shell
docker compose run --rm api python3 manage.py populatedb --createsuperuser

Passing --createsuperuser creates an admin account for [email protected] with the password set to admin. That credential is fine for a laptop and is exactly the kind of default you must not carry anywhere else. Finally the stack starts.

shell
docker compose up

You should see the API, the Dashboard, the worker, Postgres, Valkey, Jaeger and Mailpit come up together. On macOS and Windows, two preparation steps come first: add the cloned saleor-platform directory to the Docker shared directories under Preferences, Resources, File sharing, and dedicate at least 5 GB of memory to the daemon under Preferences, Resources, Advanced.

Four localhost URLs and two that are there for the plumbing

The service map is short and worth memorising, because every troubleshooting session starts with knowing which port belongs to what.

- Saleor Core, the API, at http://localhost:8000 - Saleor Dashboard at http://localhost:9000 - Jaeger UI for APM at http://localhost:16686 - Mailpit, the test email interface, at http://localhost:8025

Mailpit is the one that saves the most time for backend work. Because it catches outbound mail locally, you can exercise password reset and checkout notification flows without a real sending domain, and you can read the message in a web interface instead of a mailbox.

The compose file also publishes Postgres on 5432 and Valkey on 6379, and Jaeger's own ports 4317 and 4318, so trace data and the databases are reachable from the host as well as from the backend network. That is convenient for a local machine and slightly untidy otherwise, since a database and a cache are bound to the host's interfaces with a password that is simply saleor. Nothing here is hardened, and nothing here is meant to be.

Volumes, shared folders and the three commands that can delete your data

The compose file uses shared folders to enable live code reloading, which is the whole point of running this locally, and it is also the source of the most common friction on macOS and Windows when the shared directory is not registered with Docker.

The documented recovery path for running out of space or hitting build errors after an update is to stop the stack, remove the existing containers, and build again.

shell
docker compose stop
shell
docker compose rm
shell
docker compose build

The warning attached to docker compose rm matters: proceeding removes the database container too, so the README advises removing only the services that cause the problem if you have data you care about. The deeper cleanup is pruning the Docker cache, which takes out all stopped containers, all networks not used by at least one container, all dangling images and all dangling build cache.

shell
docker system prune

And when you need the database itself back to a clean state, because its state is persisted in the mounted volume, the dedicated command removes all data already stored.

shell
docker compose down --volumes db

The repository also carries replica_user.sql, mounted into the postgres entrypoint directory, and setup-e2e-db.sh for end to end database setup, which is how the e2e path gets a usable data set.

Pinned 3.23 images, a BSD licence and no release history

Versioning is pinned rather than tracked. Every Saleor image in the compose file sits at 3.23, the dashboard included, while Postgres is pinned to 15-alpine and the cache to valkey 8.1-alpine. Pinning is the right default for a development bundle, because two developers get identical behaviour, but it also means an upgrade is a deliberate edit of image tags rather than a pull.

The licence is BSD-3-Clause. The README frames it plainly: everything is open and free to use as long as you comply with the licence, and there are no hidden charges. The same README notes that some situations call for extra code and that Saleor will cover exotic use cases or build a custom e commerce appliance, which is a commercial arrangement, not an open source guarantee. Nothing here is legal advice, but the practical read is that the code is permissive and the paid part is support, not the licence.

On maintenance, the repository is not archived and the last push was on 2026-06-02. There are no GitHub releases, so there is no changelog to check before you bump the tags. For a repository whose entire job is to keep two image versions in step, that is the gap to watch.

Where the compose bundle stops and running Saleor yourself begins

Two alternatives exist and they differ in kind, not in polish. The first is hosted: the README points people who just want to try Saleor to a live demo, and offers a signup link for the hosted API. That is a different product with a different responsibility model, and it removes the local environment from the equation entirely rather than making the local environment better.

The second alternative is to assemble the same services yourself: the Core API image, the Dashboard image, your own Postgres, your own cache, and your own mail and tracing setup. The difference in approach is control, and the cost of that control is exactly what the compose file hides. Running the services by hand means choosing versions yourself, wiring the environment variables that common.env and backend.env hold, keeping the API and the worker on matching code, and recreating the replica user and the media volume yourself. saleor-platform buys all of that for the price of accepting its pinned tags and its local development assumptions, such as shared folders for live reload and a database password of saleor.

For a feature branch, the bundle is faster. For anything that must survive a machine reboot, be reached by other people, or carry real customer data, it is the wrong shape, and the README says so before you find out the hard way.

Editorial conclusion

Adopt saleor-platform when you are working on Saleor itself, need the API, the Dashboard and a mail catcher running locally within a few minutes, and do not mind pinned 3.23 images. Do not adopt it as a hosting plan, because the README states the repository is for local development only and is not meant to be deployed in a production environment. Before relying on it, check that the 3.23 image tags in docker-compose.yml match the Saleor version your work targets, and give the Docker daemon at least 5 GB of memory as the README requires, since the shared folder mounting and the database both fail in confusing ways when the daemon is short on space.

Frequently asked questions

How do I start Saleor Platform locally?

Clone the repository, run docker compose run --rm api python3 manage.py migrate, then docker compose run --rm api python3 manage.py populatedb --createsuperuser, and finally docker compose up. Docker is the only stated requirement, and on macOS and Windows the cloned directory must be added to the Docker shared directories with at least 5 GB of memory dedicated to the daemon.

Is Saleor Platform suitable for production deployment?

No. The README states that the repository is for local development only and is not meant to be deployed in any production environment, and it points people who only want to try Saleor to the live demo.

Which ports does the Saleor Platform stack expose?

Saleor Core is on http://localhost:8000, the Dashboard on http://localhost:9000, the Jaeger UI on http://localhost:16686 and Mailpit on http://localhost:8025. The compose file also publishes Postgres on 5432, the Valkey cache on 6379, and Jaeger on 4317 and 4318.

How do I reset the Saleor Platform database after a migration problem?

Run docker compose down --volumes db, which removes all data already stored in the database because the state is persisted in the mounted volume. For space and build problems the README suggests docker compose stop, docker compose rm and docker compose build, and it asks for an issue ticket if migrations fail during a version update.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. README
  4. saleor/saleor-platform on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/saleor-saleor-platform.svg)](https://hysenlabs.com/projects/saleor-saleor-platform)

Was this useful?