Skip to content

docs: Add comprehensive Dokploy deployment guide for Plane#8605

Open
andyng2410 wants to merge 1 commit intomakeplane:previewfrom
andyng2410:claude/dokploy-deployment-guide-0jy2D
Open

docs: Add comprehensive Dokploy deployment guide for Plane#8605
andyng2410 wants to merge 1 commit intomakeplane:previewfrom
andyng2410:claude/dokploy-deployment-guide-0jy2D

Conversation

@andyng2410
Copy link

@andyng2410 andyng2410 commented Feb 2, 2026

Description

This PR adds a comprehensive Vietnamese deployment guide for deploying Plane on Dokploy. The guide covers three different deployment approaches with detailed step-by-step instructions, environment configuration, troubleshooting, and best practices.

The document (deployments/dokploy/DEPLOY.md) includes:

  1. Architecture Overview - Complete service breakdown with ports and descriptions

  2. Three Deployment Methods:

    • Docker Compose (recommended) - Using the project's native docker-compose.yml
    • AIO (All-In-One) Image - Simplified single-image deployment with external services
    • Pre-built Images Compose - Using pre-built images without building from source
  3. Detailed Configuration:

    • Environment variables for all services
    • Database, Redis, RabbitMQ, and MinIO setup
    • Domain and SSL configuration with Traefik
    • API environment file handling strategies
  4. Operational Guidance:

    • Resource requirements
    • Post-deployment verification steps
    • Troubleshooting common issues
    • Version update procedures

Type of Change

  • Documentation update

Key Features

  • No project modifications required - All configuration happens within Dokploy
  • Multiple deployment options - Caters to different infrastructure needs
  • Comprehensive troubleshooting - Covers common deployment issues
  • Security considerations - Guidance on handling secrets and credentials
  • Vietnamese language - Accessible to Vietnamese-speaking developers

Test Scenarios

This is a documentation-only change. The guide has been structured to be:

  • Clear and actionable with step-by-step instructions
  • Technically accurate based on Plane's architecture
  • Practical with real configuration examples
  • Comprehensive with multiple deployment strategies

References

https://claude.ai/code/session_01CTtRjowgPvFWBCESwRbHRx

Summary by CodeRabbit

  • Documentation
    • Added comprehensive deployment guide covering system architecture, three deployment options with step-by-step instructions, environment configuration, domain and SSL setup, troubleshooting, and version update workflows.

Add comprehensive guide for deploying Plane on Dokploy with 3 approaches:
- Docker Compose from Git repo (recommended)
- AIO (All-In-One) pre-built image
- Compose with pre-built images (no build required)

https://claude.ai/code/session_01CTtRjowgPvFWBCESwRbHRx
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

A new comprehensive deployment guide for Plane on Dokploy is introduced, documenting system architecture, three deployment options (Docker Compose via Dokploy, AIO image, and pre-built images), environment configuration, domain setup with Traefik, troubleshooting procedures, and version update workflows.

Changes

Cohort / File(s) Summary
Dokploy Deployment Documentation
deployments/dokploy/DEPLOY.md
New comprehensive guide covering Plane deployment on Dokploy, including architecture overview, three deployment strategies with step-by-step instructions, environment variable configurations, SSL/domain setup via Traefik, troubleshooting guidance, and version update procedures.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~12 minutes

Poem

