diff --git a/.dockerdev/.psqlrc b/.dockerdev/.psqlrc
new file mode 100644
index 00000000000..6a0fa9dc35c
--- /dev/null
+++ b/.dockerdev/.psqlrc
@@ -0,0 +1 @@
+\set HISTFILE ~/history/psql_history
diff --git a/.dockerdev/Dockerfile b/.dockerdev/Dockerfile
new file mode 100644
index 00000000000..b733cc1e905
--- /dev/null
+++ b/.dockerdev/Dockerfile
@@ -0,0 +1,58 @@
+ARG RUBY_VERSION
+FROM ruby:$RUBY_VERSION-slim-buster
+
+ARG PG_VERSION
+ARG MYSQL_VERSION
+ARG NODE_VERSION
+ARG BUNDLER_VERSION
+
+RUN apt-get update -qq \
+  && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
+    build-essential \
+    gnupg2 \
+    curl \
+    git \
+    imagemagick \
+    libvips \
+    libmariadb-dev \
+    sqlite3 \
+    libsqlite3-dev \
+    chromium \
+    chromium-driver \
+  && rm -rf /var/cache/apt/lists/*
+
+RUN curl -sSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
+  && echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main' $PG_VERSION > /etc/apt/sources.list.d/pgdg.list
+
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467b942d3a79bd29 \
+ && echo "deb http://repo.mysql.com/apt/debian/ buster mysql-"$MYSQL_VERSION > /etc/apt/sources.list.d/mysql.list
+
+RUN curl -sSL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -
+
+RUN apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade && \
+  DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
+    libpq-dev \
+    postgresql-client-$PG_VERSION \
+    mysql-client \
+    nodejs \
+  &&  rm -rf /var/lib/apt/lists/*
+
+ENV APP_USER=solidus_user \
+    LANG=C.UTF-8 \
+    BUNDLE_JOBS=4 \
+    BUNDLE_RETRY=3
+ENV GEM_HOME=/home/$APP_USER/gems
+ENV APP_HOME=/home/$APP_USER/app
+ENV PATH=$PATH:$GEM_HOME/bin
+
+RUN useradd -ms /bin/bash $APP_USER
+
+RUN gem update --system \
+  && gem install bundler:$BUNDLER_VERSION \
+  && chown -R $APP_USER:$(id -g $APP_USER) /home/$APP_USER/gems
+
+USER $APP_USER
+
+RUN mkdir -p /home/$APP_USER/history
+
+WORKDIR /home/$APP_USER/app
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000000..4609c6ee55f
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,63 @@
+version: '3.7'
+
+services:
+  mysql:
+    image: mysql:8.0
+    command: --default-authentication-plugin=mysql_native_password
+    environment:
+      MYSQL_ROOT_PASSWORD: password
+    volumes:
+      - mysql:/var/lib/mysql:cached
+
+  postgres:
+    image: postgres:13.2
+    environment:
+      POSTGRES_USER: root
+      POSTGRES_PASSWORD: password
+    volumes:
+      - postgres:/var/lib/postgresql/data:cached
+
+  app:
+    build:
+      context: .dockerdev
+      dockerfile: Dockerfile
+      args:
+        RUBY_VERSION: "2.7.2"
+        PG_VERSION: 13
+        NODE_VERSION: 14
+        MYSQL_VERSION: "8.0"
+        BUNDLER_VERSION: 2
+    image: solidus-2.11
+    command: bash -c "(bundle check || bundle) && tail -f /dev/null"
+    environment:
+      CAPYBARA_DRIVER: selenium_chrome_headless_docker_friendly
+      DB_USERNAME: root
+      DB_PASSWORD: password
+      RAILS_VERSION: ${RAILS_VERSION:-~> 6.1.0}
+      DB_ALL: "1"
+      DB_MYSQL_HOST: mysql
+      DB_POSTGRES_HOST: postgres
+      HISTFILE: "/home/solidus_user/history/bash_history"
+      MYSQL_HISTFILE: "/home/solidus_user/history/mysql_history"
+      RAILS_ENV: development
+      ACTIVE_STORAGE_VARIANT_PROCESSOR: "mini_magick"
+    ports:
+      - "${SANDBOX_PORT:-3000}:${SANDBOX_PORT:-3000}"
+    volumes:
+      - .:/home/solidus_user/app:delegated
+      - bundle:/home/solidus_user/gems:cached
+      - history:/home/solidus_user/history:cached
+      - .dockerdev/.psqlrc:/home/solidus_user/.psqlrc:cached
+    tty: true
+    stdin_open: true
+    tmpfs:
+      - /tmp
+    depends_on:
+      - mysql
+      - postgres
+
+volumes:
+  bundle:
+  history:
+  postgres:
+  mysql: