Docker images
DevLyft runs the container image you point a build at. This page covers how to reference it and what the image needs to do to run well.
Referencing your image#
A build takes the image in two fields, Image and Tag. Put the repository in Image and only the tag in Tag. The Builds page then shows them joined as image:tag.
| Registry | Image | Tag |
|---|---|---|
| Docker Hub official image | nginx | 1.27 |
| Docker Hub user or org | acme/api | 1.4.2 |
| GitHub Container Registry | ghcr.io/acme/api | 1.4.2 |
| Any other registry | registry.example.com/team/api | 2026-09-30.1 |
Tag defaults to latest, but pin a real version instead. A fixed tag makes each build a precise record of what's running, so rolling back means pointing a deploy at an older build.
docker build -t ghcr.io/acme/api:1.4.2 .
docker push ghcr.io/acme/api:1.4.2
# New build → Image: ghcr.io/acme/api Tag: 1.4.2
Private registries#
The New build form has no field for registry credentials, so the images you can use today are ones DevLyft can pull without authenticating.
Architecture#
Builds have no architecture field. Nodes report their architecture in the Arch column on the Nodes page, and machine type ids name one too (devlyft-amd-…, devlyft-arm-…). The image must be able to run on the nodes it lands on. A multi-architecture image (built with docker buildx build --platform linux/amd64,linux/arm64) covers both.
What the image should do#
- Listen on one known port. Set it as the build's Container port. Without it, a deploy of the build can't be publicly exposed.
- Listen on all interfaces (
0.0.0.0), not just127.0.0.1, so traffic from the edge reaches the container. - Read configuration from environment variables. Plain variables and secrets both reach the container as environment variables. See Environment variables and secrets.
- Log to stdout and stderr. Watch logs shows what the container writes there. JSON lines with a
levelandmessagefield get level colouring and expandable fields. - Stay within its memory request. A workload that runs out of memory may restart. Watch the Restarts metric.
- Run more than one copy safely. A deploy can run several replicas, so keep state in a database or external store rather than on the container's filesystem.
Minimal example#
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV PORT=8080
EXPOSE 8080
CMD ["node", "server.js"]
Create the build with Container port 8080. EXPOSE in the Dockerfile is documentation only. DevLyft uses the port set on the build.