Dockerfiles and container images
Deploy a custom build environment or an image you already publish to a registry.
Use Docker when you need precise control over system packages, language versions, runtime files, or a nonstandard application layout. You can build a Dockerfile from GitHub or deploy an existing container image.
Build a Dockerfile
- Commit a Dockerfile and
.dockerignoreto the repository. - Choose Dockerfile as the service's build method.
- Set the application root, Dockerfile path, and Docker context.
- Configure the service's listening port and runtime variables.
- Deploy and inspect the build log.
Both Dockerfile path and Docker context are relative to the selected application root. They cannot escape it with ... If a monorepo build needs shared files elsewhere in the repository, use the repository root as the application root and point to the nested Dockerfile.
Example Node.js image
This example assumes an npm lockfile, production dependencies, and a server.js entry point. Applications that compile TypeScript or frontend assets should add a separate build stage.
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
ENV NODE_ENV=production
USER node
EXPOSE 3000
CMD ["node", "server.js"]Set Openstead's service port to 3000, and have server.js listen on 0.0.0.0 using process.env.PORT. EXPOSE documents a port; it does not make the server bind to it.
Example .dockerignore:
.git
node_modules
.env
.env.*
npm-debug.logDo not ignore required checked-in configuration or generated assets your Dockerfile expects to copy.
Build-time secrets
Openstead passes configured environment variables to Docker builds as BuildKit secrets, not as automatic Docker ARG values. Reference a secret explicitly in the Dockerfile:
# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=PRIVATE_TOKEN,required=true \
PRIVATE_TOKEN="$(cat /run/secrets/PRIVATE_TOKEN)" ./scripts/install-private-dependencies.shAdd PRIVATE_TOKEN to the service's environment. The script must avoid printing the token or saving it into the final filesystem. A secret mount protects how a value is supplied; your build can still leak it if you copy it into output.
Deploy an existing image
Choose Container image as the source and provide a registry reference such as ghcr.io/your-team/your-app:release. For private images, select an authorized registry connection. Private registry access requires the applicable paid workspace features.
Openstead resolves the image to an immutable digest for the release. Publishing a new image under the same tag does not replace a running release automatically; deploy the image again. Use digest references when you want to identify an exact artifact yourself.
Keep the service start command empty to retain the image's entry point and command unless an override is required. Ensure the image can run as a foreground service and includes any shell needed for command-based operations.
Persistent data and migrations
Image files are replaced by subsequent releases. Store application data in managed databases, a persistent disk, or object storage. Run one-time migrations in a paid pre-deploy command, not in a Dockerfile build step that needs the private runtime database.