AFFiNE-ஐ Docker மூலம் self-host செய்வது எப்படி?
Docker Compose பயன்படுத்தி AFFiNE-ஐ உங்கள் server-ல் நிறுவுவதற்கான முழுமையான வழிகாட்டி. நான்கு containers, தரவு சேமிப்பு, 2 GB RAM தேவை மற்றும் backup எடுக்கும் முறையை இதில் அறியலாம்.
AFFiNE-ஐ self-host செய்யும்போது உங்களுக்குக் கிடைப்பவை
AFFiNE-ஐ self-host செய்வதன் மூலம், உங்கள் கட்டுப்பாட்டில் உள்ள server-ல் Notion போன்ற ஒரு workspace-ஐப் பெறலாம். இது நான்கு containers-ஆக இயங்குகிறது: application, ஒருமுறை மட்டும் இயங்கும் migration job, Postgres, மற்றும் Redis. இதில் real-time collaboration வசதி உள்ளது; self-hosted workspace-க்கு இயல்பாகவே 10 seats வரை வழங்கப்படுகிறது. இதன் நிறுவல் ஒரு compose file மற்றும் ஒரு JSON config file ஆகியவற்றைக் கொண்டது. image tags, disk layout, memory ceiling, மற்றும் முன்னால் நீங்கள் அமைக்கும் proxy ஆகியவற்றில் கூடுதல் கவனம் செலுத்த வேண்டும்.
AFFiNE ஒரே workspace-ல் document editor மற்றும் infinite canvas ஆகிய இரண்டையும் வைத்திருக்கிறது. எனவே, ஒரு பக்கத்தை document-ஆகவோ அல்லது whiteboard-ஆகவோ பயன்படுத்தலாம். நீங்கள் எதை இயக்க வேண்டும் என்று இன்னும் முடிவு செய்யவில்லை என்றால், முதலில் self-hosted Notion மாற்றுகளின் ஒப்பீட்டை வாசிக்கவும். இந்த வழிகாட்டி, AFFiNE-ஐ முறையாக இயக்குவதில் கவனம் செலுத்துகிறது; மீண்டும் ஒப்பீடு செய்யவில்லை.
இங்குள்ள அனைத்தும் 8 August 2026 அன்று AFFiNE self-host ஆவணங்கள் மற்றும் வெளியிடப்பட்ட release files-உடன் சரிபார்க்கப்பட்டன. அந்தத் தேதியில் இருந்த புதிய stable release 0.27.3 ஆகும், இது 23 July 2026 அன்று வெளியிடப்பட்டது.
நான்கு containers-ன் செயல்பாடுகள்
affine என்பது ஒரே image-ல் உள்ள server மற்றும் web client ஆகும். இது port 3010-ல் இயங்குகிறது.
affine_migration என்பது node ./scripts/self-host-predeploy.js-ஐ இயக்கும் ஒரு one-shot பணியாகும்; இது database migrations-ஐ முடித்துவிட்டு வெளியேறிவிடும். அந்தப் பணியின் மீது condition: service_completed_successfully-ஐ application குறிப்பிடுவதால், migration தோல்வியடைந்து (non-zero status) வெளியேறினால், affine தொடங்கவே தொடங்காது. Web interface இயங்கவில்லை என்றால், முதலில் அந்தப் பணியின் log-ஐப் பார்க்க வேண்டும்.
postgres உங்கள் ஆவணங்கள், பயனர்கள், workspaces மற்றும் அனுமதிகளைச் சேமிக்கிறது. வழங்கப்பட்ட image pgvector/pgvector:pg16 ஆகும்; இது pgvector extension சேர்க்கப்பட்ட சாதாரண Postgres 16 ஆகும். pgvector, Postgres-ல் vector column வகையைச் சேர்க்கிறது. இது embeddings-ஐச் சேமிக்கப் பயன்படும் எண் வடிவம்; இதன் மூலம் உரைகளை அவற்றின் பொருளைக் கொண்டு தேட முடியும்.
redis ஒரு கட்டாயத் தேவை (hard dependency): server மற்றும் migration பணி ஆகிய இரண்டுமே, இது இயங்கத் தொடங்கிய பின்னரே செயல்படும். வழங்கப்பட்ட compose file-ல் Redis-க்கு volume வழங்கப்படவில்லை என்பதைக் கவனிக்கவும். இதில் உள்ள எந்தத் தரவும் docker compose down-க்குப் பிறகு இருக்காது. இதிலிருந்து, இதில் உங்கள் தரவுகள் எதுவும் இல்லை என்பதும், இதற்கு backup தேவையில்லை என்பதும் தெளிவாகிறது.
Postgres image ஏன் stock postgres-ஆக இல்லாமல் pgvector-ஆக உள்ளது
இந்தத் தேவை AFFiNE-ன் schema-விலிருந்து வருகிறது, இது விருப்பத்தின் அடிப்படையில் அல்ல. schema.prisma-ல் datasource extensions = [pgvector(map: "vector")] என்று அறிவிக்கிறது, மேலும் நான்கு அட்டவணைகள் vector(1024) வகைப்படுத்தப்பட்ட embedding நெடுவரிசையைக் கொண்டுள்ளன. நீங்கள் AI அம்சங்களை இயக்கினாலும் இல்லாவிட்டாலும், migration job அந்த அட்டவணைகளை உருவாக்குகிறது. எனவே, migration முடிவதற்கு முன்பே database-ல் அந்த extension ஏற்கனவே இருக்க வேண்டும். postgres:16-க்கு மாற்றினால் extension இருக்காது, migration-ஆல் அந்த நெடுவரிசைகளை உருவாக்க முடியாது, மேலும் தோல்வியடைந்த job-க்காக server காத்திருக்கும்.
AFFiNE பதிப்பு 0.21-ல் pgvector image-க்கு மாறியது. அதற்கு முந்தைய install-ல், image வரியை மட்டும் மாற்றுவது முழுமையான upgrade ஆகாது. எனவே, எதையும் pull செய்வதற்கு முன் AFFiNE self-host docs-ல் உள்ள upgrade பக்கத்தைப் படிக்கவும்.
அந்த tag குறித்து மேலும் ஒரு விஷயம். pg16 என்பது Postgres 16-ஐக் குறிக்கிறது, Postgres major பதிப்பு எண்ணை நீங்கள் தன்னிச்சையாக மாற்ற முடியாது. ஏற்கனவே உள்ள data directory-ன் மேல் அதை pg17 என மாற்றினால், Postgres தொடங்க மறுத்துவிடும். அப்போது docker compose logs postgres-ல் The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 17 போன்ற வரி இடம்பெறும். ஒரு major பதிப்பு மாற்றத்திற்கு, data-வை dump செய்து புதிய data directory-ல் restore செய்ய வேண்டும்.
self-hosted AFFiNE-க்கு எவ்வளவு CPU மற்றும் RAM தேவை
AFFiNE-ன் தேவைகள் பக்கத்தில் குறைந்தபட்சம் 4 CPU cores மற்றும் 2 GB RAM தேவை என்று குறிப்பிடப்பட்டுள்ளது. உங்கள் ஆவணங்கள் 10,000 சொற்களைத் தாண்டும்போது, நினைவகத் தேவை 4 GB-ஆக உயர்கிறது. இந்த நினைவகம் எங்கே செலவாகிறது என்பதையும் அதே பக்கம் விளக்குகிறது: sync system மற்றும் document merging ஆகியவற்றுக்குத்தான் இது தேவைப்படுகிறது. இதில் கவனிக்க வேண்டிய முக்கியமான புள்ளி ஒன்று உள்ளது: 10,000 மாற்றங்களைக் கொண்ட ஒரு ஆவணத்தை இணைக்கும்போது (merging), அது உச்சகட்டமாக 1 GB நினைவகத்தை எடுத்துக்கொள்ளலாம்.
இப்போது 2 GB திட்டத்தில் (plan) இருவர் எழுதும் சூழலை எடுத்துக்கொள்வோம். சராசரி பயன்பாடு சரியாகவே இருக்கும். Postgres மற்றும் Node process ஆகியவை வரம்பிற்குள் இருக்கும், மீதமுள்ள இடமும் இருக்கும். ஆனால், உச்சகட்ட பயன்பாடுதான் சிக்கல். ஒரு பெரிய merge நடக்கும்போது, ஏற்கனவே பயன்பாட்டில் உள்ள நினைவகத்துடன் கூடுதலாக 1 GB தேவைப்படலாம். 2 GB மட்டுமே கொண்ட server-ல் swap இல்லையென்றால், kernel-ன் out-of-memory (OOM) killer அந்த கோரிக்கையை நிறைவேற்ற, மிகப்பெரிய process-ஆன AFFiNE server-ஐயே நிறுத்திவிடும்.
உங்கள் சக ஊழியருக்குப் பிழை (error) தெரியாது. பக்கம் மீண்டும் ஏற்றப்படுவதை (reload) மட்டுமே அவர் காண்பார், ஏனெனில் restart: unless-stopped சில நொடிகளில் container-ஐ மீண்டும் இயக்கிவிடும். இதை ஊகிக்க வேண்டாம், உறுதிப்படுத்தவும்:
docker inspect affine_server --format '{{.State.OOMKilled}} {{.RestartCount}}'
sudo dmesg -T | grep -i -E 'out of memory|killed process'முதல் கட்டளையிலிருந்து true, அல்லது இரண்டாவது கட்டளையிலிருந்து node-ஐக் குறிப்பிடும் Killed process வரி, நீங்கள் ஒரு பிழையைக் கண்டறியவில்லை, மாறாக நினைவகம் தீர்ந்துவிட்டது என்பதைக் குறிக்கிறது. இதை இரு முனைகளிலும் சரிசெய்யவும். முதலில் swap-ஐச் சேர்க்கவும், அப்போதுதான் ஒரு திடீர் சுமை (spike) ஏற்பட்டால் அது செயலிழக்காமல் மெதுவாகச் செயல்படும்:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -hfree -h இப்போது மொத்தம் 2.0Gi swap-ஐக் காட்ட வேண்டும். Swap-ஆல் AFFiNE வேகமாக இயங்காது, அதற்காக அது உருவாக்கப்படவில்லை. இது ஒரு நொடி நீடிக்கும் திடீர் சுமையை, container-ஐக் கொல்லாமல், ஒரு மெதுவான நொடியாக மாற்றுகிறது. இந்தத் தீர்வின் மறுமுனை, merge நடக்கும்போது application-க்குத் தேவையான இடத்தை Postgres-ன் cache ஆக்கிரமிப்பதைத் தடுப்பதாகும். இதற்குத்தான் Compose service-ல் நினைவக வரம்புகள் பயன்படுகின்றன.
சேமிப்பகத்தை (storage) கணிப்பது மிகவும் எளிது. AFFiNE அதே பக்கத்தில் வெளியிட்டுள்ள புள்ளிவிவரங்கள் இவை:
The data behind this chart
[
{
"label": "Server install",
"gb": 1.5
},
{
"label": "Postgres per 1,000 docs",
"gb": 0.1
},
{
"label": "Blob store per 1,000 uploads",
"gb": 10
}
]Server நிறுவல் 1.5 GB-ஐ எடுத்துக்கொள்ளும். தலா ஆயிரம் சொற்களைக் கொண்ட ஆயிரம் ஆவணங்கள், 0.1 GB Postgres தரவைச் சேர்க்கும், இது மிகக் குறைவு. பதிவேற்றப்பட்ட ஆயிரம் கோப்புகள் 10 GB-ஐச் சேர்க்கும், இதுவே முழுமையான கணக்கு. இவை இயங்கும் instance-லிருந்து எடுக்கப்பட்ட அளவீடுகள் அல்ல, திட்டமிடலுக்காக வெளியிடப்பட்ட புள்ளிவிவரங்கள் மட்டுமே. எனவே, இதை ஒரு உறுதிமொழியாகக் கருதாமல், ஒரு தோராயமான அளவீடாகக் கருதவும். தரவுத்தளம் சிறியதாகவே இருக்கும், உங்கள் பதிவேற்றங்களே வட்டு இடத்தைத் தீர்மானிக்கின்றன என்பதுதான் இதில் முக்கியமானது.
Compose கோப்பை நீங்களே எழுதுங்கள், tags-ஐ உறுதிப்படுத்துங்கள்
ஆவணப்படுத்தப்பட்ட நிறுவல் முறை curl -L -o docker-compose.yml https://github.com/toeverything/AFFiNE/releases/latest/download/docker-compose.yml மூலம் ஏற்கனவே தயாரிக்கப்பட்ட கோப்பைத் தரவிறக்கம் செய்கிறது. அது வேலை செய்யும். நீங்கள் அதைச் சார்ந்திருப்பதற்கு முன் ஒரு விவரத்தைத் தெரிந்துகொள்வது அவசியம்: 8 ஆகஸ்ட் 2026 நிலவரப்படி, release 0.27.3-உடன் இணைக்கப்பட்டுள்ள கோப்பு இன்னும் அதன் பாதைகளை .env கோப்பிலிருந்து ${UPLOAD_LOCATION}, ${CONFIG_LOCATION} மற்றும் ${DB_DATA_LOCATION} ஆகியவற்றைப் பயன்படுத்திப் படிக்கிறது. ஆனால் ஆவணங்களின் குறிப்புப் பக்கம், அனைத்தையும் ./data-க்குக் கீழ் வைத்திருக்கும் மற்றும் .env தேவையில்லாத புதிய அமைப்பைக் காட்டுகிறது. இவை இரண்டுமே சரியானவைதான். கோப்பை நீங்களே எழுதுவது இந்தச் சந்தேகத்தைத் தீர்க்கும், மேலும் images-ஐ pin செய்யவும் database கடவுச்சொல்லை அமைக்கவும் நீங்கள் அதைத் திருத்த வேண்டியிருக்கும்.
mkdir -p ~/affine/config ~/affine/data
cd ~/affine
printf 'DB_PASSWORD=%s\n' "$(openssl rand -hex 24)" > .env
chmod 600 .envCompose, project directory-ல் உள்ள .env-ஐத் தானாகவே வாசித்து ${DB_PASSWORD}-ஐ உங்களுக்குப் பதிலாகப் பிரதியிடும். எனவே, நீங்கள் support thread-ல் பகிரும் கோப்பில் கடவுச்சொல் ஒருபோதும் வெளிப்படாது. நீங்கள் இயக்கும் ஒவ்வொரு stack-லும் இந்தப் பழக்கத்தைப் பின்பற்றுவது நல்லது. இதற்கான காரணம் keeping secrets out of the compose file பகுதியில் உள்ளது.
இப்போது ~/affine/docker-compose.yml-ஐ எழுதுங்கள்:
name: affine
services:
affine:
image: ghcr.io/toeverything/affine:stable
container_name: affine_server
ports:
- '127.0.0.1:3010:3010'
depends_on:
redis:
condition: service_healthy
postgres:
condition: service_healthy
affine_migration:
condition: service_completed_successfully
volumes:
- ./data/storage:/root/.affine/storage
- ./config:/root/.affine/config
environment:
- REDIS_SERVER_HOST=redis
- DATABASE_URL=postgresql://affine:${DB_PASSWORD}@postgres:5432/affine
- AFFINE_INDEXER_ENABLED=false
restart: unless-stopped
affine_migration:
image: ghcr.io/toeverything/affine:stable
container_name: affine_migration_job
command: ['sh', '-c', 'node ./scripts/self-host-predeploy.js']
volumes:
- ./data/storage:/root/.affine/storage
- ./config:/root/.affine/config
environment:
- REDIS_SERVER_HOST=redis
- DATABASE_URL=postgresql://affine:${DB_PASSWORD}@postgres:5432/affine
- AFFINE_INDEXER_ENABLED=false
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
redis:
image: redis:8-alpine
container_name: affine_redis
healthcheck:
test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
postgres:
image: pgvector/pgvector:pg16
container_name: affine_postgres
volumes:
- ./data/postgres:/var/lib/postgresql/data
environment:
POSTGRES_USER: affine
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: affine
POSTGRES_INITDB_ARGS: '--data-checksums'
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'affine', '-d', 'affine']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stoppedupstream வழங்கும் கோப்பிலிருந்து இதில் நான்கு மாற்றங்கள் உள்ளன, ஒவ்வொன்றிற்கும் ஒரு காரணம் உண்டு:
127.0.0.1:3010:3010, port-ஐ loopback முகவரியில் மட்டுமே வெளியிடுகிறது. எனவே, நீங்கள் முடிவு செய்யும் வரை server-க்கு வெளியே எவராலும் AFFiNE-ஐ அணுக முடியாது. upstream-ன்'3010:3010'அனைத்து interface-களிலும் இணைகிறது; பெரும்பாலான VPS images-ல் இது public interface-ஐயும் உள்ளடக்கும்.POSTGRES_HOST_AUTH_METHOD: trustநீக்கப்பட்டு அதற்குப் பதிலாகக் கடவுச்சொல் அமைக்கப்பட்டுள்ளது. Trust authentication, அந்த database-க்கு வரும் எந்த இணைப்பையும் கடவுச்சொல் இன்றிaffineபயனராக ஏற்கும். இது private Compose network-க்குள் மட்டுமே கட்டுப்படுத்தப்பட்டுள்ளது. நீங்கள் அந்த network-ல் மற்றொரு container-ஐ இணைக்கும் வரை அல்லது debugging-ன் போது 5432-ஐ வெளியிடும் வரை இது பாதுகாப்பானது.redis:8-alpine, வெறும்redis-க்கு மாற்றாகப் பயன்படுத்தப்படுகிறது; இதுlatestஎனத் தீர்க்கப்படும். ஆகஸ்ட் 2026 நிலவரப்படி அது Redis 8 ஆகும். எனவே, இந்த pin நீங்கள் சோதித்த major version-ஐ அப்படியே வைத்திருக்கும், மேலும் தேவையற்றdocker compose pull-ன் போது Redis 9 தானாகவே வருவதைத் தடுக்கும்.pgvector/pgvector:pg16, மேலே குறிப்பிட்ட காரணத்திற்காக upstream அமைத்தபடியே அப்படியே இருக்கும்.
POSTGRES_PASSWORD, Postgres முதன்முதலில் அதன் data directory-ஐ உருவாக்கும்போது மட்டுமே வாசிக்கப்படும். ஏற்கனவே உள்ள instance-ல், docker compose exec postgres psql -U affine -c "ALTER USER affine WITH PASSWORD 'yourpassword'" மூலம் கடவுச்சொல்லை அமைத்துவிட்டு, அதற்கேற்ப DATABASE_URL-ஐப் புதுப்பிக்கவும்.
Configuration config/config.json-ல் உள்ளது
AFFiNE தனது அமைப்புகளை config/config.json-லிருந்து படிக்கிறது, இது நீங்கள் /root/.affine/config-ல் mount செய்த directory ஆகும். அந்த file-ஐ யாரும் உங்களுக்காக உருவாக்க மாட்டார்கள், எனவே முதல் முறை தொடங்குவதற்கு முன்பே அதை எழுதிவிடவும். ~/affine/config/config.json-ஐ ஒரு editor-ல் திறந்து, உதாரணத்திற்குப் பதிலாக உங்கள் domain-ஐக் குறிப்பிட்டு, பின்வரும் உள்ளடக்கத்தைச் சேர்க்கவும்:
{
"$schema": "https://github.com/toeverything/affine/releases/latest/download/config.schema.json",
"server": {
"name": "Team workspace",
"externalUrl": "https://affine.example.com"
},
"copilot": {
"enabled": false,
"byok": {
"enabled": false
}
}
}server.externalUrl என்பது பயனர்கள் browser-ல் உண்மையில் திறக்கும் முகவரியாக இருக்க வேண்டும். AFFiNE இந்த மதிப்பைக் கொண்டே share links மற்றும் workspace அழைப்புகளை உருவாக்குகிறது. எனவே, இதை http://localhost:3010-லேயே விட்டால், நீங்கள் அனுப்பும் அழைப்பு பெறுநரை அவர்களின் சொந்த machine-க்கு அழைத்துச் சென்று, அங்கு தோல்வியடையும். முதல் முறை தொடங்குவதற்கு முன்பே இதை public HTTPS முகவரிக்கு அமைக்கவும், அப்போதுதான் file-ம் admin panel-ம் ஒரே தகவலைக் கொண்டிருக்கும்.
copilot என்பது AI அம்சங்களைக் கட்டுப்படுத்துகிறது. copilot.byok.enabled என்பது 'bring-your-own-key' சுவிட்ச் ஆகும்; இது workspace உரிமையாளர் தனது சொந்த model provider key-ஐ workspace அமைப்புகளில் உள்ளிட அனுமதிக்கிறது. AFFiNE-ஐ நீங்களே host செய்யும்போது AI subscription இதில் அடங்காது. உங்களுக்கு இது தேவையில்லை என்றால், இரண்டையும் false என விடவும்.
Stack-ஐத் தொடங்கவும்:
docker compose up -d
docker compose psdocker compose ps-ல் affine_postgres மற்றும் affine_redis ஆகியவை healthy நிலையிலும், affine_server இயங்கும் நிலையிலும், affine_migration_job ஆனது exited (0) நிலையிலும் இருக்க வேண்டும். migration job-ல் வேறு ஏதேனும் exit code வந்தால், அதைத்தான் நீங்கள் கவனிக்க வேண்டும். அதன் log எந்தப் படிநிலையில் நின்றது என்பதைக் காட்டும்:
docker compose logs affine_migrationமறப்பதற்கு முன்பாக image-ஐ pin செய்யவும்
stable என்பது அடிக்கடி மாறும் ஒரு tag ஆகும். AFFiNE-ன் release workflow, ஒவ்வொரு stable build-க்கும் பல tags-ஐ வழங்குகிறது. அவற்றில் இரண்டு முக்கியமானவை: ஒவ்வொரு release-க்கும் மாற்றப்படும் stable, மற்றும் git short hash-ஐக் கொண்ட stable-. நீங்கள் stable-ல் வைத்திருந்தால், ஆறு மாதங்களுக்குப் பிறகு ஒரு docker compose pull-ஐ இயக்கும்போது, அது வேறு ஒரு image-ஐத் தரவிறக்கம் செய்து, நீங்கள் எதிர்பாராத நேரத்தில் database migrations-ஐச் செய்துவிடும். நீங்கள் சோதித்த அதே image-ஐ pin செய்யவும்:
docker compose pull
docker image inspect ghcr.io/toeverything/affine:stable --format '{{index .RepoDigests 0}}'இது ghcr.io/toeverything/affine@sha256: மற்றும் அதைத் தொடர்ந்து ஒரு நீண்ட hash-ஐக் காட்டும். அந்த முழு string-ஐயும் affine மற்றும் affine_migration ஆகிய இரண்டின் image: வரியிலும் paste செய்யவும். இவை இரண்டும் ஒரே image-ஐ இரண்டு வெவ்வேறு பணிகளுக்குப் பயன்படுத்துவதால், அவை எப்போதும் ஒன்றாக இருக்க வேண்டும். இல்லையெனில், ஒரு schema-வில் database-ஐ migrate செய்துவிட்டு, வேறொரு schema-வில் அதை இயக்க நேரிடும். எனவே, upgrade செய்வது என்பது தற்செயலாக நடக்காமல், திட்டமிட்டுச் செய்யப்பட வேண்டும்: digest-ஐ மாற்றவும், backup எடுக்கவும், பின் docker compose pull மற்றும் docker compose up -d செய்யவும்.
மற்றவர்கள் செய்வதற்கு முன்பே admin account-ஐ உருவாக்குங்கள்
புதிய instance-ல் /admin-ஐத் திறந்தால், server-ல் இன்னும் administrator இல்லாததால், AFFiNE உங்களை account உருவாக்கும் பக்கத்திற்கு அழைத்துச் செல்லும். அந்த செயல்பாட்டில் invitation code அல்லது setup token எதுவும் இல்லை. அந்தப் பக்கத்தை முதலில் அணுகும் நபரே உங்கள் server-ன் administrator ஆகிவிடுவார். எனவே, நீங்கள் பதிவு செய்யும் வரை அந்த port-ஐத் திறக்கக்கூடாது.
இதனால்தான் மேலே உள்ள compose file 127.0.0.1-உடன் பிணைக்கப்பட்டுள்ளது (bind). உங்கள் கணினியிலிருந்து SSH tunnel மூலம் அதை அணுகுங்கள்:
ssh -L 3010:127.0.0.1:3010 you@your-server-ipஅதை இயங்கவிட்டு, உங்கள் உள்ளூர் browser-ல் http://127.0.0.1:3010/admin-ஐத் திறக்கவும். பதிவு செய்து login செய்த பிறகு, tunnel-ஐ மூடிவிடவும். இப்போது மட்டுமே instance-ஐ ஒரு public name-ல் வைப்பது பாதுகாப்பானது.
AFFiNE உங்கள் தரவை எங்கு சேமிக்கிறது
மூன்று பாதைகள் அனைத்தையும் கொண்டுள்ளன, இவை அனைத்தும் நீங்கள் உருவாக்கிய directory-க்குள் அமைகின்றன.
./data/postgresஎன்பது Postgres தரவு directory: ஆவணங்கள், பயனர்கள், workspaces, மற்றும் அனுமதிகள்../data/storageஎன்பது container-ல்/root/.affine/storage-ல் mount செய்யப்பட்டுள்ளது, இது பதிவேற்றப்பட்ட அனைத்து கோப்புகளையும் கொண்டுள்ளது../configஎன்பது/root/.affine/config-ல் mount செய்யப்பட்டுள்ளது, இதுconfig.json-ஐக் கொண்டுள்ளது.
Upstream இங்கே named volumes-க்கு பதிலாக bind mounts-ஐப் பயன்படுத்துகிறது, இந்தத் தேர்வு வேண்டுமென்றே செய்யப்பட்டது: Docker-ஐக் கேட்காமலேயே, சாதாரண commands மூலம் இந்தத் தரவுகளை tar செய்து நகலெடுக்க முடியும். இதன் விளைவாக, host-ல் உள்ள கோப்புகளின் உரிமையாளர் (file ownership) தொடர்பான பொறுப்பு உங்களுடையதாகிறது; இது bind mounts and named volumes பகுதியில் விவரிக்கப்பட்டுள்ள பரிமாற்றமாகும்.
AFFiNE-ஐ எவ்வாறு பேக்கப் செய்வது
இரண்டு விஷயங்களை பேக்கப் செய்ய வேண்டும், அவை வெவ்வேறு முறைகளில் பேக்கப் செய்யப்படுகின்றன. Database ஒரு live server என்பதால், அது இயங்கிக்கொண்டிருக்கும்போது அதன் கோப்புகளை நகலெடுப்பது சிதைந்த நகலை மட்டுமே தரும். அதற்கு பதிலாக dump செய்யவும்:
mkdir -p ~/affine/backup
cd ~/affine
docker compose exec -T postgres pg_dump --format c --username affine affine \
> backup/affine-$(date +%F).dump
ls -lh backup/இந்த dump, container-க்குள் அதன் local socket வழியாக இயங்குவதால், அது கடவுச்சொல்லைக் கேட்காது. ls வெளியீட்டில் அதன் அளவைச் சரிபார்க்கவும். சில நூறு bytes மட்டுமே உள்ள கோப்பு, dump தோல்வியடைந்ததைக் குறிக்கிறது, ஆனால் shell அந்த கோப்பை உருவாக்கியிருக்கும்; இதுவே ஆறு மாதங்களுக்குப் பிறகு கண்டறியப்படும் தோல்வியாகும். -T-ம் முக்கியமானது: அது இல்லையென்றால், Compose ஒரு terminal-ஐ ஒதுக்கி binary stream-ஐ சிதைக்கக்கூடும்.
பதிவேற்றப்பட்ட கோப்புகள் வெறும் கோப்புகள் மட்டுமே, எனவே அவற்றை tar செய்யவும்:
tar czf backup/storage-$(date +%F).tgz -C data storage
cp config/config.json backup/config-$(date +%F).jsonconfig.json-ஐ உங்கள் பேக்கப்பில் கைமுறையாகச் சேர்த்துக்கொள்ளுங்கள். ஆகஸ்ட் 2026 நிலவரப்படி, admin panel-லிருந்து configuration-ஐ export செய்யும் வசதி இன்னும் செயல்படுத்தப்படவில்லை என்று AFFiNE ஆவணங்கள் குறிப்பிடுகின்றன, எனவே disk-ல் உள்ள கோப்பு மட்டுமே உங்கள் அமைப்புகளின் ஒரே நகலாகும். இந்த மூன்று கோப்புகளையும் server-லிருந்து வெளியே நகலெடுக்கவும். பாதுகாக்கும் அதே disk-ல் வைக்கப்படும் பேக்கப், உண்மையான பேக்கப் ஆகாது.
மீட்டெடுத்தல் மற்றும் வெளியிடப்பட்ட வழிமுறைகளில் உள்ள ஒரு சிக்கல்
மீட்டெடுப்புத் தேவைப்படுவதற்கு முன்பே அதிகாரப்பூர்வ வழிமுறைகளை வாசித்துவிடுங்கள், அவற்றை கவனமாகப் படியுங்கள். ஆகஸ்ட் 2026-ல் வெளியிடப்பட்டவற்றின்படி, அவை affine.backup என்ற கோப்பை container-க்குள் நகலெடுத்து, பின் ./pg.backup-லிருந்து மீட்டெடுக்கின்றன; இவை இரண்டு வெவ்வேறு பெயர்கள். மேலும், தற்போதைய compose கோப்பு அதன் தரவை ./data/postgres-ல் வைத்திருக்கும்போது, அவை ./postgres கோப்பகத்தை நீக்குகின்றன. துணுக்குகளில் (snippet) உள்ள பாதைகளைப் பின்பற்றாமல், நீங்கள் உண்மையில் பயன்படுத்திய பாதைகளையே பின்பற்றுங்கள். இந்த வழிகாட்டியில் உள்ள அமைப்பிற்கான வரிசைமுறை இதோ:
cd ~/affine
docker compose down
sudo mv data/postgres data/postgres.old
docker compose up -d postgres
docker compose cp backup/affine-2026-08-08.dump postgres:/tmp/affine.dump
docker compose exec postgres pg_restore --format c --username affine \
--dbname affine --verbose /tmp/affine.dump
docker compose up -drm-க்கு பதிலாக mv-ஐக் கவனியுங்கள். நகல் எடுக்காத ஒரு தரவுத்தளத்தின் மீது மீட்டெடுப்பது, ஒரு தவறான கட்டளை மூலம் மொத்த தரவையும் இழக்கச் செய்யும். பழைய கோப்பகத்தை நகர்த்தி வைப்பதில் எந்தச் செலவும் இல்லை. tar xzf backup/storage-2026-08-08.tgz -C data-ஐப் பயன்படுத்தி பதிவேற்றங்களையும் (uploads) மீட்டெடுங்கள், இல்லையெனில் ஒவ்வொரு ஆவணமும் சிதைந்த இணைப்புகளுடன் (broken attachments) காட்சியளிக்கும். பின்னர், உள்நுழைந்து ஒரு படத்தைக் கொண்ட ஆவணத்தைத் திறக்கவும். இதுவே சோதனை. நீங்கள் உலாவியில் (browser) திறந்து பார்க்காத ஒரு மீட்டெடுப்பு, அது ஒரு கோப்பு மட்டுமே, காப்புப்பிரதி (backup) அல்ல.
ஏற்கனவே இயங்கும் proxy-ன் பின்னால் AFFiNE-ஐ அமைத்தல்
AFFiNE, WebSocket-ஐப் பயன்படுத்துகிறது, இது கட்டாயமானது. AFFiNE-ன் sync மற்றும் collaboration முறைக்கு WebSocket அடிப்படையாக இருப்பதால், அதை upgrade செய்யாத proxy-ஐப் பயன்படுத்தினால், workspace-ல் செய்யப்படும் மாற்றங்கள் sync ஆகாது என்று ஆவணங்கள் தெளிவாகக் கூறுகின்றன. பக்கம் ஏற்றப்படும், login வேலை செய்யும், ஆனால் ஒரு browser-ல் செய்யப்படும் மாற்றம் மற்றொன்றுக்குச் செல்லாது. உங்கள் browser-ன் developer tools-ல் Network tab-ஐத் திறந்து WS என்று filter செய்யவும். ஒரு connection மீண்டும் மீண்டும் திறக்கப்பட்டு மூடப்பட்டால், அந்த proxy upgrade-ஐ அனுமதிக்கவில்லை என்று அர்த்தம்.
நீங்கள் ஏற்கனவே பிற containers-க்காக Traefik-ஐப் பயன்படுத்துகிறீர்கள் என்றால், AFFiNE-ஐ ஒரு சாதாரண service-ஆக அதனுடன் இணைக்கலாம். ports: தொகுதியை affine service-லிருந்து நீக்கிவிட்டு, பின்வருவனவற்றைச் சேர்க்கவும்:
networks:
- default
- proxy
labels:
- 'traefik.enable=true'
- 'traefik.docker.network=proxy'
- 'traefik.http.routers.affine.rule=Host(`affine.example.com`)'
- 'traefik.http.routers.affine.entrypoints=websecure'
- 'traefik.http.routers.affine.tls.certresolver=letsencrypt'
- 'traefik.http.services.affine.loadbalancer.server.port=3010'கோப்பின் இறுதியில், services:-க்கு அருகில்:
networks:
proxy:
external: trueCertificate resolver பெயர் உங்கள் Traefik configuration-ல் வரையறுக்கப்பட்ட பெயருடன் ஒத்துப்போக வேண்டும். loadbalancer.server.port என்பது container port 3010 ஆகும், இது host port அல்ல. Traefik எந்த கூடுதல் configuration-ம் இன்றி WebSocket connections-ஐ proxy செய்யும். உங்கள் stack-ல் உள்ள பிற சேவைகள் ஏற்கனவே single sign-on-க்கான Authentik-ன் பின்னால் இருந்தால், இந்த router-ல் ஒரு forward auth middleware-ஐப் பயன்படுத்தி AFFiNE-க்கான browser access-ஐக் கட்டுப்படுத்தலாம். ஆனால், desktop app-ஐச் சோதிக்கும் வரை இதைத் தவிர்க்கவும், ஏனெனில் அதில் browser session இருக்காது என்பதால் sync தோல்வியடையும். ஒரே instance-ன் பின்னால் பல apps-ஐ இயக்குவது பல apps-க்கு முன்னால் ஒரு Traefik என்பதில் விளக்கப்பட்டுள்ளது.
Nginx-ல் நீங்கள் upgrade-ஐத் தெளிவாகக் குறிப்பிட வேண்டும்:
location / {
proxy_pass http://127.0.0.1:3010;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 100m;
}Nginx-ல் client_max_body_size இயல்பாக 1 MB ஆக இருக்கும். அந்த வரி இல்லையென்றால், சிறிய புகைப்படத்தை விடப் பெரிய கோப்புகளை upload செய்யும்போது 413 status பிழை ஏற்படும். கோரிக்கை வந்து சேராததால் AFFiNE logs-ல் எதுவும் பதிவாகாது. Caddy-க்கு reverse_proxy http://127.0.0.1:3010 என்ற ஒரே ஒரு வரி போதும், அதுவே certificates மற்றும் WebSocket upgrades-ஐக் கவனித்துக்கொள்ளும்.
Self-hosted கட்டமைப்பில் விடுபட்டவை
ஒரு குழுவை இதற்கு மாற்றும் முன், இது குறித்து வெளிப்படையாக இருங்கள்.
நிகழ்நேர ஒத்துழைப்பு (Real-time collaboration) இதில் உள்ளது; AFFiNE-ன் ஆவணங்கள் நினைவகப் பயன்பாட்டை (memory use) ஒத்திசைவு அமைப்பு (sync system) மற்றும் ஆவணங்களை இணைக்கும் முறைக்கு (document merging) ஒதுக்குவதால், அனைத்து அளவு நிர்ணய ஆலோசனைகளும் இந்த அம்சத்தைப் பற்றியே அமைகின்றன. ஆஃப்லைனில் திருத்தம் செய்யும் வசதிக்காகவே பலர் local-first கருவியை விரும்புகிறார்கள்; desktop application-ல் உங்கள் self-hosted server-ஐ workspace பட்டியலில் சேர்த்து உள்நுழைய முடியும். உங்கள் குழு சார்ந்திருக்கும் ஆஃப்லைன் செயல்பாட்டை உறுதிப்படுத்தும் முன் அதைச் சோதிக்கவும்: நெட்வொர்க் இல்லாத நிலையில் desktop app-ல் திருத்தம் செய்து, மீண்டும் இணைத்து, மற்றொரு சாதனத்தில் முடிவைச் சரிபார்க்கவும். அம்சப் பட்டியல்கள் (feature lists) ஆதாரங்கள் அல்ல, இதுவும் அதற்கு விதிவிலக்கல்ல.
Server-side full-text search வசதி, வழங்கப்பட்ட compose file-ல் முடக்கப்பட்டுள்ளது; அங்கு AFFINE_INDEXER_ENABLED=false சர்வர் மற்றும் migration job-ல் அமைக்கப்பட்டுள்ளது. இதைச் செயல்படுத்துவது என்பது Manticore Search container-ஐச் சேர்ப்பதாகும்; இது ஐந்தாவது service மற்றும் கூடுதல் நினைவகத்தை எடுக்கும். 2 GB அளவுள்ள box-ல், இதுவே உங்கள் கணினியின் திறனை மீறச் செய்யும் மாற்றமாகும். நீங்கள் திறந்து வைத்துள்ள workspace-ல் client-க்குள் தேடும் வசதி தொடர்ந்து செயல்படும்.
பயனர்களை அழைக்கும் முன் இரண்டு வரம்புகளைத் தெரிந்துகொள்வது அவசியம். ஒரு self-hosted workspace-க்கு அதிகபட்சம் 10 இடங்கள் (seats) மட்டுமே வழங்கப்படும்; அதற்கு மேல் செல்ல AFFiNE-ன் Team license தேவை. Self-hosted instances-க்கு வரம்பற்ற blob storage மற்றும் வரம்பற்ற blob அளவு ஆகியவை ஆவணங்களில் குறிப்பிடப்பட்டிருந்தாலும், ஆகஸ்ட் 2026 நிலவரப்படி அவை முழுமையாகச் செயல்படுத்தப்படவில்லை. ஒரு குடும்பத்திற்கோ அல்லது சிறிய குழுவிற்கோ இவை பெரிய பாதிப்பை ஏற்படுத்தாது. ஆனால், நாற்பது பேரை மாற்றத் திட்டமிட்டிருந்தால், இவை முக்கியமானவை.
மேம்படுத்தல்கள் (Upgrades)
முதலில் release notes-ஐப் படிக்கவும். குறிப்பாக 0.26-லிருந்து 0.27 போன்ற minor version மாற்றங்களின்போது, சில breaking changes இருக்கலாம். எதையும் மாற்றும் முன் database மற்றும் storage directory-ஐ backup எடுக்கவும். ஏனெனில், அடுத்தமுறை service தொடங்கும்போது migration job உங்கள் schema-வை மாற்றியமைக்கும்; இதை மீண்டும் பழைய நிலைக்குக் கொண்டுவர முடியாது. அதன் பிறகு, pinned digest-ஐ மாற்றவும், docker compose pull கட்டளையை இயக்கி, தொடர்ந்து docker compose up -d கட்டளையை இயக்கவும். docker compose logs -f affine_migration சரியாக முடியும் வரை அதைக் கவனிக்கவும். அதன் பிறகு, பழைய layers-ஐ நீக்க docker image prune கட்டளையைப் பயன்படுத்தவும். மிகப்பழைய install வைத்திருப்பவர்களுக்கான ஒரு குறிப்பு: 0.23.0 பதிப்பிலிருந்து image பெயர் affine-graphql என்பதிலிருந்து affine என மாற்றப்பட்டது. எனவே, அதற்கு முந்தைய compose file-களில் உள்ள image வரிகளை மாற்றினால் மட்டுமே புதிய பதிப்பைப் பதிவிறக்க (pull) முடியும்.
FAQ
AFFiNE container ஏன் தொடங்கவில்லை?
affine service, affine_migration job-ல் condition: service_completed_successfully-ஐக் குறிப்பிடுகிறது. எனவே, migration செயல்முறை 0 அல்லாத எந்தவொரு status-உடன் நின்றாலும், server தொடங்கப்படாது மற்றும் web interface-ம் தோன்றாது. எந்தப் படிநிலையில் செயல்முறை நின்றது என்பதை அறிய docker compose logs affine_migration கட்டளையை இயக்கவும். கையால் திருத்தப்பட்ட compose file-களில், pgvector/pgvector:pg16-க்கு பதிலாக சாதாரண postgres image-ஐப் பயன்படுத்துவதுதான் பொதுவான காரணம். ஏனெனில், AFFiNE schema-வானது pgvector extension-ஐக் கோருகிறது மற்றும் சாதாரண Postgres-ஆல் உருவாக்க முடியாத vector(1024) columns-களைக் கொண்ட tables-களை உருவாக்குகிறது.
self-hosted AFFiNE-க்கு எவ்வளவு RAM தேவை?
AFFiNE-ன் தேவைகள் பக்கத்தில் குறைந்தபட்சம் 4 CPU cores மற்றும் 2 GB RAM பரிந்துரைக்கப்படுகிறது. ஆவணங்கள் 10,000 சொற்களைத் தாண்டும்போது இது 4 GB-ஆக உயர்கிறது. 10,000 மாற்றங்களைக் கொண்ட ஒரு ஆவணத்தை இணைக்கும்போது (merging) 1 GB வரை தேவைப்படலாம் என்று அது குறிப்பிடுகிறது. 2 GB RAM கொண்ட server-ல், idle load-ஐ விட இந்த உச்சகட்டத் தேவைதான் சிக்கலை ஏற்படுத்துகிறது: kernel-ன் out-of-memory killer, AFFiNE process-ஐ நிறுத்துகிறது, பின் restart: unless-stopped அதை மீண்டும் தொடங்குகிறது. இதனால் பயனர்களுக்குப் பிழைச் செய்திக்கு பதிலாக, பக்கம் மீண்டும் ஏற்றப்படுவது (page reload) மட்டுமே தெரியும். இதை உறுதிப்படுத்த docker inspect affine_server --format '{{.State.OOMKilled}}' மற்றும் sudo dmesg -T | grep -i 'out of memory' கட்டளைகளைப் பயன்படுத்தவும். பின்னர் 2 GB swap file-ஐச் சேர்க்கவும், அப்போதுதான் இத்தகைய திடீர் தேவை (spike) ஏற்பட்டால், அது fatal பிழையாக மாறாமல் மெதுவாகச் செயல்படும்.
AFFiNE எனது தரவை எங்கே சேமிக்கிறது, எதை backup எடுக்க வேண்டும்?
உங்கள் compose directory-க்குக் கீழே உள்ள மூன்று paths-களில் அனைத்தும் சேமிக்கப்படுகின்றன: database-க்கு ./data/postgres, பதிவேற்றப்பட்ட கோப்புகளுக்கு ./data/storage, மற்றும் config.json-க்கு ./config. இயங்கிக்கொண்டிருக்கும் Postgres-ஐ அப்படியே நகலெடுப்பது பாதுகாப்பானது அல்ல என்பதால், கோப்புகளை நகலெடுப்பதற்குப் பதிலாக docker compose exec -T postgres pg_dump --format c --username affine affine > affine.dump மூலம் database-ஐ backup எடுக்கவும். பதிவேற்றங்களுக்கு ./data/storage-ஐ tar செய்யவும். config.json-ஐக் கையால் நகலெடுத்து வைத்துக்கொள்ளவும், ஏனெனில் ஆகஸ்ட் 2026 நிலவரப்படி, admin panel-லிருந்து configuration-ஐ export செய்யும் வசதி இன்னும் செயல்படுத்தப்படவில்லை.
self-hosted AFFiNE-ல் real-time collaboration வேலை செய்யுமா?
ஆம், இதற்குத் தனியாக எதையும் enable செய்ய வேண்டியதில்லை. உங்கள் reverse proxy-ல் ஒரு தேவை மட்டுமே உள்ளது, ஏனெனில் sync செயல்பாடு WebSocket connections வழியாகவே நடக்கிறது. Nginx-ல் இதற்கு proxy_http_version 1.1 மற்றும் அதனுடன் Upgrade, Connection: upgrade headers தேவை. Traefik மற்றும் Caddy ஆகியவை கூடுதல் configuration இல்லாமலேயே இந்த இணைப்புகளை அனுமதிக்கும். Proxy-ல் இந்த upgrade வசதி இல்லையென்றால், workspace மற்றும் login சரியாக வேலை செய்யும், ஆனால் ஒரு browser-ல் செய்யப்படும் மாற்றங்கள் மற்றொன்றில் தெரியாது.
சாதாரண Postgres image-ஐப் பயன்படுத்தி AFFiNE-ஐ இயக்க முடியுமா?
முடியாது. AFFiNE-ன் schema.prisma, extensions = [pgvector(map: "vector")]-ஐக் குறிப்பிடுகிறது மற்றும் vector(1024) type-ல் embedding column கொண்ட நான்கு tables-களை வரையறுக்கிறது. AI வசதிகள் அணைக்கப்பட்டிருந்தாலும், migration job இந்த tables-களை உருவாக்குகிறது. அந்த extension-உடன் தொகுக்கப்பட்ட (compiled) Postgres 16-ஆன pgvector/pgvector:pg16-ஐப் பயன்படுத்தவும். நீங்கள் AFFiNE-ஐ ஒரு external Postgres server-க்கு இணைப்பதாக இருந்தால், அதில் pgvector-ஐ நிறுவி, migration-ஐ இயக்கும் முன்பே target database-ல் அந்த extension-ஐ உருவாக்கவும்.