Dokploy

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.

Affine Pro logo

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 → AdvancedBase64 import and paste the content below:

ewogICJjb21wb3NlIjogInZlcnNpb246IFwiMy44XCJcbnNlcnZpY2VzOlxuICBhZmZpbmVwcm86XG4gICAgaW1hZ2U6IGdoY3IuaW8vdG9ldmVyeXRoaW5nL2FmZmluZTpzdGFibGVcbiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZFxuICAgIHBvcnRzOlxuICAgICAgLSAzMDEwXG4gICAgdm9sdW1lczpcbiAgICAgIC0gYWZmaW5lLXN0b3JhZ2U6L3Jvb3QvLmFmZmluZS9zdG9yYWdlXG4gICAgICAtIGFmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWdcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXNcbiAgICAgIC0gUkVESVNfU0VSVkVSX1BBU1NXT1JEPSR7UkVESVNfUEFTU1dPUkR9XG4gICAgICAtIERBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtQT1NUR1JFU19QQVNTV09SRH1AZGI6NTQzMi9hZmZpbmVwcm9cbiAgICAgIC0gQUZGSU5FX0lOREVYRVJfRU5BQkxFRD1mYWxzZVxuICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JHtET01BSU59XG4gICAgICAtIE1BSUxFUl9IT1NUPSR7TUFJTEVSX0hPU1R9XG4gICAgICAtIE1BSUxFUl9QT1JUPSR7TUFJTEVSX1BPUlR9XG4gICAgICAtIE1BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9XG4gICAgICAtIE1BSUxFUl9QQVNTV09SRD0ke01BSUxFUl9QQVNTV09SRH1cbiAgICAgIC0gTUFJTEVSX1NFTkRFUj0ke01BSUxFUl9TRU5ERVJ9XG4gICAgZGVwZW5kc19vbjpcbiAgICAgIGRiOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgcmVkaXM6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgICBtaWdyYXRpb246XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5XG5cbiAgbWlncmF0aW9uOlxuICAgIGltYWdlOiBnaGNyLmlvL3RvZXZlcnl0aGluZy9hZmZpbmU6c3RhYmxlXG4gICAgY29tbWFuZDogW1wic2hcIiwgXCItY1wiLCBcIm5vZGUgLi9zY3JpcHRzL3NlbGYtaG9zdC1wcmVkZXBsb3kuanNcIl1cbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXNcbiAgICAgIC0gUkVESVNfU0VSVkVSX1BBU1NXT1JEPSR7UkVESVNfUEFTU1dPUkR9XG4gICAgICAtIERBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtQT1NUR1JFU19QQVNTV09SRH1AZGI6NTQzMi9hZmZpbmVwcm9cbiAgICAgIC0gQUZGSU5FX0lOREVYRVJfRU5BQkxFRD1mYWxzZVxuICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JHtET01BSU59XG4gICAgICAtIE1BSUxFUl9IT1NUPSR7TUFJTEVSX0hPU1R9XG4gICAgICAtIE1BSUxFUl9QT1JUPSR7TUFJTEVSX1BPUlR9XG4gICAgICAtIE1BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9XG4gICAgICAtIE1BSUxFUl9QQVNTV09SRD0ke01BSUxFUl9QQVNTV09SRH1cbiAgICAgIC0gTUFJTEVSX1NFTkRFUj0ke01BSUxFUl9TRU5ERVJ9XG4gICAgdm9sdW1lczpcbiAgICAgIC0gYWZmaW5lLXN0b3JhZ2U6L3Jvb3QvLmFmZmluZS9zdG9yYWdlXG4gICAgICAtIGFmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWdcbiAgICBkZXBlbmRzX29uOlxuICAgICAgZGI6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgICByZWRpczpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHlcblxuICBkYjpcbiAgICBpbWFnZTogcGd2ZWN0b3IvcGd2ZWN0b3I6cGcxNlxuICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSR7UE9TVEdSRVNfUEFTU1dPUkR9XG4gICAgICAtIFBPU1RHUkVTX0RCPWFmZmluZXByb1xuICAgICAgLSBQT1NUR1JFU19JTklUREJfQVJHUz0tLWRhdGEtY2hlY2tzdW1zXG4gICAgdm9sdW1lczpcbiAgICAgIC0gcG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGFcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFtcIkNNRFwiLCBcInBnX2lzcmVhZHlcIiwgXCItVVwiLCBcInBvc3RncmVzXCIsIFwiLWRcIiwgXCJhZmZpbmVwcm9cIl1cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG5cbiAgcmVkaXM6XG4gICAgaW1hZ2U6IHJlZGlzOjctYWxwaW5lXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBjb21tYW5kOiByZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAke1JFRElTX1BBU1NXT1JEfVxuICAgIHZvbHVtZXM6XG4gICAgICAtIHJlZGlzLWRhdGE6L2RhdGFcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFtcIkNNRC1TSEVMTFwiLCBcInJlZGlzLWNsaSAtYSAnJHtSRURJU19QQVNTV09SRH0nIHBpbmcgfCBncmVwIFBPTkdcIl1cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG5cbnZvbHVtZXM6XG4gIGFmZmluZS1zdG9yYWdlOiB7fVxuICBhZmZpbmUtY29uZmlnOiB7fVxuICBwb3N0Z3Jlcy1kYXRhOiB7fVxuICByZWRpcy1kYXRhOiB7fVxuIiwKICAiY29uZmlnIjogIlt2YXJpYWJsZXNdXG5tYWluX2RvbWFpbiA9IFwiJHtkb21haW59XCJcbnBvc3RncmVzX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkOjE2fVwiXG5yZWRpc19wYXNzd29yZCA9IFwiJHtwYXNzd29yZDoxNn1cIlxubWFpbGVyX2hvc3QgPSBcIlwiXG5tYWlsZXJfcG9ydCA9IFwiNTg3XCJcbm1haWxlcl91c2VyID0gXCJcIlxubWFpbGVyX3Bhc3N3b3JkID0gXCJcIlxubWFpbGVyX3NlbmRlciA9IFwiXCJcblxuW2NvbmZpZ11cbltbY29uZmlnLmRvbWFpbnNdXVxuc2VydmljZU5hbWUgPSBcImFmZmluZXByb1wiXG5wb3J0ID0gMzAxMFxuaG9zdCA9IFwiJHttYWluX2RvbWFpbn1cIlxuXG5bY29uZmlnLmVudl1cbkRPTUFJTiA9IFwiJHttYWluX2RvbWFpbn1cIlxuUE9TVEdSRVNfUEFTU1dPUkQgPSBcIiR7cG9zdGdyZXNfcGFzc3dvcmR9XCJcblJFRElTX1BBU1NXT1JEID0gXCIke3JlZGlzX3Bhc3N3b3JkfVwiXG5NQUlMRVJfSE9TVCA9IFwiJHttYWlsZXJfaG9zdH1cIlxuTUFJTEVSX1BPUlQgPSBcIiR7bWFpbGVyX3BvcnR9XCJcbk1BSUxFUl9VU0VSID0gXCIke21haWxlcl91c2VyfVwiXG5NQUlMRVJfUEFTU1dPUkQgPSBcIiR7bWFpbGVyX3Bhc3N3b3JkfVwiXG5NQUlMRVJfU0VOREVSID0gXCIke21haWxlcl9zZW5kZXJ9XCIgIgp9

Tags

collaboration, self-hosted, productivity, project-management


Version: stable

On this page