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/ 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