#14: Gitea CI, registry composes, Node 22 image and changelog

- Gitea Actions: Trivy, Vitest in a Dockerfile test stage, arm64 image build, image
  scan and smoke test; releases reuse the image by content hash.
- docker-compose.<edition>.registry.yaml run the stack from the published image.
- Dockerfile: Node 22, a test stage, and no npm in the runtime image.
- README, CLAUDE.md and CHANGELOG describe the CI, the image and the release flow.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-11-01 22:54:00 -03:00
1 parent 640e52c0c9
commit a4a2584f37
12 files changed
+606 -9

No files matched your search

+85
View File
@@ -0,0 +1,85 @@
# CraftDock — Java stack, from the published image (no local build).
# Usage: docker compose -f docker-compose.java.registry.yaml up -d
# Same stack as docker-compose.java.yaml, but the panel is pulled from the Gitea
# registry (built and tested by CI) instead of being built on the host.
# Secrets/overrides (${...}) are read from the project .env by docker compose.
# See the "Environment variables" table in README.md for every variable.
services:
craftdock-panel:
image: git.lucasrguerra.dev.br/lucasrguerra/craftdock:${IMAGE_TAG:-latest}
pull_policy: always
container_name: craftdock-panel
# Behind a reverse proxy (Coolify/Traefik) the panel is reached over the
# internal Docker network, so only EXPOSE the port — do NOT publish it on the
# host. In Coolify, set the service domain WITHOUT a port
# (https://your.domain, not https://your.domain:3000) and make sure the
# service's target port is 3000 — otherwise Traefik forwards to the wrong
# port and plain 443 returns "no available server".
#
# For LOCAL testing without a proxy, comment out `expose` and uncomment
# `ports` to publish on the host, then open http://localhost:3000.
expose:
- "3000"
# ports:
# - "${PORT:-3000}:3000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- mc-data:/minecraft/data
environment:
- NODE_ENV=${NODE_ENV:-production}
- LOG_LEVEL=${LOG_LEVEL:-info}
# base64 of the bcrypt hash — avoids docker/Coolify eating the `$` chars.
- ADMIN_PASSWORD_HASH_B64=${ADMIN_PASSWORD_HASH_B64}
- SESSION_SECRET=${SESSION_SECRET}
- MC_CONTAINER_NAME=craftdock-mc-server
- MC_DATA_PATH=/minecraft/data
- MC_EDITION=java
- MC_WORLD_NAME=world
- RCON_HOST=craftdock-mc-server
- RCON_PORT=25575
- RCON_PASSWORD=${RCON_PASSWORD:-}
- MAP_VERSION=${MAP_VERSION:-}
healthcheck:
test: ["CMD", "node", "src/healthcheck.js"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
networks: [craftdock-net]
# `always` (not `unless-stopped`): the panel must come back after ANY exit —
# a crash, its own healthcheck self-restart (kill PID 1), a manual stop, or a
# host/daemon reboot. It's the control plane, so it should never stay down.
restart: always
minecraft-server:
image: itzg/minecraft-server:latest
container_name: craftdock-mc-server
# stdin_open + tty are REQUIRED by CraftDock: without a TTY, Docker returns a
# multiplexed log stream (8-byte frame headers) that garbles the Console tab.
stdin_open: true
tty: true
ports:
- "25565:25565" # Java game port (raw TCP — open it in the host firewall)
volumes:
- mc-data:/data
environment:
- EULA=TRUE
- TYPE=PAPER
- VERSION=LATEST
- ENABLE_RCON=true
- RCON_PASSWORD=${RCON_PASSWORD:-} # required for the panel's Java command channel
- OVERRIDE_SERVER_PROPERTIES=false # so the Options tab persists
healthcheck:
test: ["CMD-SHELL", "/usr/local/bin/mc-health || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 120s
networks: [craftdock-net]
restart: unless-stopped
volumes:
mc-data:
networks:
craftdock-net:
driver: bridge