Dockerfile, then write a manifest that points to that image and declares its port, memory, healthcheck and questions. In this tutorial you package a small web app that keeps a visit counter on the persistent disk, and you end with a private template anyone on your account can deploy in a few clicks.
Use an image template when the app needs another language or version, system packages, its own start process, or when you are packaging ready-made software. If plain source code is enough, a code template is simpler and does not use an image slot.
Before you start
The Vertra CLI signed in with an API key that has the
templates:read, templates:write and templates:deploy scopes, plus the scopes that build images.A plan that can create Docker images and private templates (see Plans and limits). Each account keeps up to 5 private templates.
You know the rules of custom Docker images: writable paths, user
1000:1000, the PORT variable and what the build refuses.Every image in use takes one image slot in the account that uses it, no matter how many apps run from it. When you deploy your own template, the image is already yours; people who receive it through a link get their own copy and use one slot each.
Step by step
1
Write an app that follows the platform rules
An image runs with the same isolation as any application: the root filesystem is read-only, the user is always The
1000:1000, /app is the only persistent disk, and the server must listen on the PORT variable. Create this folder:server.js serves the page, counts visits in a file under /app/data and answers /healthz for the healthcheck:server.js
Dockerfile keeps the program outside /app (anything the image puts in /app is hidden by the persistent disk when the app runs) and does not use USER, VOLUME or HEALTHCHECK, which the platform ignores or refuses:Dockerfile
2
Build the image on the platform
The template does not carry the Find the image id with
Dockerfile: it references an image that already exists in your account. Build it from the folder:vertra image list. Wait until the build is success; a failure shows the reason in the log. The .env* files are removed from the context and .dockerignore is respected. Each successful build becomes a new version of the same image, with the same id.3
Write the manifest
Create The fields that differ from a code template:
vertracloud.template.yaml. The value of source.image is the id of your image; replace the example id with yours:vertracloud.template.yaml
source.context and image digests (@sha256:...) belong to templates in the public catalog, where the image is pinned by digest and built from the template folder. In a private template the image of your account is the source. The last tutorial shows how a private template becomes a catalog one.4
Validate
validate cannot see, such as an image that is not yours (IMAGE_NOT_FOUND) or not built yet (IMAGE_NOT_READY).5
Create the template and deploy it
/healthz and prints the outputs. Open the address and reload it: the counter must go up. Restart the app from the panel and reload again: the number survives, because /app is persistent.6
Ship a new version
Change the code, run
vertra image rebuild <image-id> --context ., wait for success, raise version in the manifest and run vertra template create --template hello-counter --changelog "Describe the change". The new template version pins the new image version. Apps created from the template see “New version available” and update when their owner chooses, with a safety snapshot first.Troubleshooting
Next steps
- Requirements and plan: how
ram,weband the image decide the required plan and slots. - Deploy settings: when to lock blue-green and require rollback with data.
- Best practices: where data goes, the read-only root, user 1000 and the port.
- Manifest reference: every field of an app service.
- Custom Docker images: the build rules, versions and rollback of the image itself.
- Next tutorial: a stack with Postgres and Redis.