feat: add AFFiNE

This commit is contained in:
Yuris Cakranegara
2025-06-18 22:23:57 +10:00
parent b5832c27a9
commit b73c7ab21d
5 changed files with 343 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
# AFFiNE Module
This module deploys [AFFiNE](https://affine.pro/), a privacy-first, local-first, note-taking and knowledge base application, as Docker containers in the homelab environment.
## Overview
The AFFiNE module:
- Deploys four Docker containers:
- `affine_server`: The main AFFiNE application server
- `affine_migration_job`: A container that runs pre-deployment migrations
- `affine_postgres`: A PostgreSQL (pgvector) database backend
- `affine_redis`: A Redis instance for caching and temporary data
- Creates a dedicated Docker network (`affine-network`) for container communication
- Persists data to volumes on the host
- Provides service definition for integration with networking modules
## Usage
```hcl
module "affine" {
source = "./modules/20-services-apps/affine"
volume_path = "/path/to/volumes/affine"
networks = ["homelab-network"]
}
```
## Variables
| Variable | Description | Type | Default |
| ------------- | -------------------------------------------------------------- | -------------- | ---------- |
| `image_tag` | Tag of the AFFiNE image to use | `string` | `"stable"` |
| `volume_path` | Host path for AFFiNE and database data volumes | `string` | - |
| `networks` | List of additional networks to which AFFiNE should be attached | `list(string)` | `[]` |
## Outputs
| Output | Description |
| -------------------- | ---------------------------------------------------------- |
| `service_definition` | Service definition for integration with networking modules |
## Service Definition
This module outputs a service definition that is used by the networking modules to expose the service.
```hcl
{
name = "affine_server"
primary_port = 3010
endpoint = "http://affine_server:3010"
subdomains = ["affine"]
publish_via = "tunnel" # Only publish through Cloudflare tunnel
}
```
## Environment Variables
AFFiNE requires several environment variables to function properly. These are stored in a `.env` file in the module directory and read using the `dotenv` Terraform provider:
- Database configuration:
- `DB_USERNAME`: PostgreSQL user
- `DB_PASSWORD`: PostgreSQL password
- `DB_DATABASE`: Database name (defaults to "affine")
- AFFiNE configuration:
- `AFFINE_REVISION`: Version of AFFiNE to use ("stable" or "canary") (defaults to "canary")
- `PORT`: External port for the AFFiNE server (defaults to 3010)
- `AFFINE_SERVER_HTTPS`: Whether to use HTTPS (defaults to "true")
- `AFFINE_SERVER_HOST`: Hostname for the AFFiNE server
- `AFFINE_SERVER_NAME`: Name for the AFFiNE server (defaults to "AFFiNE Selfhosted")
- Cloudflare R2 configuration:
- `R2_OBJECT_STORAGE_ACCOUNT_ID`: Cloudflare R2 account ID
- `R2_OBJECT_STORAGE_ACCESS_KEY_ID`: Cloudflare R2 access key ID
- `R2_OBJECT_STORAGE_SECRET_ACCESS_KEY`: Cloudflare R2 secret access key
## Data Persistence
AFFiNE stores its data in three main volumes:
1. AFFiNE application data: `/root/.affine/storage` in the container, mapped to `${volume_path}/self-host/storage` on the host
2. AFFiNE configuration: `/root/.affine/config` in the container, mapped to `${volume_path}/self-host/config` on the host
3. PostgreSQL data: `/var/lib/postgresql/data` in the container, mapped to `${volume_path}/self-host/postgres/pgdata` on the host
## Networking
The module creates a dedicated Docker network named `affine-network` for communication between the AFFiNE components. The AFFiNE server container is also attached to any additional networks specified in the `networks` variable, allowing it to communicate with other services in the homelab.
## Dependencies
The AFFiNE containers have the following dependencies:
- The main `affine_server` depends on PostgreSQL, Redis, and the migration job
- The migration job depends on PostgreSQL and Redis
- Both PostgreSQL and Redis use healthchecks to ensure they're ready before dependent services start
## Integration with Networking Modules
This service is configured to be exposed through the Caddy reverse proxy, set by `publish_via = "reverse_proxy"`.
## Example Integration in Main Configuration
```hcl
module "affine" {
source = "./modules/20-services-apps/affine"
volume_path = module.system_globals.volume_host
networks = [module.services.homelab_docker_network_name]
}
# The service definition is automatically included in the services output
module "services" {
source = "./modules/services"
# ...
service_definitions = [
module.affine.service_definition,
# Other service definitions
]
}
```