Files
kzbkowskiandClaude Sonnet 5 b313c126ce
CI / PHP 8.2 (push) Failing after 1m40s
CI / PHP 8.3 (push) Failing after 55s
CI / PHP 8.4 (push) Failing after 1m11s
Release image / image (push) Successful in 2m33s
ADconsole v1.1.0
Config backup, a Docker dev/prod split, and a Gitea-built release image.

Added
- /settings -> General -> "Configuration backup": JSON export/import of the
  panel's general settings + attribute definitions
  (App\Services\ConfigBackupService); audited as config.export / config.import.
  Export can leave out the attribute-encryption key. No AD data included.
- docker/compose.dev.yaml: live-reload dev stack that bind-mounts the working
  tree. docker/php/Dockerfile is now multi-stage (base -> dev / prod).
- .github/workflows/release.yml: on every vX.Y.Z tag, builds the prod image and
  pushes gitea.kzbikowski.pl/kzbkowski/adconsole:{X.Y.Z,X.Y,latest}.

Changed
- docker/compose.yaml: self-contained prod image (app code + composer install
  --no-dev baked in via COPY); persistent state in docker/data/{app_storage,db};
  defaults to the released image (ADCONSOLE_VERSION pins a tag, ADCONSOLE_IMAGE
  replaces the ref). Apache now honours public/.htaccess (AllowOverride All).
  Run from the repo root with --env-file .env.
- Repo root now holds only README.md; CHANGELOG / CONTRIBUTING / SECURITY /
  CODE_OF_CONDUCT moved under docs/.

Upgrade notes: docs/upgrading.md#v110--docker-layout. Full log: docs/CHANGELOG.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKT9p3bfP8RZesExdYCS52
2026-09-10 09:13:04 +02:00

95 lines
3.0 KiB
YAML

name: adconsole-dev
# =============================================================================
# Development stack — live-reload. The working tree is bind-mounted over
# /var/www/html, so edits to PHP / Blade / assets take effect on the next
# request (opcache revalidates every hit in the `dev` image target). The
# entrypoint runs `composer install` (incl. dev deps) and `key:generate` on
# the first boot of a fresh clone.
#
# Persistent state is kept in named volumes (not docker/data), so `migrate:fresh`
# and `down -v` behave like a throwaway dev box:
#
# app_storage -> /var/www/html/storage
# db_data -> /var/lib/mysql
#
# Run from the repo root:
# cp .env.example .env # APP_ENV=local, APP_DEBUG=true, real LDAP_*
# docker compose --env-file .env -f docker/compose.dev.yaml up --build
#
# Reverse proxy: an external Traefik on `traefik_public`, same as production.
# Without Traefik, uncomment the `ports:` block below and open
# http://localhost:8080 (set APP_URL to match).
# =============================================================================
services:
app:
build:
context: ..
dockerfile: docker/php/Dockerfile
target: dev
container_name: adconsole_dev_app
restart: unless-stopped
environment:
# Reach the DB service by name regardless of DB_HOST in the bind-mounted
# .env (Laravel's dotenv does not override a real env var). Kept minimal so
# `artisan test` inside the container still picks up phpunit.xml's env.
DB_HOST: mariadb
volumes:
- ..:/var/www/html
- app_storage:/var/www/html/storage
# ports:
# - "8080:80"
depends_on:
mariadb:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost/up"]
interval: 30s
timeout: 5s
retries: 5
start_period: 120s
networks:
- internal
- traefik_public
labels:
- traefik.enable=true
- traefik.docker.network=traefik_public
- traefik.http.routers.adconsole-dev.rule=Host(`${APP_DOMAIN:-adconsole.localhost}`)
- traefik.http.routers.adconsole-dev.entrypoints=websecure
- traefik.http.routers.adconsole-dev.tls=true
- traefik.http.services.adconsole-dev.loadbalancer.server.port=80
mariadb:
image: mariadb:11
container_name: adconsole_dev_db
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-change-me-root}
MARIADB_DATABASE: ${DB_DATABASE:-adconsole}
MARIADB_USER: ${DB_USERNAME:-adconsole}
MARIADB_PASSWORD: ${DB_PASSWORD:-change-me}
MARIADB_AUTO_UPGRADE: "1"
volumes:
- db_data:/var/lib/mysql
# Expose the DB on the host for a GUI client.
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
networks:
- internal
volumes:
app_storage:
db_data:
networks:
internal:
traefik_public:
external: true