Skip to content

Docker AIO (All-in-One) Commercial Edition ​

Not for production

Use Docker AIO only to evaluate Plane or run a proof of concept. For production instances, deploy with Docker Compose or Kubernetes.

AIO runs every Plane service in one container, so you can't scale, restart, or upgrade services independently, and a problem in one service affects the whole instance.

The Plane Commercial All-in-One (AIO) Docker image packages all Plane services into a single container. It's the fastest way to try Plane.

What's included ​

Your single AIO container includes all these services running together:

  • Web App - The main Plane web interface you'll use
  • Space - Public project spaces for external collaboration
  • Admin - Administrative interface
  • API Server - Backend API
  • Live Server - Real-time collaboration features
  • Silo - Integration services
  • Monitor - Feature flags and payments
  • Email Server - SMTP server for notifications
  • Proxy (Port 80, 20025, 20465, 20587) - Caddy reverse proxy
  • Worker and Beat Worker - Background task processing

Port Mapping ​

The following ports are exposed:

  • 80: Main web interface (HTTP)
  • 443: HTTPS (if SSL configured)
  • 20025: SMTP port 25
  • 20465: SMTP port 465 (SSL/TLS)
  • 20587: SMTP port 587 (STARTTLS)

Prerequisites ​

  • Docker
  • Set up these external services:
    • PostgreSQL
      For data storage
    • Redis
      For caching and session management
    • RabbitMQ For message queuing
    • S3-compatible storage
      For file uploads (AWS S3 or MinIO)

Install Plane ​

  1. Download the image with:

    bash
    docker pull makeplane/plane-aio-commercial:stable
  2. Run the following command to deploy the Plane AIO container. Make sure to replace all placeholder values (e.g., your-domain.com, user:pass) with your actual configuration.

    WARNING

    All environment variables are required for the container to function correctly.

    bash
    docker run --name plane-aio --rm -it \
        -p 80:80 \
        -p 20025:20025 \
        -p 20465:20465 \
        -p 20587:20587 \
        -e DOMAIN_NAME=your-domain.com \
        -e DATABASE_URL=postgresql://user:pass@host:port/database \
        -e REDIS_URL=redis://host:port \
        -e AMQP_URL=amqp://user:pass@host:port/vhost \
        -e AWS_REGION=us-east-1 \
        -e AWS_ACCESS_KEY_ID=your-access-key \
        -e AWS_SECRET_ACCESS_KEY=your-secret-key \
        -e AWS_S3_BUCKET_NAME=your-bucket \
        makeplane/plane-aio-commercial:stable

    If you're running on an IP address, use this example:

    bash
    MYIP=192.168.68.169
    docker run --name myaio --rm -it \
    -p 80:80 \
    -p 20025:20025 \
    -p 20465:20465 \
    -p 20587:20587 \
    -e DOMAIN_NAME=${MYIP} \
    -e DATABASE_URL=postgresql://plane:plane@${MYIP}:15432/plane \
    -e REDIS_URL=redis://${MYIP}:16379 \
    -e AMQP_URL=amqp://plane:plane@${MYIP}:15673/plane \
    -e AWS_REGION=us-east-1 \
    -e AWS_ACCESS_KEY_ID=<YOUR_AWS_ACCESS_KEY_ID> \
    -e AWS_SECRET_ACCESS_KEY=<YOUR_AWS_SECRET_ACCESS_KEY> \
    -e AWS_S3_BUCKET_NAME=plane-app \
    -e AWS_S3_ENDPOINT_URL=http://${MYIP}:19000 \
    -e FILE_SIZE_LIMIT=10485760 \
    makeplane/plane-aio-commercial:stable

    You can also keep your values in a file and pass it with --env-file. With the current stable image, values you pass with -e or --env-file always take precedence over the defaults built into the image. Older images could replace some of them, such as the Slack credentials, with empty defaults. The image still sets its own version and the addresses its internal services use to reach each other.

  3. Once it's running, you can access the Plane application on the domain you provided during the deployment.

  4. If you've purchased a paid plan, activate your license key to unlock premium features.

Volume mounts ​

bash
-v /path/to/logs:/app/logs \
-v /path/to/data:/app/data

Keep /app/data mounted. Your license is bound to the instance's MACHINE_SIGNATURE. With the current stable image, if you don't set MACHINE_SIGNATURE, the container generates one and stores it in /app/data, so it reuses the same signature when you recreate the container. Without the volume, a recreated container gets a new signature. To avoid depending on the volume, set MACHINE_SIGNATURE yourself. See Security and secrets.

