From Photos to Digital Workspace Link to heading

In the previous article we completed the migration from iCloud to Immich, gaining total control over our photos. With photos and music now managed autonomously, the next step is creating a complete digital workspace: AFFiNE, an all-in-one platform that combines notes, whiteboard, database, and AI functionality in a single self-hosted solution.

Info
AFFiNE vs commercial services: Combines the functionality of Notion, Miro, and Obsidian in one platform. No block limits, no automatic content reading, no vendor lock-in. Your data remains completely under your control.

Dedicated Container for AFFiNE Link to heading

Following the established approach of the series, we create an LXC container dedicated exclusively to AFFiNE. AFFiNE requires more resources than simple note apps, as it includes whiteboard rendering, AI features, and integrated database.

Creating AFFiNE Container Link to heading

Via Proxmox Web Interface:

  1. Create CTGeneral

    • CT ID: 107
    • Hostname: affine
    • Password: Set secure password
  2. Template: ubuntu-22.04-standard

  3. Root Disk:

    • Storage: local-lvm
    • Disk size: 8 GB (minimum, data on external disk)
  4. CPU:

    • Cores: 2 (AFFiNE recommends at least 4 cores, 2 cores for single user)
  5. Memory:

    • Memory: 4 GB (AFFiNE is more demanding for AI and whiteboard)
    • Swap: 2 GB
  6. Network:

    • Bridge: vmbr0
    • IPv4: Static
    • IPv4/CIDR: 192.168.1.208/24
    • Gateway: 192.168.1.1
    • Firewall: ✓ Enabled

Storage Strategy for AFFiNE Link to heading

AFFiNE manages not only textual notes, but also whiteboards with graphic elements, databases, and various attachments. However, for a single user, volumes remain manageable. We keep all data on the internal M.2 disk to maximize PostgreSQL database and Redis performance.

Info
Storage Choice: AFFiNE includes PostgreSQL, Redis, and file storage. The database benefits from internal M.2 SSD speed. Data volume will be contained (10-20GB with intensive use), making internal disk use appropriate.
Tip
Performance vs Storage: AFFiNE prioritizes speed for whiteboard rendering and AI features. PostgreSQL database and Redis cache perform better on internal SSD than network storage.

Docker Setup in AFFiNE Container Link to heading

# Start the container
pct start 107

# Enter the container
pct enter 107

# Update system and install Docker
apt update && apt install -y curl
curl -fsSL https://get.docker.com | sudo sh
usermod -aG docker $USER

# Verify installation
docker --version

# Restart to apply docker group
exit
pct reboot 107
pct enter 107

Preparing Directories for AFFiNE Link to heading

# Create directory structure for AFFiNE on internal disk
mkdir -p /opt/affine/{postgres,redis,storage}

# Check available space on internal disk
df -h /

# Verify permissions
ls -la /opt/affine/

AFFiNE Setup with Docker Compose Link to heading

AFFiNE requires PostgreSQL and Redis to function. We use the official Docker Compose configuration provided by the project.

Step 1 - Download Official Files Link to heading

# Create working directory
mkdir -p /root/affine-app
cd /root/affine-app

# Download official docker-compose.yml
wget -O docker-compose.yml https://github.com/toeverything/affine/releases/latest/download/docker-compose.yml

# Download example .env file
wget -O .env https://github.com/toeverything/affine/releases/latest/download/default.env.example

# Verify download
ls -la

Step 2 - Customizing .env File Link to heading

The downloaded .env file contains all necessary variables. Let’s customize it for our setup:

# Edit the .env file
nano .env

Main configurations to modify:

# Base URL for web access
AFFINE_SERVER_HOST=192.168.1.208
AFFINE_SERVER_PORT=3010

# PostgreSQL Database
POSTGRES_USER=affine
POSTGRES_PASSWORD=affine_secure_password_456
POSTGRES_DB=affine

# Redis (keep default)
REDIS_HOST=redis
REDIS_PORT=6379

# Storage paths (customized for our setup)
AFFINE_CONFIG_PATH=/opt/affine/storage
POSTGRES_DATA_PATH=/opt/affine/postgres
REDIS_DATA_PATH=/opt/affine/redis

# Feature flags (optional)
AFFINE_ADMIN_EMAIL=[email protected]
AFFINE_ADMIN_PASSWORD=admin_password_123
Warning
Secure Passwords: Change all default passwords with secure values. Use characters A-Za-z0-9_- to avoid escape issues in containers.

Step 3 - Verify and Customize Docker Compose Link to heading

The official docker-compose.yml file is well configured, but let’s verify it uses our custom paths:

# Check docker-compose.yml content
cat docker-compose.yml

# The file should reference .env variables for paths
# If necessary, we can modify volumes to point to our paths
Info
Official Docker Compose: AFFiNE provides a complete Docker Compose configuration that includes PostgreSQL with pgvector extension, Redis, and the AFFiNE server. No manual YAML modification is needed.

Step 4 - First AFFiNE Launch Link to heading

# From project directory
cd /root/affine-app

# Verify configuration
docker compose config

# First pull of images (may take time)
docker compose pull

# Start services
docker compose up -d

# Check container status
docker compose ps

# We should see 3 running containers: affine, postgres, redis

Step 5 - Verify Functionality Link to heading

# Check AFFiNE server logs
docker compose logs affine

# We should see messages like:
# "Server listening on port 3010"
# "Database connected successfully"

# Check database and redis logs
docker compose logs postgres
docker compose logs redis

Access and Initial Configuration Link to heading

AFFiNE should be accessible at http://192.168.1.208:3010.

First Access and Setup Link to heading

  1. Open browser and navigate to http://192.168.1.208:3010
  2. On first time, AFFiNE will show welcome screen
  3. Create account:
  4. Confirm registration
Info
Personal Workspace: AFFiNE automatically creates a personal workspace for each user. All documents, whiteboards, and databases are organized within the workspace.

Exploring AFFiNE Features Link to heading

AFFiNE combines different work modes in a single interface:

📝 Page Mode: Traditional Notion-style notes

  • Text blocks, images, tables
  • Native Markdown support
  • Hierarchical document structure

🎨 Edgeless Mode: Infinite whiteboard

  • Canvas for diagrams and brainstorming
  • Graphic elements and connections
  • Ideal for mind maps

🗃️ Database Mode: Tables and views

  • Structured data management
  • Filters and sorting
  • Multiple views (table, kanban, calendar)

Next Steps Link to heading

With AFFiNE operational, we’ve added a complete digital workspace to our self-hosted ecosystem. No longer just notes, but an integrated environment for documents, whiteboards, databases, and collaboration - all under our control.

AFFiNE represents a qualitative leap over simple note-taking apps: it combines the flexibility of Notion, the creativity of Miro, and the power of a database, all in a single self-hosted platform.

The next service in the homelab roadmap will be document management with Paperless-NGX, to digitize and organize physical documents with automatic OCR, thus completing the transition to a fully digital office.

Continue with: Homelab: Paperless-NGX and Document Management