4 Feb 2020 by Chad Cassady

Running Saleor with Docker Compose

This article shows how to use Docker Compose to run the full Saleor suite of services: the headless GraphQL API, the dashboard used by staff to manage the store, and the storefront where users can browse and purchase products.

Saleor 2.9's PWA architecture introduces two new repositories. The Saleor repository still contains a Django application, but the Django views are deprecated in favor of a GraphQL API which provides e-commerce data access to the separate dashboard and storefront applications.

Saleor includes a Docker Compose configuration with good starting-point defaults to run the application and all related services locally. But as of this writing, this configuration does not provide a default way to run the new dashboard and storefront applications out of the box. As Mirumee continues work on Saleor in the coming weeks and months, these instructions will become obsolete in favor of a documented toolchain included in the Saleor repositories.

This setup is not recommended for production, but is a great way to start working on the platform and contributing to the development of Saleor.

Using Docker Compose to Run Saleor

Preparing a Development Environment

Developing Saleor requires Node, Python 3.8+, Docker, Docker Compose, and a Python virtualenv. Follow the installation instructions for Windows, Mac, or Linux with the following exceptions: there is no need to install PostgreSQL or GTK+. They are both provided by Docker and Docker Compose configuration files located in the Saleor Django application repository.

PostgreSQL is provided by a Docker container described by the docker-compose.yml file here, and GTK+ is provided in the container built from the Dockerfile provided with Saleor here.

With Docker Compose, many aspects of the development environment remain the same. With a virtualenv in place and the Python requirements for an application installed in it, developers can use Django's manage.py to run a development HTTP server, along with a few other routine development tasks like database migrations. NPM and Webpack provide similar developer utilities for the JavaScript-based headless PWA client applications.

Docker Compose only changes the runtime aspect of this traditional process. A developer would install everything they need for a development environment, setting up their favorite tools, scripts, IDE or editor, and so on. But to run the application locally, Docker Compose encodes the build and runtime process in version control, while saving a little effort manually administering databases. This helps ensure the development runtime matches the production runtime with less effort.

Running Saleor

First, add the Saleor PWA dashboard and storefront to the Docker Compose manifest. As a starting point, use git repositories as the build context, instead of a local directory. The Dockerfile in each of these repositories contains everything necessary to run the application directly with Docker Compose.

docker-compose.yml:

diff --git a/docker-compose.yml b/docker-compose.yml
index 53f6bab60..e57b951dd 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -48,6 +48,22 @@ services:
    depends_on:
      - redis

+  storefront:
+    restart: unless-stopped
+    build:
+      context: https://github.com/mirumee/saleor-storefront.git
+      dockerfile: ./Dockerfile
+    depends_on:
+      - web
+
+  dashboard:
+    restart: unless-stopped
+    build:
+      context: https://github.com/mirumee/saleor-dashboard.git
+      dockerfile: ./Dockerfile
+    depends_on:
+      - web
+
volumes:
  saleor-db:
    driver: local

To serve the dashboard applications, bind a predetermined port on the host to port 80 on the container – 3000 for the storefront, and 9000 for the dashboard.

docker-compose.override.yml:

diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index f0df7f4c5..419eaacf8 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -15,6 +15,14 @@ services:
      # shared volume between celery and web for media
      - saleor-media:/app/media

+  dashboard:
+    ports:
+      - 9000:80
+
+  storefront:
+    ports:
+      - 3000:80
+
  db:
    ports:
      - 5432:5432

For local development, follow these instructions and modify docker-compose.override.yml to mount local assets.

diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 419eaacf8..66dfb4c0c 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -9,9 +9,8 @@ services:
      - ./saleor/:/app/saleor:Z
      - ./templates/:/app/templates:Z
      - ./tests/:/app/tests
-      # prevents overshadowing of build-time assets
-      - /app/saleor/static/assets
-      - /app/templates/templated_email/compiled
+      # mounts local assets instead of build-time assets for local development
+      - ./webpack-bundle.json:/app/webpack-bundle.json
      # shared volume between celery and web for media
      - saleor-media:/app/media

@@ -35,8 +34,6 @@ services:
    volumes:
      - ./saleor/:/app/saleor:Z
      - ./templates/:/app/templates:Z
-      # prevents overshadowing of build-time assets
-      - /app/templates/templated_email/compiled
      # shared volume between celery and web for media
      - saleor-media:/app/media

Now, run two commands for a local running instance of the Saleor e-commerce application suite:

$ docker-compose build
$ docker-compose up

Navigate to http://localhost:3000 to see the storefront, and http://localhost:9000 to see the dashboard.

Developing All Three Applications in Concert

Following these instructions yields a local running Saleor installation using only the repository that provides the headless e-commerce API and includes the Docker Compose configuration. Within that repository, additions to Docker Compose files build and run the other two applications straight from a git repository URL.

This is great for running the applications together locally and showing the power of Docker Compose, but it's not quite everything needed to develop and publish extensions to Saleor. To customize Saleor, developers will want to make modifications to the dashboard and storefront to utilize new features. This entails a local copy of each repository, and a way to track development efforts across all three repositories. This information should be tracked in version control. Upon checking out a revision or branch, the changes appropriate to that revision from all three applications should be reflected with little or no effort beyond running docker-compose build and docker-compose up, and maybe a git command.

The simplest way to do this is to specify a specific revision, branch, or tag of a fork to the build context of the storefront and dashboard services defined in the Docker Compose files. This method still uses a Git repository URL – use the syntax described in the table here.

For smaller teams, or those doing tightly-integrated feature development on the Django headless API and the PWA client apps, git submodules are a tool that meets these requirements. For this approach, initialize the dashboard and storefront repositories as submodules to the Saleor Django backend repository. Add the submodule directories to the .dockerignore file. Otherwise, building the Celery worker and Django container images will start taking a very long time!

Further information on this workflow may be explored in a future post, along with other steps needed to begin development of Saleor with Docker Compose. Among things to consider: Many will opt to use the Webpack development server instead of nginx to serve the applications, and to configure shared volumes to have the hot reloading work. In the meantime, there is more information on using git submodules here.

Questions From Gitter

  • "How do I run X in the Docker container during development?"

If it's a development command like manage.py or npm, you don't. Docker is for running your application code in a container, the same way it runs your application's software dependencies like databases. Docker Compose helps you do this locally in your development environment. Think of Docker as a runtime environment, not a development environment. Docker Compose is part of your development environment responsible for running your software and its dependencies in a reproducible way.

  • "When do I use the docker build -t mystorefront command shown in the Saleor documentation?"

This command is relevant to building a Docker container for production. You might run it manually before docker run, or put it in a YAML file for a CI system. When using Docker Compose, you don't need to run this command manually.

Further Reading

If you're developing multiple Python applications, take a look at virtualenvwrapper. It's great! If you use WSL on Windows, you can use it too! The following resources will also be useful:

— Share