RWX Container Image Build Syntax
This is the reference documentation for building images. See the guide on building container images for high-level concepts.
Building images on RWX is substantially faster and more ergonomic than building images with docker build
due to techniques detailed in the original proposal.
The syntax for building images on RWX is mostly the same as normal RWX run definitions.
Some configuration options are exposed via writing to the $RWX_IMAGE configuration directory from within a task.
FROM
Dockerfile:
FROM ubuntu:24.04
RWX:
base:
image: ubuntu:24.04
config: none
You'll almost always want to use config: none when building images.
This will start building your image pristinely from the defined image without any additional configuration applied.
RUN
Dockerfile:
RUN \
apt-get -y update && \
apt-get -y upgrade && \
apt-get -y install curl jq && \
apt-get -y clean
On RWX, run scripts are defined as multi-line shell scripts, so you do not need the && chaining.
tasks:
- key: system
run: |
apt-get -y update
apt-get -y upgrade
apt-get -y install curl jq
apt-get -y clean
COPY and ADD
Rather than using COPY and ADD, you'll mostly use the git/clone package and artifacts.
You'll also use filters to avoid needing as many COPY statements as you typically find in docker files.
For example, in a Dockerfile, you usually have a COPY . . towards the end to copy the entire build context into the container.
On RWX however, you can start your run definition with cloning your full git repository.
- key: code
use: system
call: git/clone 1.8.0
with:
repository: https://github.com/rwx-cloud/rwx-image-example.git
ref: ${{ init.commit-sha }}
After defining a task such as code that contains your full git repository, you can then filter additional commands. So while in a Dockerfile, before copying your full build context into your container, you might do this:
COPY package.json package-lock.json ./
RUN npm ci
On RWX you can do this:
- key: npm-install
use: code
run: npm ci
filter:
- package.json
- package-lock.json
Artifacts
You can use artifacts to mimic copying files between layers in multi-stage builds.
Multi-stage build copy example
Here is a full example comparing the docker approach to the RWX approach.
This example shows building a Node.js application without copying all of node_modules into the final container.
# ---- Stage 1: Build the app ----
FROM node:24-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ---- Stage 2: Production image ----
FROM node:24-slim AS runtime
WORKDIR /app
# Copy only the build output from the builder stage
COPY --from=builder /app/dist ./dist
# Set environment and command
ENV NODE_ENV=production
CMD ["node", "dist/index.js"]
On RWX:
base:
image: node:24-slim
config: none
tasks:
- key: code
call: git/clone 1.8.0
with:
repository: https://github.com/your-org/your-repo.git
ref: main
- key: npm-install
use: code
run: npm ci
filter:
- package.json
- package-lock.json
- key: build
use: npm-install
run: npm run build
outputs:
artifacts:
- key: dist
path: dist
- key: dist
run: cp -a ${{ tasks.build.artifacts.dist }}/. ./dist
- key: image
use: dist
run: echo "node dist/index.js" | tee $RWX_IMAGE/command
env:
NODE_ENV: production
Note that the dist task in the RWX definition does not have a use dependency, making it the same as the multi-stage build approach.
ARG
On RWX, you use init parameters to configure runtime values.
Dockerfile:
# Define a required build argument (no default)
ARG APP_VERSION
# Use it in a command
RUN echo "Building version: ${APP_VERSION}" > version.txt
RWX:
tasks:
- key: version-file
run: echo "Building version: ${APP_VERSION}" > version.txt
env:
APP_VERSION: ${{ init.app-version }}
CMD
Dockerfile:
CMD node server.js
On RWX, write the command to $RWX_IMAGE/command
tasks:
- key: image
run: echo "node server.js" > $RWX_IMAGE/command
ENTRYPOINT
Dockerfile:
ENTRYPOINT /usr/local/bin/myapp
CMD "--help"
On RWX, write the entrypoint to $RWX_IMAGE/entrypoint
tasks:
- key: image
run: |
echo "/usr/local/bin/myapp" > $RWX_IMAGE/command
echo "--help" > $RWX_IMAGE/help
ENV
Dockerfile:
ENV PORT=3000
RWX:
tasks:
- key: image
run: ...
env:
PORT: 3000
ENV
Dockerfile:
SHELL ["/bin/bash", "-c"]
RWX:
tasks:
- key: image
run: echo "/bin/bash -c" > $RWX_IMAGE/shell
Note that not all RWX packages have been updated yet to support shells other than bash.
USER
Dockerfile:
USER myuser
RWX:
tasks:
- key: image
run: echo "myuser" > $RWX_IMAGE/user
WORKDIR
On RWX, the workdir it currently always /var/mint-workspace
EXPOSE
Docker supports defining exposed ports, such as
EXPOSE 3000
However, EXPOSE is only for documentation purposes.
It does not affect which ports can actually be exposed from the image.
RWX does not currently support EXPOSE.
Not Supported
The following Dockerfile options are not currently supported on RWX.
HEALTHCHECK Check a container's health on startup.
LABEL Add metadata to an image.
MAINTAINER Specify the author of an image.
ONBUILD Specify instructions for when the image is used in a build.
STOPSIGNAL Specify the system call signal for exiting a container.
VOLUME Create volume mounts.