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:
- Updates the system and installs
curl,unzip,jqandsocat, and Docker if it is missing. - Creates
/var/www/featherpaneland/var/www/featherpanel/backups. - Writes a random
DOCKER_UPDATER_TOKENto/var/www/featherpanel/.envand installs thefeatherpanel-docker-updatersystemd service (see Updating). - Downloads
docker-compose.ymlfrom themainbranch (ordocker-compose.v2.dev.ymlfor development builds) and applies the panel port. - Stops any old FeatherPanel containers and runs
docker compose up -d. - 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.
- Installs the
featherpanelcommand in/usr/local/bin, which runsphp cliinside 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
| Service | Image | Role |
|---|---|---|
mysql | mariadb:latest | Database. Not published on the host. |
redis | redis:latest | Cache, sessions and queues, with append-only persistence and a password. |
backend | featherpanel-backend | PHP API under FrankenPHP (worker mode by default) and the cron runner, both managed by supervisord. |
frontendv2 | featherpanel-frontendv2 | Next.js frontend. Publishes ${FEATHERPANEL_PANEL_PORT:-4831}:80 and proxies /api to the backend. |
mcp | featherpanel-mcp | MCP server on port 3001 inside the network. |
async-runner | featherpanel-async-runner | Rust 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
| Volume | Mounted at | Contents |
|---|---|---|
mariadb_data | /var/lib/mysql | The database |
redis_data | /data | Redis append-only file |
featherpanel_config | /var/www/html/storage/config | The backend .env, including DATABASE_ENCRYPTION_KEY |
featherpanel_attachments | /var/www/html/public/attachments | Uploaded files |
featherpanel_snapshots | /var/www/html/storage/backups | Panel snapshots |
featherpanel_logs | /var/www/html/storage/logs | Logs, shared with the async runner |
featherpanel_translations | /var/www/html/public/translations | Translation files |
featherpanel_addons | /var/www/html/storage/addons | Installed plugins |
featherpanel_data | /var/www/html/storage/data | Runtime data |
featherpanel_pma | /var/www/html/public/pma | phpMyAdmin files |
featherpanel_webmail | /var/www/html/public/webmail | Webmail files |
mcp_oauth_data | /data | MCP 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.
| Variable | Value | Meaning |
|---|---|---|
DATABASE_HOST, DATABASE_PORT | mysql, 3306 | Database inside the Compose network |
DATABASE_ENCRYPTION | xchacha20 | Cipher for encrypted columns |
TRUST_PROXY_HEADERS | true | Read the client IP from X-Forwarded-For |
PANEL_DOCKER_DEPLOYMENT | true | Enables Docker-only actions such as the in-panel update button |
FRANKENPHP_WORKER | true | Set false for classic (non-worker) PHP mode |
DOCKER_UPDATER_URL, DOCKER_UPDATER_TOKEN | http://host.docker.internal:9418/update, from .env | Host 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
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.
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_.
The installer asks you to wait about five minutes. The backend health check allows a 180 second start period while it runs database migrations.