3x-ui/docker-compose.yml
MHSanaei a13a79b230
fix(docker): start crond and persist acme.sh state so cert renewal works
The image shipped busybox crond but the entrypoint never started it, and the acme.sh crontab entry vanished on every container recreation, so certificates issued via the panel's SSL menu silently expired after 90 days. The entrypoint now re-registers the acme.sh cron job and starts crond when acme.sh is installed, and docker-compose gains an acme volume so renewal state survives recreation.

Closes #5116
2026-07-03 09:32:28 +02:00

59 lines
2.4 KiB
YAML

services:
3xui:
build:
context: .
dockerfile: ./Dockerfile
container_name: 3xui_app
# hostname: yourhostname <- optional
# Optional hard memory cap. When set, the panel derives its Go soft limit
# (GOMEMLIMIT, ~90% of this cap) so it GCs before the OOM killer fires.
# mem_limit: 512m
# The bundled Fail2ban (XUI_ENABLE_FAIL2BAN below) enforces the IP limit
# with iptables, which needs NET_ADMIN. Without these caps a ban is logged
# and shown in fail2ban status but never actually applied. NET_RAW covers
# ip6tables. If you disable Fail2ban, you can drop cap_add.
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- $PWD/db/:/etc/x-ui/
- $PWD/cert/:/root/cert/
# Persists acme.sh state so certificate auto-renewal survives container
# recreation (the entrypoint re-registers the renewal cron job from it).
- $PWD/acme/:/root/.acme.sh/
environment:
XRAY_VMESS_AEAD_FORCED: "false"
XUI_ENABLE_FAIL2BAN: "true"
# Memory tuning. The panel keeps RAM low via GOGC + periodic release; it no
# longer sets a soft limit from total host RAM (no benefit, risks GC thrash).
# XUI_GOGC: "75" # lower = less RAM, slightly more CPU; GOGC env overrides
# XUI_MEMORY_RELEASE_INTERVAL: "10" # minutes between FreeOSMemory; 0 disables
# Go memory soft limit, only applied from an explicit budget below (or a
# real cgroup/mem_limit cap). Pin it with one of:
# XUI_MEMORY_LIMIT: "400" # in MiB
# GOMEMLIMIT: "400MiB" # Go syntax, takes precedence
# XUI_PPROF: "true" # expose pprof on 127.0.0.1:6060 for profiling
# XUI_INIT_WEB_BASE_PATH: "/"
# XUI_PORT: "8080"
# To use PostgreSQL instead of the default SQLite, run:
# docker compose --profile postgres up -d
# and uncomment the two lines below.
# XUI_DB_TYPE: "postgres"
# XUI_DB_DSN: "postgres://xui:xui@postgres:5432/xui?sslmode=disable"
tty: true
ports:
# When XUI_PORT is set, publish the same container port (for example "8080:8080").
- "2053:2053"
restart: unless-stopped
postgres:
image: postgres:16-alpine
container_name: 3xui_postgres
profiles: ["postgres"]
environment:
POSTGRES_USER: xui
POSTGRES_PASSWORD: xui
POSTGRES_DB: xui
volumes:
- $PWD/pgdata/:/var/lib/postgresql/data
restart: unless-stopped