The Compose setup in docker-compose.yml starts a complete local daloRADIUS stack:
radius-mysql: MariaDB database;radius: FreeRADIUS;radius-web: daloRADIUS users and operators web interfaces.
Use Dockerfile-standalone only when MariaDB and FreeRADIUS are already managed outside this repository.
Create an environment file from the template:
cp .env.example .envEdit .env and replace every CHANGE_ME_... value:
MYSQL_PASSWORD=CHANGE_ME_RADIUS_DB_PASSWORD
MYSQL_ROOT_PASSWORD=CHANGE_ME_ROOT_DB_PASSWORD
DEFAULT_CLIENT_SECRET=CHANGE_ME_RADIUS_SHARED_SECRETOptional values can be kept as-is for a local setup:
TZ=Europe/Vienna
DALORADIUS_OPERATORS_BIND=127.0.0.1:8000
MYSQL_HEALTH_START_PERIOD=10m
FREERADIUS_SQL_TLS=disabled
MAIL_SMTPADDR=127.0.0.1
MAIL_PORT=25
MAIL_FROM=root@daloradius.example.com
MAIL_AUTH=Validate the Compose file and environment:
docker compose config --quietBuild and start the stack:
docker compose up -d --buildCheck service state:
docker compose psAccess the web interfaces:
- users UI:
http://localhost/ - operators UI:
http://127.0.0.1:8000/, unlessDALORADIUS_OPERATORS_BINDis changed
The initial operator account seeded by the default schema is:
username: administrator
password: radius
Use this account only for the first login, then change the operator password from the operators UI.
RADIUS authentication and accounting listen on host UDP ports 1812 and 1813.
MariaDB data remains in ./data/mysql, FreeRADIUS init state remains in ./data/freeradius, and daloRADIUS init state remains in ./data/daloradius.
Fresh Docker deployments initialize the database from the bundled schema. When upgrading an existing Docker deployment, check contrib/db/migrations/ in the updated source tree and apply the relevant SQL migrations before using newly added features.
For example, to apply the operator MFA migration from the directory that contains docker-compose.yml:
docker compose exec -T radius-mysql sh -lc 'mariadb -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' \
< contrib/db/migrations/2026-06-operator-totp-mfa.sqlTo initialize a new Docker stack from an existing MariaDB dump, copy one or more .sql or .sql.gz files into ./var/backup before the first startup:
mkdir -p var/backup
cp /path/to/backup.sql.gz var/backup/
docker compose up -d --buildThe radius-mysql container mounts ./var/backup as /docker-entrypoint-initdb.d, so MariaDB imports those files automatically when ./data/mysql is empty. After the import, the daloRADIUS and FreeRADIUS containers detect the existing schema and skip their default schema imports.
Large dumps can take several minutes to import. MYSQL_HEALTH_START_PERIOD controls how long Docker ignores failing MariaDB healthchecks during first startup; increase it in .env if your hardware or dump size requires more time.
This automatic import only runs during MariaDB first initialization. To replace an already initialized Docker database, stop the stack, back up any data you need to keep, remove ./data/mysql, place the desired dump in ./var/backup, and start the stack again:
docker compose down
rm -rf ./data/mysql
mkdir -p var/backup
cp /path/to/backup.sql.gz var/backup/
docker compose up -d --buildUse Docker logs for container output:
docker compose logs -f radius-web radius radius-mysqlThe FreeRADIUS log is shared with the web container through the radius_logs volume so the daloRADIUS operators UI can read /var/log/freeradius/radius.log.
Stop containers without deleting data:
docker compose downRemove containers and local database/application state:
docker compose down
rm -rf ./dataBuild the standalone web image:
docker build -t daloradius-standalone -f Dockerfile-standalone .Create a daloradius.conf.php for your external database and RADIUS settings, then mount it into the container:
docker run --name daloradius-standalone \
-v /path/to/daloradius.conf.php:/var/www/html/daloradius/common/includes/daloradius.conf.php:ro \
-p 80:80 \
-p 127.0.0.1:8000:8000 \
-d daloradius-standalone