Guides
Migrate from Docker Compose
A compose file maps to jekyo.yaml almost line for line. The parts that do not map are the parts Kubernetes does better.
The mapping
| compose | jekyo.yaml |
|---|---|
image | image, unchanged |
build | build (context, dockerfile, args map directly) |
environment (list or map) | env map, all values quoted |
ports: ["8080:80"] | port: 80. Public access goes through http: instead of host ports. |
volumes: [data:/var/lib/x] | Service volumes: plus a top-level volumes: entry with a size. |
volumes: [./file.conf:/etc/x] | Bake the file into the image with build.inline. |
healthcheck.test: [CMD, x] | health.command: [x] |
healthcheck.test: [CMD-SHELL, x] | health.command: [sh, -c, x] |
depends_on, restart, networks, labels, container_name | Drop them. Probes and the scheduler handle ordering and restarts. |
Two habits worth keeping: compact multiple data volumes into one volume with subpath mounts (one size question, one backup), and run jekyo render on the result before deploying.
Worked example
# docker-compose.yml (before)
services:
web:
image: ghost:5
ports: ["8080:2368"]
environment:
- url=https://blog.example.com
- database__connection__host=db
depends_on: [db]
db:
image: mysql:8.0
volumes: [dbdata:/var/lib/mysql]
restart: always
volumes:
dbdata:
# jekyo.yaml (after)
app: blog
services:
web:
image: ghost:5
env:
url: https://blog.example.com
database__connection__host: db
port: 2368
http:
domain: blog.example.com
db:
image: mysql:8.0
port: 3306
volumes:
dbdata: /var/lib/mysql
volumes:
dbdata:
size: 10Gi
backup:
schedule: "0 3 * * *"
The compose version had a host port and no TLS. The JEKYO version has a domain, a certificate, and a nightly backup.
Let your agent do it
If you use Claude Code, Codex, or Cursor with the JEKYO skill installed, paste the compose file and say:
/jekyo migrate this compose file to jekyo.yaml and deploy it
The skill knows this mapping table and will jekyo render its work before deploying.
Moving the data
Deploy the app first (volumes start empty), then stream the old server's data into the running pod:
# From the old volume's directory on the old server:
tar -cf - . | \
jekyo kubectl -- exec -i -n jekyo-blog db-0 -- tar -xf - -C /var/lib/mysql
jekyo restart blog/db
For databases, prefer the application's own tools over raw files: pg_dump | psql, mysqldump | mysql, or redis SAVE plus copying the dump file. Take a jekyo backup now immediately after the import so day one on JEKYO starts with a restorable snapshot.
Images without source
If the old server has images you cannot rebuild (no source access), export and import them:
docker save old-image:tag | gzip | ssh you@new-server \
"gunzip | sudo k3s ctr -n k8s.io images import -"
Reference the image by the same name in jekyo.yaml. Rebuilding from source later is a one-line change from image: to build:.