Affine Pro
Affine Pro is a modern, self-hosted platform designed for collaborative content creation and project management. It offers an intuitive interface, seamless real-time collaboration, and powerful tools for organizing tasks, notes, and ideas.
Configuration
version: "3.8"
services:
affinepro:
image: ghcr.io/toeverything/affine:stable
restart: unless-stopped
ports:
- 3010
volumes:
- affine-storage:/root/.affine/storage
- affine-config:/root/.affine/config
environment:
- REDIS_SERVER_HOST=redis
- REDIS_SERVER_PASSWORD=${REDIS_PASSWORD}
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/affinepro
- AFFINE_INDEXER_ENABLED=false
- AFFINE_SERVER_HOST=${DOMAIN}
- MAILER_HOST=${MAILER_HOST}
- MAILER_PORT=${MAILER_PORT}
- MAILER_USER=${MAILER_USER}
- MAILER_PASSWORD=${MAILER_PASSWORD}
- MAILER_SENDER=${MAILER_SENDER}
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
migration:
condition: service_completed_successfully
migration:
image: ghcr.io/toeverything/affine:stable
command: ["sh", "-c", "node ./scripts/self-host-predeploy.js"]
environment:
- REDIS_SERVER_HOST=redis
- REDIS_SERVER_PASSWORD=${REDIS_PASSWORD}
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/affinepro
- AFFINE_INDEXER_ENABLED=false
- AFFINE_SERVER_HOST=${DOMAIN}
- MAILER_HOST=${MAILER_HOST}
- MAILER_PORT=${MAILER_PORT}
- MAILER_USER=${MAILER_USER}
- MAILER_PASSWORD=${MAILER_PASSWORD}
- MAILER_SENDER=${MAILER_SENDER}
volumes:
- affine-storage:/root/.affine/storage
- affine-config:/root/.affine/config
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
db:
image: pgvector/pgvector:pg16
restart: unless-stopped
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=affinepro
- POSTGRES_INITDB_ARGS=--data-checksums
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "affinepro"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis-data:/data
healthcheck:
test: ["CMD-SHELL", "redis-cli -a '${REDIS_PASSWORD}' ping | grep PONG"]
interval: 10s
timeout: 5s
retries: 5
volumes:
affine-storage: {}
affine-config: {}
postgres-data: {}
redis-data: {}[variables]
main_domain = "${domain}"
postgres_password = "${password:16}"
redis_password = "${password:16}"
mailer_host = ""
mailer_port = "587"
mailer_user = ""
mailer_password = ""
mailer_sender = ""
[config]
[[config.domains]]
serviceName = "affinepro"
port = 3010
host = "${main_domain}"
[config.env]
DOMAIN = "${main_domain}"
POSTGRES_PASSWORD = "${postgres_password}"
REDIS_PASSWORD = "${redis_password}"
MAILER_HOST = "${mailer_host}"
MAILER_PORT = "${mailer_port}"
MAILER_USER = "${mailer_user}"
MAILER_PASSWORD = "${mailer_password}"
MAILER_SENDER = "${mailer_sender}"Base64
To import this template in Dokploy: create a Compose service → Advanced → Base64 import and paste the content below:
ewogICJjb21wb3NlIjogInZlcnNpb246IFwiMy44XCJcbnNlcnZpY2VzOlxuICBhZmZpbmVwcm86XG4gICAgaW1hZ2U6IGdoY3IuaW8vdG9ldmVyeXRoaW5nL2FmZmluZTpzdGFibGVcbiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZFxuICAgIHBvcnRzOlxuICAgICAgLSAzMDEwXG4gICAgdm9sdW1lczpcbiAgICAgIC0gYWZmaW5lLXN0b3JhZ2U6L3Jvb3QvLmFmZmluZS9zdG9yYWdlXG4gICAgICAtIGFmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWdcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXNcbiAgICAgIC0gUkVESVNfU0VSVkVSX1BBU1NXT1JEPSR7UkVESVNfUEFTU1dPUkR9XG4gICAgICAtIERBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtQT1NUR1JFU19QQVNTV09SRH1AZGI6NTQzMi9hZmZpbmVwcm9cbiAgICAgIC0gQUZGSU5FX0lOREVYRVJfRU5BQkxFRD1mYWxzZVxuICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JHtET01BSU59XG4gICAgICAtIE1BSUxFUl9IT1NUPSR7TUFJTEVSX0hPU1R9XG4gICAgICAtIE1BSUxFUl9QT1JUPSR7TUFJTEVSX1BPUlR9XG4gICAgICAtIE1BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9XG4gICAgICAtIE1BSUxFUl9QQVNTV09SRD0ke01BSUxFUl9QQVNTV09SRH1cbiAgICAgIC0gTUFJTEVSX1NFTkRFUj0ke01BSUxFUl9TRU5ERVJ9XG4gICAgZGVwZW5kc19vbjpcbiAgICAgIGRiOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgcmVkaXM6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgICBtaWdyYXRpb246XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5XG5cbiAgbWlncmF0aW9uOlxuICAgIGltYWdlOiBnaGNyLmlvL3RvZXZlcnl0aGluZy9hZmZpbmU6c3RhYmxlXG4gICAgY29tbWFuZDogW1wic2hcIiwgXCItY1wiLCBcIm5vZGUgLi9zY3JpcHRzL3NlbGYtaG9zdC1wcmVkZXBsb3kuanNcIl1cbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXNcbiAgICAgIC0gUkVESVNfU0VSVkVSX1BBU1NXT1JEPSR7UkVESVNfUEFTU1dPUkR9XG4gICAgICAtIERBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtQT1NUR1JFU19QQVNTV09SRH1AZGI6NTQzMi9hZmZpbmVwcm9cbiAgICAgIC0gQUZGSU5FX0lOREVYRVJfRU5BQkxFRD1mYWxzZVxuICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JHtET01BSU59XG4gICAgICAtIE1BSUxFUl9IT1NUPSR7TUFJTEVSX0hPU1R9XG4gICAgICAtIE1BSUxFUl9QT1JUPSR7TUFJTEVSX1BPUlR9XG4gICAgICAtIE1BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9XG4gICAgICAtIE1BSUxFUl9QQVNTV09SRD0ke01BSUxFUl9QQVNTV09SRH1cbiAgICAgIC0gTUFJTEVSX1NFTkRFUj0ke01BSUxFUl9TRU5ERVJ9XG4gICAgdm9sdW1lczpcbiAgICAgIC0gYWZmaW5lLXN0b3JhZ2U6L3Jvb3QvLmFmZmluZS9zdG9yYWdlXG4gICAgICAtIGFmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWdcbiAgICBkZXBlbmRzX29uOlxuICAgICAgZGI6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgICByZWRpczpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHlcblxuICBkYjpcbiAgICBpbWFnZTogcGd2ZWN0b3IvcGd2ZWN0b3I6cGcxNlxuICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSR7UE9TVEdSRVNfUEFTU1dPUkR9XG4gICAgICAtIFBPU1RHUkVTX0RCPWFmZmluZXByb1xuICAgICAgLSBQT1NUR1JFU19JTklUREJfQVJHUz0tLWRhdGEtY2hlY2tzdW1zXG4gICAgdm9sdW1lczpcbiAgICAgIC0gcG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGFcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFtcIkNNRFwiLCBcInBnX2lzcmVhZHlcIiwgXCItVVwiLCBcInBvc3RncmVzXCIsIFwiLWRcIiwgXCJhZmZpbmVwcm9cIl1cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG5cbiAgcmVkaXM6XG4gICAgaW1hZ2U6IHJlZGlzOjctYWxwaW5lXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBjb21tYW5kOiByZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAke1JFRElTX1BBU1NXT1JEfVxuICAgIHZvbHVtZXM6XG4gICAgICAtIHJlZGlzLWRhdGE6L2RhdGFcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFtcIkNNRC1TSEVMTFwiLCBcInJlZGlzLWNsaSAtYSAnJHtSRURJU19QQVNTV09SRH0nIHBpbmcgfCBncmVwIFBPTkdcIl1cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG5cbnZvbHVtZXM6XG4gIGFmZmluZS1zdG9yYWdlOiB7fVxuICBhZmZpbmUtY29uZmlnOiB7fVxuICBwb3N0Z3Jlcy1kYXRhOiB7fVxuICByZWRpcy1kYXRhOiB7fVxuIiwKICAiY29uZmlnIjogIlt2YXJpYWJsZXNdXG5tYWluX2RvbWFpbiA9IFwiJHtkb21haW59XCJcbnBvc3RncmVzX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkOjE2fVwiXG5yZWRpc19wYXNzd29yZCA9IFwiJHtwYXNzd29yZDoxNn1cIlxubWFpbGVyX2hvc3QgPSBcIlwiXG5tYWlsZXJfcG9ydCA9IFwiNTg3XCJcbm1haWxlcl91c2VyID0gXCJcIlxubWFpbGVyX3Bhc3N3b3JkID0gXCJcIlxubWFpbGVyX3NlbmRlciA9IFwiXCJcblxuW2NvbmZpZ11cbltbY29uZmlnLmRvbWFpbnNdXVxuc2VydmljZU5hbWUgPSBcImFmZmluZXByb1wiXG5wb3J0ID0gMzAxMFxuaG9zdCA9IFwiJHttYWluX2RvbWFpbn1cIlxuXG5bY29uZmlnLmVudl1cbkRPTUFJTiA9IFwiJHttYWluX2RvbWFpbn1cIlxuUE9TVEdSRVNfUEFTU1dPUkQgPSBcIiR7cG9zdGdyZXNfcGFzc3dvcmR9XCJcblJFRElTX1BBU1NXT1JEID0gXCIke3JlZGlzX3Bhc3N3b3JkfVwiXG5NQUlMRVJfSE9TVCA9IFwiJHttYWlsZXJfaG9zdH1cIlxuTUFJTEVSX1BPUlQgPSBcIiR7bWFpbGVyX3BvcnR9XCJcbk1BSUxFUl9VU0VSID0gXCIke21haWxlcl91c2VyfVwiXG5NQUlMRVJfUEFTU1dPUkQgPSBcIiR7bWFpbGVyX3Bhc3N3b3JkfVwiXG5NQUlMRVJfU0VOREVSID0gXCIke21haWxlcl9zZW5kZXJ9XCIgIgp9Links
Tags
collaboration, self-hosted, productivity, project-management
Version: stable