Docker will download the images and start MySQL, Redis, and Fleet. This takes 2-3 minutes on the first run.
Check the status:
```bash
docker compose ps
```
All services should show as "healthy" after about 30 seconds.
## Access Fleet
Open your browser and navigate to:
**If using TLS (FLEET_SERVER_TLS=true):**
```
https://localhost:1337
```
**If behind a reverse proxy (FLEET_SERVER_TLS=false):**
```
http://localhost:1337
```
If using a self-signed certificate, your browser will warn you about the connection. This is expected - click "Advanced" and proceed.
You'll see the Fleet setup screen. Follow the prompts to:
1. Create your first admin account
2. Configure your organization name
3. Add your first device (optional)
That's it! Fleet is running.
## What's running
This deployment includes three services and one initialization container:
**fleet-init** is a one-time setup container that fixes volume permissions before Fleet starts. Fleet runs as a non-root user (UID 100) for security, but Docker creates volumes owned by root. This container runs once, sets the correct ownership, and exits. You'll see it listed as "Exited (0)" when you run `docker compose ps -a`.
**MySQL** stores all Fleet data (devices, policies, queries, users). The database persists in a Docker volume so your data survives restarts.
**Redis** handles background jobs and caching. Fleet uses this for scheduling tasks and improving performance.
**Fleet** is the main application. It serves the web UI, API, and handles device connections.
Fleet automatically runs database migrations on startup.
## Stop Fleet
Stop all services:
```bash
docker compose down
```
Stop and remove all data (careful - this deletes everything):
```bash
docker compose down -v
```
## Troubleshooting
**Permission denied errors on /logs**
The docker-compose file includes an initialization container that automatically fixes volume permissions. If you still see errors like `open /logs/osqueryd.status.log: permission denied`, try:
```bash
docker compose down
docker compose up -d
```
This restarts the initialization process.
**Fleet won't start**
Check that all required environment variables are set in your `.env` file. The `FLEET_SERVER_PRIVATE_KEY` must be a valid base64 string.
**Can't access the web UI**
Verify Fleet is running:
```bash
docker compose ps fleet
```
Check that port 1337 isn't blocked by your firewall.
If using TLS, verify your certificates exist in the `./certs` directory and are readable.
**Certificate errors**
If you see certificate-related errors in the logs, verify:
```bash
ls -l certs/
```
Both `fleet.crt` and `fleet.key` should exist and be readable. If using Option 1 (reverse proxy), make sure `FLEET_SERVER_TLS=false` in your `.env` file.
If using self-signed certificates, devices need the certificate installed or TLS verification disabled (not recommended for production).
## Production considerations
This deployment works well for testing and small fleets. For production use with many devices:
- Use a managed MySQL database (AWS RDS, Google Cloud SQL)
- Use a managed Redis instance (AWS ElastiCache, Google Memorystore)
- Run multiple Fleet containers behind a load balancer
- Use certificates from a trusted certificate authority
- Pin container versions in docker-compose.yml
- Enable automatic backups
- Monitor resource usage
- Set up log forwarding to a centralized logging system
See Fleet's [Reference configuration strategies](https://fleetdm.com/docs/deploy/reference-architectures#reference-configuration-strategies) for production best practices.
<metaname="articleTitle"value="Deploy Fleet with Docker Compose">
<metaname="authorGitHubUsername"value="kitzy">
<metaname="authorFullName"value="Kitzy">
<metaname="publishedOn"value="2025-12-01">
<metaname="category"value="guides">
<metaname="description"value="Learn how to deploy Fleet using Docker Compose.">