Deploying
Dockerfiles, prebuilt images, Compose and monorepos
Build with your own Dockerfile, deploy a prebuilt image from a public or private registry, run a Docker Compose stack, and deploy apps that live in a subfolder.
Dockerfile builds
Used when Build Type is Dockerfile, or Nixpacks with a root Dockerfile.
- The file must be named
Dockerfileat the repository root; other paths aren't supported. The build context is the root. - No build args are passed, and project environment variables aren't available during
docker build; they're injected when the container starts. EXPOSEdoesn't control routing. Listen on0.0.0.0:$PORT, or setPORTto your image's port.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "server.js"]Deploy a prebuilt image
- General → Deploy from Image: e.g.
ghcr.io/acme/api:1.4.0ornginx:1.27. Save, then Deploy. No clone, no build. - Set
PORTto the image's port (e.g.PORT=80for nginx). - Clear the field and Save to build from source again.
Private registries: add Registry host (ghcr.io, docker.io, your ECR or GitLab host), Username and Password or token in Settings → Registries (admins). MarvX uses the credential whose host the image reference starts with; for private Docker Hub images write docker.io/acme/api:1.0.
Prebuilt images are the answer when the build needs secrets (private packages, submodules) or more than 15 minutes: build in CI, push, deploy the image.
Docker Compose
- General → Docker Compose: paste a
docker-compose.yml, Save, Deploy. While saved, it overrides build and image settings; clear it to go back. - The repository isn't cloned, so give every service an
image:(no localbuild:). - Project variables are written to a
.envbeside the file: use${VAR}orenv_file: .env. - Reload, Stop, Start and Logs cover the whole stack; Open Terminal and cron schedules use the first service.
Compose stacks aren't attached to MarvX domains or the *.apps.marvx.io address. They're reachable only via ports published in the file, and on MarvX-hosted servers non-web ports may not be open to the internet. For a public site or API, deploy a regular project; contact support if you need a stack exposed.
Monorepos and subfolders
There's no root-directory setting. Options:
Root Dockerfile (most predictable):
FROM node:20-alpine
WORKDIR /app
COPY apps/api/package*.json ./
RUN npm ci
COPY apps/api/ .
RUN npm run build
CMD ["npm", "start"]Root nixpacks.toml: declare the runtime, since detection only looks at root files.
[phases.setup]
nixPkgs = ["nodejs_20"]
[phases.install]
cmds = ["cd apps/web && npm ci"]
[phases.build]
cmds = ["cd apps/web && npm run build"]
[start]
cmd = "cd apps/web && npm start"Prebuilt image per app from CI. Create one project per app either way.