Docker image
Set up deeplo as a Docker container and run your first deploy.
Prerequisites:
- A host running Docker with the Compose plugin
- At least one remote host running Docker with the Compose plugin
- SSH access to those remote hosts
Create the compose file
Create compose.yml with the deeplo service:
services:
deeplo:
image: ghcr.io/jancernik/deeplo:latest
container_name: deeplo
restart: unless-stopped
ports:
- "8470:8470"
environment:
DEEPLO_SSH_PRIVATE_KEY_FILE: /run/secrets/deploy_key
DEEPLO_SSH_USER: deploy
volumes:
- deeplo-data:/var/lib/deeplo
- ./config.yml:/etc/deeplo/config.yml:ro
secrets:
- deploy_key
volumes:
deeplo-data:
secrets:
deploy_key:
file: ./secrets/deploy_keyIf you prefer to mount a host directory, create it with the same container ownership:
mkdir -p data
sudo chown 1000:1000 dataThen mount it instead of the named volume:
volumes:
- ./data:/var/lib/deeploGenerate a deploy key
mkdir -p secrets
ssh-keygen -t ed25519 -f secrets/deploy_keyKeys generated with the command above already have the right permissions. If you copy in an existing key or create one another way, make sure the container user owns it:
sudo chown 1000:1000 secrets/deploy_key
sudo chmod 600 secrets/deploy_keyAuthorize the deploy key
Confirm DEEPLO_SSH_USER matches your deploy user. If you need to create one, see the deploy user. Then install the public key on each target before starting the daemon:
ssh-copy-id -i secrets/deploy_key.pub deploy@10.0.0.10To do it manually, append the contents of secrets/deploy_key.pub to ~/.ssh/authorized_keys for the deploy user on each target.
The daemon uses the same key to fetch your repos over SSH. For private repos, grant that key read access. On GitHub, for example, you can add deploy_key.pub as a read-only deploy key.
Edit the config
Create config.yml beside compose.yml and replace the example values with your own:
hosts:
- name: web-1
address: 10.0.0.10 # your host IP or hostname
deploy_dir: /srv/apps
repos:
- name: myapp
url: git@github.com:yourorg/myapp.git
branch: main
projects:
- name: myapp
repo: myapp
repo_subdir: deploy # directory in repo containing compose.yml
persist_files:
- .env
targets:
- web-1The deploy directory is rebuilt each time
Each deploy rebuilds the project's remote directory from the commit and replaces the previous contents. A file that lives only on the host (a token you copied in, a runtime-generated file) won't survive the next deploy unless you persist it:
- Keep specific files by listing them in
persist_files(defaults to[".env"],[]keeps nothing). - Store data in a Docker named volume or a bind mount outside the deploy directory.
Then validate it:
docker compose run --rm deeplo config checkSee Config file for the full schema.
Start the daemon
docker compose up -d
docker compose exec deeplo deeplo health # confirm it's running and reachableOn start, the daemon reconciles your config and deploys every configured project at its current commit, so your first deploy begins right away.
Watch the first deploy
Follow it in the logs:
docker compose logs -fThen check the result:
docker compose exec deeplo bash
deeplo deploys state # latest state per project-host
deeplo deploys history # recent runs
deeplo deploys logs <run-id> # log for a run (id from history)To see all available commands, use deeplo --help or browse the CLI reference.
You can create an alias to run CLI commands against the container as you would on a native install:
alias deeplo='docker exec deeplo deeplo'Next steps
Triggers
Webhook, poll, and hybrid trigger modes
Repository layout
How to lay out a repo and its compose files
Upgrading
docker compose pull deeplo
docker compose up -d deeploThis downloads the new image and recreates the container. In-flight deploys get up to DEEPLO_SHUTDOWN_GRACE (default 30s) to finish first.