Docker Compose
Run ImgYoung with the compose.yaml from the repository, and pair it with Caddy for automatic HTTPS.
The sample file
deploy/compose.yaml in the repository (release archives include a copy too):
# ImgYoung 的 Docker Compose 示例。
# 用法:把本文件放进一个空目录,执行 docker compose up -d,浏览器打开 http://<主机>:8721/,
# 用 admin / imgyoung123 登录(首次登录强制改密)。
services:
imgyoung:
image: ghcr.io/x-haose/imgyoung:latest # 生产环境建议钉大小版本(如 1.0)或具体版本
# 后台「从快照恢复」会让服务优雅退出,靠重启策略重新拉起后换入快照;正常退出也要拉起
restart: unless-stopped
# 优雅停机先停收新请求、等在途请求至多 6 秒,再停后台任务至多 2 秒;多出的是关库与退出的余量
stop_grace_period: 15s
ports:
- "8721:8721"
volumes:
# 数据库、本地存储渠道与自动生成的 master.key 都在这里;丢了 master.key,渠道凭证与加密数据不可恢复
- imgyoung-data:/data
# environment:
# # 前面有反向代理时,不论代理在宿主机还是另一个容器,ImgYoung 看到的对端都是 Docker 网络里的地址,
# # 填该网络的网段(docker network inspect 查看);否则登录限速与 /metrics 放行会把所有请求都当成来自代理本身
# IMGYOUNG_TRUSTED_PROXIES: 172.16.0.0/12
volumes:
imgyoung-data:
Put it in an empty directory and start it:
mkdir imgyoung && cd imgyoung
curl -fsSLO https://raw.githubusercontent.com/x-haose/imgyoung/main/deploy/compose.yaml
docker compose up -dOpen http://<host>:8721/ and sign in with admin / imgyoung123; the first sign-in asks you to change the password right away.
Image tags, the contents of the data volume, environment variables and the restart policy are explained on Docker image and not repeated here. Before referencing host variables with ${VAR} under environment:, read the warning in the "Environment variables" section there: a variable the host does not set is substituted as an empty string.
stop_grace_period: 15s in the sample caps how long Compose waits for the process to exit on stop. On the stop signal ImgYoung stops accepting new requests and waits up to 6 seconds for in-flight ones, stops background work within 2 more seconds, then closes the database and exits; 15 seconds leaves headroom over those roughly 8.
Day-to-day operations
Run these in the directory that holds compose.yaml:
| Task | Command |
|---|---|
Start, or apply changes to compose.yaml | docker compose up -d |
| Show status | docker compose ps |
| Follow the logs | docker compose logs -f imgyoung |
| Stop and remove the container (the volume is kept) | docker compose down |
| Upgrade | docker compose pull && docker compose up -d |
Do not add -v
docker compose down -v also deletes the data volume, and with it the database, the images and master.key.
The volume's real name carries the project name as a prefix, and the project name defaults to the directory name: inside an imgyoung directory it is imgyoung_imgyoung-data. Check with docker volume ls.
To pin a version, change image: to a major.minor tag such as ghcr.io/x-haose/imgyoung:1.0, or to an exact version, then run docker compose up -d. Switching back to an older tag is not a downgrade: the older version refuses to start on a database migrated by a newer one. Before upgrading, consider clicking "Back up now" under "Settings → Backups & export"; see Upgrading for the rollback steps and more.
Serving HTTPS with Caddy
Caddy obtains and renews certificates automatically. Put the two files below in one directory, replace the domain with yours, point its DNS at this host, and open ports 80 and 443:
services:
imgyoung:
image: ghcr.io/x-haose/imgyoung:latest
restart: unless-stopped
stop_grace_period: 15s
# No published port: Caddy is the only entry point
volumes:
- imgyoung-data:/data
environment:
# Caddy runs in another container on the same Docker network; use that network's range
IMGYOUNG_TRUSTED_PROXIES: 172.16.0.0/12
caddy:
image: caddy:2
restart: unless-stopped
depends_on:
- imgyoung
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
volumes:
imgyoung-data:
caddy-data:
caddy-config:img.example.com {
# Metrics are for internal scraping only; never forward them from the public entry point
respond /metrics 404
reverse_proxy imgyoung:8721
}The only configuration difference from deploy/Caddyfile in the repository is the upstream: Caddy runs in a container, so it reaches ImgYoung by service name, imgyoung:8721, instead of 127.0.0.1:8721.
Notes:
- Why
IMGYOUNG_TRUSTED_PROXIESis needed. By default ImgYoung trusts forwarding headers only from loopback, but Caddy connects from a private address on the Docker network. Without it, login rate limiting treats every visitor as the same client, returned image links usehttp://instead ofhttps://, and the session cookie is not markedSecure. - Check the subnet. The network Compose creates for the project usually falls inside
172.16.0.0/12, but once Docker's default pools there are used up it allocates from192.168.0.0/16as well. Rundocker network inspect imgyoung_default(when the project is named after the directory) and look atSubnet; if it is outside172.16.0.0/12, use the actual subnet. - Certificates and Caddy's data. Certificates live in the
caddy-datavolume; deleting it makes Caddy request new ones. - Upload size. Caddy does not limit request body size by default, so the only limit is "Max image size" in the console (50 MB by default).
- Link addresses. With the proxy trusted and no
base_urlconfigured, links are built from the host and scheme Caddy forwards, i.e.https://img.example.com/i/.... You only needbase_urlwhen the public domain differs from the one Caddy receives (for example with a CDN in front); see Configuration. - Metrics. The public entry point blocks
/metrics; a Prometheus on the same network can scrapeimgyoung:8721/metricsdirectly, since private addresses are allowed by default. See Monitoring.
For Nginx and other proxies, see Reverse proxy.
Docker image
Run ImgYoung from the multi-arch image on GHCR - the run command, image tags, the data volume, environment variables and settings behind a reverse proxy.
Release archives
Download the archive for your platform, verify its sha256 and run it directly; suited to Windows and to environments where the install script is inconvenient.