Deploying applications
Each application owns its Dockerfiles, Compose files, Traefik labels, secrets, and lifecycle hooks. The CLI reads this configuration from dockiy.yml in the Git repository root.
Application manifest
A minimal single-environment manifest looks like this:
version: 1
name: my-app
remote_path: apps/my-app
registry:
repositories:
app: my-app/app
artifacts:
app:
dockerfile: Dockerfile
target: app
environments:
default:
host: example.com
compose_file: docker-compose.yml
project_name: my-app
hooks:
build: scripts/build.sh
start: scripts/start.sh
healthcheck: scripts/healthcheck.shAn application must declare either one default environment or both staging and production. Arbitrary environment names are rejected. Each environment sets its host, Compose file, and project name, and may set a SOPS secrets_file.
build and start hooks are required. pre_start and healthcheck are optional. The manifest also accepts migrations and a rollback hook, but the current CLI does not act on either field. Put migrations in pre_start.
Deploy a release
Run from a committed application repository:
# One default environment
dockiy app deploy --version v1.2.3
# Staging and production
dockiy app deploy staging --version v1.2.3
dockiy app deploy production --version v1.2.3Versions must use the exact vX.Y.Z form.
Default and production deployments require a clean worktree and an explicit version. Staging can omit --version after a production tag exists; it uses the highest prod/vX.Y.Z tag. A dirty staging deployment requires --allow-dirty.
| Environment | Git tag | Image tag |
|---|---|---|
| Default | v1.2.3 | default-v1.2.3 |
| Production | prod/v1.2.3 | production-v1.2.3 |
| Staging | staging/v1.2.3-20260905-01 | staging-v1.2.3-20260905-01 |
The staging date is UTC and the final number increments for each base version on that date. The CLI creates the Git tag locally after all remote hooks pass. Push it yourself when ready.
Deployment flow
The CLI:
- resolves the Git root, global default server, optional local
dockiy.config.yml, manifest, environment, and release; - validates every referenced file and decrypts the selected SOPS secrets locally;
- runs the local
buildhook with image, Dockerfile, target, and platform variables; - opens an SSH tunnel and pushes each artifact to the VPS registry;
- uploads the Compose file, remote hooks, and a mode-0600
deploy.env; - runs
pre_start,start, andhealthcheckin that order when declared; - records the image references, digests, release, commit, and result under
<server remote_path>/state/apps/<app>/<environment>/.
The uploaded environment includes DOCKIY_APP_HOST, DOCKIY_COMPOSE_PROJECT_NAME, DOCKIY_ENVIRONMENT, DOCKIY_GIT_COMMIT, DOCKIY_RELEASE, and one DOCKIY_<ARTIFACT>_IMAGE value per artifact.
The current CLI has no application status or rollback command, deployment lock, automatic database backup, or automatic schema rollback.
Network
Application services join the external reverse_proxy network and define their own Traefik labels. They do not need to publish a host port.
The registry listens on 127.0.0.1:5000 on the VPS. SSH is the authentication boundary. The developer machine normally pushes through 127.0.0.1:5500, while the VPS Docker daemon pulls its own loopback reference.
Continue with the VitePress template, React template, or Nuxt template.
