Containers¶
The containers section of appmecca.yaml defines what Docker images to build from your repository. Each entry produces one Docker image that gets pushed to the AppMecca private image registry.
Basic Example¶
This builds one image called myapp using the Dockerfile in the repository root.
All Fields¶
| Field | Required | Default | Description |
|---|---|---|---|
name |
Yes | — | Name for this container. Names the image in the registry. |
dockerfile |
Yes | Dockerfile |
Path to the Dockerfile, relative to the repo root. See the note below — it is required in practice. |
context |
No | . |
Docker build context directory, relative to the repo root. |
args |
No | {} |
Build arguments passed to docker build --build-arg. |
build_args_from_vars |
No | [] |
Stored variables (mecca var set) to also pass as build arguments. See below. |
target |
No | — | Build target for multi-stage Dockerfiles (docker build --target). |
Unknown keys are silently ignored
Any key AppMecca does not recognise is dropped with no error and no warning.
A misspelled dockerfle: does not fail the build — it falls back to the default
Dockerfile and the pre-flight check then rejects the container for having no
dockerfile. Check spelling first when a setting seems to do nothing.
name¶
The container name identifies the image inside the AppMecca image registry, scoped to your app and environment:
You never type this path — AppMecca resolves it for you at build and deploy time.
Naming rules
Container names must be lowercase and can contain letters, numbers, and hyphens. Avoid very long names — they are folded into generated resource names that have length limits.
dockerfile¶
Path to the Dockerfile relative to the repository root.
dockerfile is required in practice
The schema defaults this to Dockerfile, but the repository pre-flight check that
runs on mecca register rejects any container entry that does not declare
dockerfile explicitly. Always write it out.
containers:
# Dockerfile in repo root (default)
- name: myapp
dockerfile: Dockerfile
# Dockerfile in a subdirectory
- name: frontend
dockerfile: frontend/Dockerfile
context¶
The Docker build context — the directory that Docker can access during the build. Defaults to . (the repository root).
When to change the context
If your Dockerfile is in a subdirectory and only needs files from that subdirectory, set the context to match. This keeps the Docker build context small and builds faster.
If your Dockerfile needs files from the repo root (like a shared requirements.txt), keep the context as . and use the full path in your COPY commands.
build_args_from_vars¶
Variables you set with mecca var set reach the build as secrets: a RUN step
reads one with --mount=type=secret,id=NAME (the value is in /run/secrets/NAME),
and the value is not stored in the image.
List a stored variable here only when it is not a secret and your Dockerfile needs it
as an ARG. It is then passed as a build argument too, and its value is stored in the
image.
Each entry must be letters, digits and underscores, not starting with a digit.
Release 6.4 transition
In release 6.4, a stored variable your Dockerfile declares with ARG is still
passed as a build argument even when it is not listed here, with a warning in the
build log and in mecca queue status. From release 6.5 that build is refused.
args¶
Build arguments passed to Docker via --build-arg. These are available in your Dockerfile as ARG values. Never put a secret here: anyone who can pull the image can read build arguments from its history.
In your Dockerfile:
ARG NODE_ENV=development
ARG API_VERSION
RUN echo "Building for ${NODE_ENV}, API version ${API_VERSION}"
target¶
For multi-stage Dockerfiles, specifies which build stage to use as the final image. This maps to docker build --target.
In your Dockerfile:
FROM node:20-slim AS builder
RUN npm ci && npm run build
FROM node:20-slim AS production
COPY --from=builder /app/dist/ /app/
CMD ["node", "/app/server.js"]
FROM node:20-slim AS development
COPY . /app/
CMD ["npm", "run", "dev"]
Multiple Containers¶
You can build multiple containers from a single repository. This is common for full-stack applications with separate frontend and backend images.
containers:
- name: frontend
dockerfile: frontend/Dockerfile
context: frontend/
- name: backend
dockerfile: backend/Dockerfile
context: backend/
args:
PYTHON_VERSION: "3.12"
Each container becomes its own image in the registry, namespaced by app and environment.
When you trigger a build, all containers defined in appmecca.yaml are built in sequence. You can't build just one.
Image tagging
Every image is tagged with the Git commit hash (e.g., abc1234) and latest. This means you can always trace a running container back to exactly which code it was built from.
Monorepo Patterns¶
Separate directories¶
The most common pattern for monorepos — each service has its own directory:
containers:
- name: web
dockerfile: services/web/Dockerfile
context: services/web/
- name: api
dockerfile: services/api/Dockerfile
context: services/api/
- name: worker
dockerfile: services/worker/Dockerfile
context: services/worker/
Shared root context¶
If your services share code (like a common library), use the repo root as the context:
containers:
- name: web
dockerfile: services/web/Dockerfile
context: .
- name: api
dockerfile: services/api/Dockerfile
context: .
In this case, both Dockerfiles can COPY from anywhere in the repository.
Dockerfile Best Practices¶
Include a health check endpoint for anything that serves HTTP¶
Any service that declares a port should expose an endpoint returning HTTP 200 when it
is healthy, and a matching health_check: block in appmecca.yaml. That is how AppMecca
decides your new container is ready to receive traffic during a deploy.
Background workers with no port need neither — omit health_check: for them, which
turns health checking off for that service entirely.
Use multi-stage builds¶
Multi-stage builds produce smaller images and faster deployments:
# Build stage — has all the build tools
FROM node:20-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Runtime stage — only has what's needed to run
FROM node:20-slim
WORKDIR /app
COPY --from=builder /app/build/ ./build/
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "build"]
Pin your base images¶
Use specific version tags, not latest:
# Good — reproducible builds
FROM python:3.12-slim
FROM node:20-slim
# Bad — might change unexpectedly
FROM python:latest
FROM node:latest
Use EXPOSE¶
While AppMecca reads the port from appmecca.yaml (not from EXPOSE), including EXPOSE in your Dockerfile is good documentation:
Next Steps¶
- Services — Configure how your containers run (ports, health checks, commands)
- Multi-Container Builds — Deep dive into building multiple containers