Workspace license DB ​

bash
-v /path/to/monitordb:/app/monitor

SSL certificate support ​

For HTTPS support, mount certificates:

bash
-v /path/to/certs:/app/email/tls

Environment variables (optional) ​

Network and Protocol ​

  • SITE_ADDRESS: Server bind address (default: :80)
  • APP_PROTOCOL: Protocol to use (http or https, default: http)

Email configuration ​

  • INTAKE_EMAIL_DOMAIN: Domain for intake emails (default: intake.<DOMAIN_NAME>)
  • LISTEN_SMTP_PORT_25: SMTP port 25 mapping (default: 20025)
  • LISTEN_SMTP_PORT_465: SMTP port 465 mapping (default: 20465)
  • LISTEN_SMTP_PORT_587: SMTP port 587 mapping (default: 20587)
  • SMTP_DOMAIN: SMTP server domain (default: 0.0.0.0)
  • TLS_CERT_PATH: Path to TLS certificate file (optional)
  • TLS_PRIV_KEY_PATH: Path to TLS private key file (optional)

Licensing ​

  • PRIME_HOST: License server URL (default: https://prime.plane.so). Set it only for an air-gapped or custom license server.

Security and secrets ​

  • MACHINE_SIGNATURE: Unique machine identifier that your license is bound to. Use at least 24 characters, made of letters, digits, -, or _, such as the output of uuidgen. If you don't set it, the container generates one and stores it in /app/data. A value that doesn't meet these rules is ignored with a warning in the container log.
  • SECRET_KEY: Django secret key (default provided)
  • SILO_HMAC_SECRET_KEY: Silo HMAC secret (default provided)
  • AES_SECRET_KEY: AES encryption key for stored integration credentials (default provided)
  • LIVE_SERVER_SECRET_KEY: Live server secret (default provided)

The container logs a warning at startup when any of SECRET_KEY, SILO_HMAC_SECRET_KEY, AES_SECRET_KEY, or LIVE_SERVER_SECRET_KEY uses the default value shipped with the image. Set unique values for all four when you create a new instance. For example, generate each one with openssl rand -hex 32.

On an existing instance:

  • You can change SECRET_KEY. All users are signed out.
  • Don't change AES_SECRET_KEY. It encrypts the integration credentials stored in the database, and a new value makes them unreadable.

Webhooks ​

  • WEBHOOK_ALLOWED_HOSTS: Comma-separated hostnames, not URLs, that webhooks may target even when they resolve to a private IP address. When it's not set and DOMAIN_NAME is a domain name, it defaults to DOMAIN_NAME, so Plane's own integrations, such as Slack, can receive webhook deliveries on your instance. There's no default when DOMAIN_NAME is localhost or an IP address, because listed hosts bypass the private-network check.

File handling ​

  • FILE_SIZE_LIMIT: Maximum file upload size in bytes (default: 5242880 = 5MB)

Integration callbacks ​

  • INTEGRATION_CALLBACK_BASE_URL: Base URL that integrations such as Slack, GitHub, and GitLab use for OAuth callbacks and webhooks, with protocol, for example https://plane.example.com (default: APP_PROTOCOL://DOMAIN_NAME). Set it only when integrations must reach Plane at a different address than your users do.

API configuration ​

  • API_KEY_RATE_LIMIT: API key rate limit (default: 60/minute)

Third-party integrations ​

  • GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET: GitHub integration
  • GITHUB_APP_NAME, GITHUB_APP_ID, GITHUB_PRIVATE_KEY: GitHub App integration. Set GITHUB_APP_NAME to the app's slug, the last part of its public URL https://github.com/apps/<slug>, not its display name. See Configure GitHub.
  • SLACK_CLIENT_ID, SLACK_CLIENT_SECRET: Slack integration
  • GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET: GitLab integration

Build the image ​

To build the AIO image yourself:

bash
cd deploy/aio/commercial
./build.sh --release=v1.11.1

Available build options:

  • --release: Plane version to build (required)
  • --image-name: Custom image name (default: plane-aio-commercial)

Troubleshoot ​

The container will validate required environment variables on startup and display helpful error messages if any are missing.

Logs ​

All service logs are available in /app/logs/:

  • Access logs: /app/logs/access/
  • Error logs: /app/logs/error/

Health checks ​

The container runs multiple services managed by Supervisor. Check service status:

bash
docker exec -it <container-name> supervisorctl status

Move to production ​

Docker AIO isn't supported for production. When you're ready to run Plane for your team, deploy with Docker Compose or Kubernetes.