Files
ADconsle/docs/upgrading.md
T
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

4.4 KiB

Upgrading

Versioning

From v1.0.0 on, releases are semantic git tags vX.Y.Z:

  • MAJOR — incompatible change: a required new .env key, a schema change that is not auto-migrated, or a new AD permission the service account needs. Read this page before upgrading.
  • MINOR — new, backwards-compatible feature. Safe to pull; still run php artisan migrate.
  • PATCH — backwards-compatible fix only.

The latest tag on main is the supported version; there are no long-term-support branches. Per-version notes are under Version notes below and in CHANGELOG.md.

General procedure

# back up the DB first (panel_settings + panel_attributes hold your config)
mysqldump adconsole > adconsole-$(date +%F).sql

git pull            # or fetch a new release
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize:clear
php artisan optimize          # config + route + view + event cache

Docker (from the repo root): bump ADCONSOLE_VERSION in .env, then docker compose --env-file .env -f docker/compose.yaml pull and … up -d. The entrypoint runs migrate --force and optimize for you.

Roll back = restore the DB dump and either check out the previous revision or set ADCONSOLE_VERSION back to the previous tag.

Version notes

v1.1.0 — Docker layout

The Docker files moved and the production image changed shape. One-time steps for an existing Docker install:

  1. git pull — docker/compose.yaml now lives in docker/, builds a self-contained image, and reads persistent state from docker/data/ bind mounts instead of the adconsole_db_data / adconsole_app_storage named volumes.

  2. Stop the old stack: docker compose -f docker/compose.yaml down (old file).

  3. Copy the volume contents into docker/data/ before the first new up:

    mkdir -p docker/data/db docker/data/app_storage
    docker run --rm -v adconsole_db_data:/from -v "$PWD/docker/data/db":/to \
      alpine cp -a /from/. /to/
    docker run --rm -v adconsole_app_storage:/from -v "$PWD/docker/data/app_storage":/to \
      alpine cp -a /from/. /to/
    
  4. Start it, always from the repo root and with --env-file .env:

    docker compose --env-file .env -f docker/compose.yaml up -d
    

    (export COMPOSE_FILE=docker/compose.yaml COMPOSE_ENV_FILES=.env once to drop the flags.) up -d now pulls the released image; add --build to build from the working tree.

Rootless Docker can't chown a bind-mounted MariaDB datadir — run the daemon rootful, or switch the mariadb volume in docker/compose.yaml to a named volume. Nothing changes for a bare-metal install.

Panel configuration moved into the database

Two migrations, both automatic — just run php artisan migrate (the Docker entrypoint does this for you).

  1. create_panel_settings_table — general settings (password policy & generator, reset-dialog defaults, encryption key) move out of the old storage/app/panel_settings.json. The migration imports that file if present and renames it panel_settings.json.migrated.
  2. create_panel_attributes_table — the AD attribute / column definitions move from the JSON blob into their own table, one row per attribute with real columns (key, label, ldap, category, type, is_column, position). The migration copies the existing list across and strips the now-unused attributes (and dead domains / users_table) keys from the panel_settings row.
  • After migrating, open /settings and confirm the General tab and the Attributes tab still show your settings, then delete any storage/app/panel_settings.json.migrated.
  • Fresh installs have empty tables and run on PanelSettingsService::defaults() / defaultAttributes() until you save something.
  • The legacy file and its .migrated rename are git-ignored.

New .env keys

LDAP_SSL, LDAP_TLS_VERIFY, APP_DOMAIN. Existing installs keep working with the defaults (LDAP_SSL=true, LDAP_TLS_VERIFY=false); add explicit values when you next edit .env. See configuration.md.

After any upgrade

  • php artisan test if you carry local patches.
  • Re-check the hardening checklist.
  • Watch storage/logs/laravel.log on the first real use.