diff --git a/cumulus/README.md b/cumulus/README.md
index a04bf18ca07c93ec132325abe5ab4aad67145f75..96a38915fd4d390e19fcb1e69b2cff805d564b1f 100644
--- a/cumulus/README.md
+++ b/cumulus/README.md
@@ -41,13 +41,13 @@ Statemint is a common good parachain providing an asset store for the Polkadot e
 To run a Statemine or Westmint node (Statemint is not deployed, yet) you will need to compile the
 `polkadot-collator` binary:
 
-```sh
+```bash
 cargo build --release --locked -p polkadot-collator
 ```
 
 Once the executable is built, launch the parachain node via:
 
-```sh
+```bash
 CHAIN=westmint # or statemine
 ./target/release/polkadot-collator --chain $CHAIN
 ```
@@ -73,7 +73,7 @@ eventually be included by the relay chain for a parachain.
 
 To run a Rococo collator you will need to compile the following binary:
 
-```
+```bash
 cargo build --release --locked -p polkadot-collator
 ```
 
@@ -93,7 +93,7 @@ If you want to reproduce other steps of CI process you can use the following
 Once the executable is built, launch collators for each parachain (repeat once each for chain
 `tick`, `trick`, `track`):
 
-```
+```bash
 ./target/release/polkadot-collator --chain $CHAIN --validator
 ```
 
@@ -102,9 +102,9 @@ Once the executable is built, launch collators for each parachain (repeat once e
 The parachains of Rococo all use the same runtime code. The only difference between them is the
 parachain ID used for registration with the relay chain:
 
--   Tick: 100
--   Trick: 110
--   Track: 120
+- Tick: 100
+- Trick: 110
+- Track: 120
 
 The network uses horizontal message passing (HRMP) to enable communication between parachains and
 the relay chain and, in turn, between parachains. This means that every message is sent to the relay
@@ -154,19 +154,27 @@ cargo build --release
 # Parachain Full Node 1
 ./target/release/polkadot-collator --tmp --parachain-id <parachain_id_u32_type_range> --port 40337 --ws-port 9948 -- --execution wasm --chain ../polkadot/rococo-local-cfde.json --port 30337
 ```
+
 ### Register the parachain
+
 ![image](https://user-images.githubusercontent.com/2915325/99548884-1be13580-2987-11eb-9a8b-20be658d34f9.png)
 
-## Build the docker image
+## Containerize
 
-After building `polkadot-collator` with cargo or with Parity docker image as documented in [this chapter](#build--launch-rococo-collators), the following will allow producting a new docker image where the compiled binary is injected:
+After building `polkadot-collator` with cargo or with Parity CI image as documented in [this chapter](#build--launch-rococo-collators),
+the following will allow producing a new docker image where the compiled binary is injected:
 
-```
+```bash
 ./docker/scripts/build-injected-image.sh
 ```
 
-You may then start a new contaier:
+Alternatively, you can build an image with a builder pattern:
 
-```
+```bash
+docker build --tag $OWNER/$IMAGE_NAME --file ./docker/polkadot-collator_builder.Containerfile .
+
+You may then run your new container:
+
+```bash
 docker run --rm -it $OWNER/$IMAGE_NAME --collator --tmp --parachain-id 1000 --execution wasm --chain /specs/westmint.json
 ```
diff --git a/cumulus/docker/polkadot-collator_builder.Containerfile b/cumulus/docker/polkadot-collator_builder.Containerfile
new file mode 100644
index 0000000000000000000000000000000000000000..4eb7ec04a1a7ae89b3800bd7a3e4ce3d0631e03e
--- /dev/null
+++ b/cumulus/docker/polkadot-collator_builder.Containerfile
@@ -0,0 +1,36 @@
+# This file is sourced from https://github.com/paritytech/polkadot/blob/master/scripts/dockerfiles/polkadot/polkadot_builder.Dockerfile
+# This is the build stage for Polkadot-collator. Here we create the binary in a temporary image.
+FROM docker.io/paritytech/ci-linux:production as builder
+
+WORKDIR /cumulus
+COPY . /cumulus
+
+RUN cargo build --release --locked -p polkadot-collator
+
+# This is the 2nd stage: a very small image where we copy the Polkadot binary."
+FROM docker.io/library/ubuntu:20.04
+
+LABEL io.parity.image.type="builder" \
+    io.parity.image.authors="devops-team@parity.io" \
+    io.parity.image.vendor="Parity Technologies" \
+    io.parity.image.description="Multistage Docker image for Polkadot-collator" \
+    io.parity.image.source="https://github.com/paritytech/polkadot/blob/${VCS_REF}/docker/test-parachain-collator.dockerfile" \
+    io.parity.image.documentation="https://github.com/paritytech/cumulus"
+
+COPY --from=builder /cumulus/target/release/polkadot-collator /usr/local/bin
+
+RUN useradd -m -u 1000 -U -s /bin/sh -d /cumulus polkadot-collator && \
+    mkdir -p /data /cumulus/.local/share && \
+    chown -R polkadot-collator:polkadot-collator /data && \
+    ln -s /data /cumulus/.local/share/polkadot-collator && \
+# unclutter and minimize the attack surface
+    rm -rf /usr/bin /usr/sbin && \
+# check if executable works in this container
+    /usr/local/bin/polkadot-collator --version
+
+USER polkadot-collator
+
+EXPOSE 30333 9933 9944 9615
+VOLUME ["/data"]
+
+ENTRYPOINT ["/usr/local/bin/polkadot-collator"]
diff --git a/cumulus/docker/test-parachain-collator.dockerfile b/cumulus/docker/test-parachain-collator.dockerfile
index 35fe09c68a04f1c0a5bfad6da429d61a3617223b..72e4e0d67ea1c68d8e282e39ba358d6c599458f3 100644
--- a/cumulus/docker/test-parachain-collator.dockerfile
+++ b/cumulus/docker/test-parachain-collator.dockerfile
@@ -1,23 +1,8 @@
-FROM rust:buster as builder
+# This file is sourced from https://github.com/paritytech/polkadot/blob/master/scripts/dockerfiles/polkadot/polkadot_builder.Dockerfile
+FROM docker.io/paritytech/ci-linux:production as builder
 
-RUN apt-get update && apt-get install time clang libclang-dev llvm -y
-RUN rustup toolchain install nightly
-RUN rustup target add wasm32-unknown-unknown --toolchain nightly
-RUN command -v wasm-gc || cargo +nightly install --git https://github.com/alexcrichton/wasm-gc --force
-
-WORKDIR /paritytech/cumulus
-
-# Ideally, we could just do something like `COPY . .`, but that doesn't work:
-# it busts the cache every time non-source files like inject_bootnodes.sh change,
-# as well as when non-`.dockerignore`'d transient files (*.log and friends)
-# show up. There is no way to exclude particular files, or write a negative
-# rule, using Docker's COPY syntax, which derives from go's filepath.Match rules.
-#
-# We can't combine these into a single big COPY operation like
-# `COPY collator consensus network runtime test Cargo.* .`, because in that case
-# docker will copy the _contents_ of each directory into the image workdir,
-# not the actual directory. We're stuck just enumerating them.
-COPY . .
+WORKDIR /cumulus
+COPY . /cumulus
 
 RUN cargo build --release --locked -p polkadot-collator