🐰 A guide hops forth with clear delight,
Dokploy paths now shining bright,
From Docker swarms to domains so fine,
Deployment steps in perfect line,
Plane soars high—no clouds to fight! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding a comprehensive Dokploy deployment guide for Plane, which matches the changeset perfectly.
Description check ✅ Passed The description follows the template structure with detailed information in all required sections: Description, Type of Change (marked as Documentation update), and References provided.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@deployments/dokploy/DEPLOY.md`:
- Around line 132-133: Add a short guidance block under the SECRET_KEY and
LIVE_SERVER_SECRET_KEY entries explaining how to generate cryptographically
secure keys; mention using Django's get_random_secret_key (via a small python
one-liner) and an alternative using openssl rand -base64 50, and note that keys
should be at least 50 random characters and kept secret—update the DEPLOY.md
text around the SECRET_KEY and LIVE_SERVER_SECRET_KEY references to include this
guidance.
- Around line 493-494: Add explicit guidance beside the SECRET_KEY and
LIVE_SERVER_SECRET_KEY examples: explain they must be cryptographically secure
random strings (suggest length e.g., 50+ chars), show secure generation commands
(for example use openssl rand -base64 50 or Python: python -c "import secrets;
print(secrets.token_urlsafe(50))"), instruct readers to store them in
environment variables or a .env file and never commit them to source control,
and note that LIVE_SERVER_SECRET_KEY should be different from SECRET_KEY and
kept secret for production use; update the text around the SECRET_KEY and
LIVE_SERVER_SECRET_KEY examples accordingly.
- Line 211: Replace the floating tag `:latest` on the Plane image reference
`artifacts.plane.so/makeplane/plane-aio-community:latest` with a pinned tag
(e.g., `:stable` or a specific semver like `:v1.2.0`) and do the same for all
other image references in the pre-built compose section (the referenced
pre-built compose image list) so every container image uses a fixed version;
update deployment docs/examples to show the pinned tag and mention how to
choose/update the pinned version.
🧹 Nitpick comments (2)
deployments/dokploy/DEPLOY.md (2)

10-10: Optional: Fix table formatting for consistency.

The table has spacing inconsistencies around the pipe separators. Consider adjusting for better formatting compliance.

✨ Proposed formatting fix
-|---------|--------|-------------|
+| ------- | ------ | ----------- |

Apply similar spacing to line 527 as well.


189-193: Add language identifier to code block.

For better syntax highlighting and clarity, specify bash as the language identifier.

✨ Proposed fix
-  ```
+  ```bash
   RABBITMQ_DEFAULT_USER=plane

Apply similarly to code blocks at lines 200 and 514.

Comment on lines +132 to +133
- SECRET_KEY=<django-secret-key-ngẫu-nhiên-50-ký-tự>
- LIVE_SERVER_SECRET_KEY=<random-key>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add guidance for generating SECRET_KEY.

The documentation references SECRET_KEY and LIVE_SERVER_SECRET_KEY but doesn't provide instructions for generating cryptographically secure values. Django's SECRET_KEY should be a random string of at least 50 characters.

📝 Suggested addition

Consider adding a note like:

> **Tạo SECRET_KEY an toàn:**
> ```bash
> python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
> ```
> hoặc dùng: `openssl rand -base64 50`
🤖 Prompt for AI Agents
In `@deployments/dokploy/DEPLOY.md` around lines 132 - 133, Add a short guidance
block under the SECRET_KEY and LIVE_SERVER_SECRET_KEY entries explaining how to
generate cryptographically secure keys; mention using Django's
get_random_secret_key (via a small python one-liner) and an alternative using
openssl rand -base64 50, and note that keys should be at least 50 random
characters and kept secret—update the DEPLOY.md text around the SECRET_KEY and
LIVE_SERVER_SECRET_KEY references to include this guidance.


1. Trong project, nhấn **+ Add Service** → **Docker**
2. Chọn source: **Docker Image**
3. Image: `artifacts.plane.so/makeplane/plane-aio-community:latest`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Recommend version pinning instead of :latest tag.

Using :latest tag for production deployments can lead to unpredictable behavior, breaking changes, and difficult rollbacks. Consider specifying a stable version tag.

Example:

image: artifacts.plane.so/makeplane/plane-aio-community:stable
# or a specific version like:
image: artifacts.plane.so/makeplane/plane-aio-community:v1.2.0

This same concern applies to all image references in the pre-built compose approach (lines 253-458).

🤖 Prompt for AI Agents
In `@deployments/dokploy/DEPLOY.md` at line 211, Replace the floating tag
`:latest` on the Plane image reference
`artifacts.plane.so/makeplane/plane-aio-community:latest` with a pinned tag
(e.g., `:stable` or a specific semver like `:v1.2.0`) and do the same for all
other image references in the pre-built compose section (the referenced
pre-built compose image list) so every container image uses a fixed version;
update deployment docs/examples to show the pinned tag and mention how to
choose/update the pinned version.

Comment on lines +253 to +458
image: artifacts.plane.so/makeplane/plane-frontend:latest
restart: always
depends_on:
- api

admin:
image: artifacts.plane.so/makeplane/plane-admin:latest
restart: always
depends_on:
- api

space:
image: artifacts.plane.so/makeplane/plane-space:latest
restart: always
depends_on:
- api

api:
image: artifacts.plane.so/makeplane/plane-backend:latest
restart: always
command: ./bin/docker-entrypoint-api.sh
environment:
- DEBUG=0
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_HOST=plane-db
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_PORT=5432
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@plane-db:5432/${POSTGRES_DB}
- REDIS_HOST=plane-redis
- REDIS_PORT=6379
- REDIS_URL=redis://plane-redis:6379/
- RABBITMQ_HOST=plane-mq
- RABBITMQ_PORT=5672
- RABBITMQ_USER=${RABBITMQ_USER}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
- RABBITMQ_VHOST=${RABBITMQ_VHOST}
- SECRET_KEY=${SECRET_KEY}
- LIVE_SERVER_SECRET_KEY=${LIVE_SERVER_SECRET_KEY}
- AWS_REGION=${AWS_REGION}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- AWS_S3_ENDPOINT_URL=http://plane-minio:9000
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME}
- FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT}
- USE_MINIO=1
- MINIO_ENDPOINT_SSL=0
- WEB_URL=${WEB_URL}
- CORS_ALLOWED_ORIGINS=${WEB_URL}
- GUNICORN_WORKERS=2
- API_KEY_RATE_LIMIT=${API_KEY_RATE_LIMIT}
depends_on:
- plane-db
- plane-redis

worker:
image: artifacts.plane.so/makeplane/plane-backend:latest
restart: always
command: ./bin/docker-entrypoint-worker.sh
environment:
- DEBUG=0
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_HOST=plane-db
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_PORT=5432
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@plane-db:5432/${POSTGRES_DB}
- REDIS_HOST=plane-redis
- REDIS_PORT=6379
- REDIS_URL=redis://plane-redis:6379/
- RABBITMQ_HOST=plane-mq
- RABBITMQ_PORT=5672
- RABBITMQ_USER=${RABBITMQ_USER}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
- RABBITMQ_VHOST=${RABBITMQ_VHOST}
- SECRET_KEY=${SECRET_KEY}
- LIVE_SERVER_SECRET_KEY=${LIVE_SERVER_SECRET_KEY}
- AWS_REGION=${AWS_REGION}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- AWS_S3_ENDPOINT_URL=http://plane-minio:9000
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME}
- FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT}
- USE_MINIO=1
- MINIO_ENDPOINT_SSL=0
- WEB_URL=${WEB_URL}
- GUNICORN_WORKERS=2
- API_KEY_RATE_LIMIT=${API_KEY_RATE_LIMIT}
depends_on:
- api
- plane-db
- plane-redis

beat-worker:
image: artifacts.plane.so/makeplane/plane-backend:latest
restart: always
command: ./bin/docker-entrypoint-beat.sh
environment:
- DEBUG=0
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_HOST=plane-db
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_PORT=5432
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@plane-db:5432/${POSTGRES_DB}
- REDIS_HOST=plane-redis
- REDIS_PORT=6379
- REDIS_URL=redis://plane-redis:6379/
- RABBITMQ_HOST=plane-mq
- RABBITMQ_PORT=5672
- RABBITMQ_USER=${RABBITMQ_USER}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
- RABBITMQ_VHOST=${RABBITMQ_VHOST}
- SECRET_KEY=${SECRET_KEY}
- LIVE_SERVER_SECRET_KEY=${LIVE_SERVER_SECRET_KEY}
- AWS_REGION=${AWS_REGION}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- AWS_S3_ENDPOINT_URL=http://plane-minio:9000
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME}
- FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT}
- USE_MINIO=1
- MINIO_ENDPOINT_SSL=0
- WEB_URL=${WEB_URL}
- GUNICORN_WORKERS=2
- API_KEY_RATE_LIMIT=${API_KEY_RATE_LIMIT}
depends_on:
- api
- plane-db
- plane-redis

migrator:
image: artifacts.plane.so/makeplane/plane-backend:latest
restart: "no"
command: ./bin/docker-entrypoint-migrator.sh
environment:
- DEBUG=0
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_HOST=plane-db
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_PORT=5432
- DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@plane-db:5432/${POSTGRES_DB}
- REDIS_HOST=plane-redis
- REDIS_PORT=6379
- REDIS_URL=redis://plane-redis:6379/
- RABBITMQ_HOST=plane-mq
- RABBITMQ_PORT=5672
- RABBITMQ_USER=${RABBITMQ_USER}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
- RABBITMQ_VHOST=${RABBITMQ_VHOST}
- SECRET_KEY=${SECRET_KEY}
- AWS_REGION=${AWS_REGION}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- AWS_S3_ENDPOINT_URL=http://plane-minio:9000
- AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME}
- USE_MINIO=1
depends_on:
- plane-db
- plane-redis

live:
image: artifacts.plane.so/makeplane/plane-live:latest
restart: always

plane-db:
image: postgres:15.7-alpine
restart: always
command: postgres -c 'max_connections=1000'
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
PGDATA: /var/lib/postgresql/data

plane-redis:
image: valkey/valkey:7.2.11-alpine
restart: always
volumes:
- redisdata:/data

plane-mq:
image: rabbitmq:3.13.6-management-alpine
restart: always
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST}
volumes:
- rabbitmq_data:/var/lib/rabbitmq

plane-minio:
image: minio/minio
restart: always
command: server /export --console-address ":9090"
volumes:
- uploads:/export
environment:
MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID}
MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY}

proxy:
image: artifacts.plane.so/makeplane/plane-proxy:latest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Version pinning recommended for all Docker images.

All services in this compose file use :latest tags, which is not recommended for production deployments. This creates several risks:

  • Reproducibility: Deployments at different times may pull different versions
  • Stability: Automatic updates may introduce breaking changes
  • Rollback difficulty: Hard to revert to a known-good state

Consider adding a note recommending users replace :latest with specific version tags (e.g., v1.2.0 or stable) for all images:

  • plane-frontend:latest
  • plane-admin:latest
  • plane-space:latest
  • plane-backend:latest
  • plane-live:latest
  • plane-proxy:latest

Infrastructure images (postgres, valkey, rabbitmq, minio) are already pinned, which is good practice.

Comment on lines +493 to +494
SECRET_KEY=<random-50-char-string>
LIVE_SERVER_SECRET_KEY=<random-string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

SECRET_KEY generation guidance needed here too.

Same as the earlier comment on lines 132-133: provide users with instructions for generating cryptographically secure SECRET_KEY values. This is especially important since this section may be read independently of the Docker Compose approach.

🤖 Prompt for AI Agents
In `@deployments/dokploy/DEPLOY.md` around lines 493 - 494, Add explicit guidance
beside the SECRET_KEY and LIVE_SERVER_SECRET_KEY examples: explain they must be
cryptographically secure random strings (suggest length e.g., 50+ chars), show
secure generation commands (for example use openssl rand -base64 50 or Python:
python -c "import secrets; print(secrets.token_urlsafe(50))"), instruct readers
to store them in environment variables or a .env file and never commit them to
source control, and note that LIVE_SERVER_SECRET_KEY should be different from
SECRET_KEY and kept secret for production use; update the text around the
SECRET_KEY and LIVE_SERVER_SECRET_KEY examples accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants