View .md

Docker installation

Install FeatherPanel with Docker Compose, by the installer script or by hand. Covers the services, volumes, ports, .env values and the first start.

On this page

With the installer

Run the installer as root and choose [1] Panel, then Install Panel, then Docker mode:

curl -sSL https://get.featherpanel.com/installer.sh | bash

The installer then:

  1. Updates the system and installs curl, unzip, jq and socat, and Docker if it is missing.
  2. Creates /var/www/featherpanel and /var/www/featherpanel/backups.
  3. Writes a random DOCKER_UPDATER_TOKEN to /var/www/featherpanel/.env and installs the featherpanel-docker-updater systemd service (see Updating).
  4. Downloads docker-compose.yml from the main branch (or docker-compose.v2.dev.yml for development builds) and applies the panel port.
  5. Stops any old FeatherPanel containers and runs docker compose up -d.
  6. Sets up the access method you picked: a Cloudflare Tunnel, or an nginx or Apache site from the templates in Web server with an optional Let’s Encrypt certificate.
  7. Installs the featherpanel command in /usr/local/bin, which runs php cli inside the backend container. See Panel CLI.

Wait about five minutes, open the panel and register. The first account becomes the administrator.

Unattended installs

Every menu choice can be passed as an environment variable. The full list is in the installer reference. For example:

curl -sSL https://get.featherpanel.com/installer.sh | env FP_COMPONENT=panel FP_ACTION=install bash

By hand

You can run the same Compose file without the installer.

mkdir -p /var/www/featherpanel && cd /var/www/featherpanel
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/MythicalLTD/FeatherPanel/main/docker-compose.yml

Create /var/www/featherpanel/.env before the first start. Compose reads it for the variables below; every one has a default in the Compose file.

MARIADB_ROOT_PASSWORD=change-me
MARIADB_DATABASE=featherpanel
MARIADB_USER=featherpanel
MARIADB_PASSWORD=change-me-too
REDIS_PASSWORD=change-me-three
FEATHERPANEL_PANEL_PORT=4831

Start the stack:

docker compose up -d
docker compose ps

What runs

ServiceImageRole
mysqlmariadb:latestDatabase. Not published on the host.
redisredis:latestCache, sessions and queues, with append-only persistence and a password.
backendfeatherpanel-backendPHP API under FrankenPHP (worker mode by default) and the cron runner, both managed by supervisord.
frontendv2featherpanel-frontendv2Next.js frontend. Publishes ${FEATHERPANEL_PANEL_PORT:-4831}:80 and proxies /api to the backend.
mcpfeatherpanel-mcpMCP server on port 3001 inside the network.
async-runnerfeatherpanel-async-runnerRust worker for background jobs. See Cron and workers.

All images are published for amd64 and arm64. On 32-bit ARM the installer sets up QEMU emulation.

Only the frontend publishes a port. The backend reaches the host’s updater service through host.docker.internal:9418.

Volumes

VolumeMounted atContents
mariadb_data/var/lib/mysqlThe database
redis_data/dataRedis append-only file
featherpanel_config/var/www/html/storage/configThe backend .env, including DATABASE_ENCRYPTION_KEY
featherpanel_attachments/var/www/html/public/attachmentsUploaded files
featherpanel_snapshots/var/www/html/storage/backupsPanel snapshots
featherpanel_logs/var/www/html/storage/logsLogs, shared with the async runner
featherpanel_translations/var/www/html/public/translationsTranslation files
featherpanel_addons/var/www/html/storage/addonsInstalled plugins
featherpanel_data/var/www/html/storage/dataRuntime data
featherpanel_pma/var/www/html/public/pmaphpMyAdmin files
featherpanel_webmail/var/www/html/public/webmailWebmail files
mcp_oauth_data/dataMCP OAuth store

Compose prefixes volume names with the project name, so on an installer host they appear as featherpanel_mariadb_data, featherpanel_featherpanel_config and so on.

Backend environment

The Compose file sets these on the backend container. You rarely need to change them.

VariableValueMeaning
DATABASE_HOST, DATABASE_PORTmysql, 3306Database inside the Compose network
DATABASE_ENCRYPTIONxchacha20Cipher for encrypted columns
TRUST_PROXY_HEADERStrueRead the client IP from X-Forwarded-For
PANEL_DOCKER_DEPLOYMENTtrueEnables Docker-only actions such as the in-panel update button
FRANKENPHP_WORKERtrueSet false for classic (non-worker) PHP mode
DOCKER_UPDATER_URL, DOCKER_UPDATER_TOKENhttp://host.docker.internal:9418/update, from .envHost updater used by the update button

The full list of variables the backend reads is in Environment variables.

Check that it works

cd /var/www/featherpanel
docker compose ps
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:4831/

All services should show healthy. If the backend restarts in a loop, read its log with docker compose logs backend and see Troubleshooting.

Frequently asked questions

Which port does FeatherPanel use?

The frontend container publishes port 4831 on the host by default. Set FEATHERPANEL_PANEL_PORT in /var/www/featherpanel/.env, or the panel port in the installer's Configuration menu, to change it.

Where does the Docker install live?

The installer keeps docker-compose.yml, .env, install.log and the backups folder in /var/www/featherpanel. Application data lives in named Docker volumes whose names start with featherpanel_.

How long does the first start take?

The installer asks you to wait about five minutes. The backend health check allows a 180 second start period while it runs database migrations.