docs: add production deployment example with volumes and .env
- docker/docker-compose.prod.yml: pulls image from 192.168.0.19:5000, mounts config/, wiki/ and db/ as separate volumes, health check, TZ support - .env.example: fully commented template for all env vars - .gitignore: ignore .env, always track .env.example - README: deployment section with step-by-step guide, volume table, backup commands - config.go: default db_path to /data/db/archivum.db (matches prod volume layout) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
51
.env.example
Normal file
51
.env.example
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# ── Archivum — environment variables example ──────────────────────────────────
|
||||||
|
# Copy to .env and edit before running docker-compose.prod.yml
|
||||||
|
#
|
||||||
|
# cp .env.example .env
|
||||||
|
#
|
||||||
|
# Lines starting with # are comments and are ignored.
|
||||||
|
# ──────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
# ── Registry ───────────────────────────────────────────────────────────────────
|
||||||
|
# Address of your private Docker registry.
|
||||||
|
REGISTRY=192.168.0.19:5000
|
||||||
|
|
||||||
|
# Image tag to pull. Use a specific digest in production for reproducible deploys.
|
||||||
|
# IMAGE_TAG=sha256:abc123...
|
||||||
|
IMAGE_TAG=latest
|
||||||
|
|
||||||
|
|
||||||
|
# ── Host paths ─────────────────────────────────────────────────────────────────
|
||||||
|
# Base directory — all data lives under this path.
|
||||||
|
# Adjust to wherever you want to store Archivum data on the host.
|
||||||
|
ARCHIVUM_BASE=/opt/archivum
|
||||||
|
|
||||||
|
# Configuration directory (config.json, settings.json).
|
||||||
|
# The Setup Wizard will create config.json here on first access.
|
||||||
|
ARCHIVUM_CONFIG=/opt/archivum/config
|
||||||
|
|
||||||
|
# AsciiDoc wiki files + git repository root.
|
||||||
|
ARCHIVUM_WIKI=/opt/archivum/wiki
|
||||||
|
|
||||||
|
# SQLite database directory.
|
||||||
|
# The database file will be created as archivum.db inside this directory.
|
||||||
|
ARCHIVUM_DB=/opt/archivum/db
|
||||||
|
|
||||||
|
|
||||||
|
# ── Network ────────────────────────────────────────────────────────────────────
|
||||||
|
# Port exposed on the host. Access the app at http://<host>:HOST_PORT
|
||||||
|
HOST_PORT=8080
|
||||||
|
|
||||||
|
|
||||||
|
# ── File system permissions ─────────────────────────────────────────────────────
|
||||||
|
# UID and GID of the user that owns the host directories above.
|
||||||
|
# Run `id` on the host to find the correct values.
|
||||||
|
# Using 1000:1000 is fine if you created the directories as your own user.
|
||||||
|
PUID=1000
|
||||||
|
PGID=1000
|
||||||
|
|
||||||
|
|
||||||
|
# ── Timezone ───────────────────────────────────────────────────────────────────
|
||||||
|
# Used for git commit timestamps. See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
|
TZ=Europe/Stockholm
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -21,6 +21,8 @@ backend/internal/graph/models_gen.go
|
|||||||
config.json
|
config.json
|
||||||
settings.json
|
settings.json
|
||||||
*.db
|
*.db
|
||||||
|
.env
|
||||||
|
# .env.example is intentionally tracked — it contains no secrets
|
||||||
|
|
||||||
# go.sum is intentionally committed once populated by go mod tidy
|
# go.sum is intentionally committed once populated by go mod tidy
|
||||||
|
|
||||||
|
|||||||
82
README.md
82
README.md
@@ -115,6 +115,88 @@ npm run dev
|
|||||||
| `PUID` | `1000` | File system user ID |
|
| `PUID` | `1000` | File system user ID |
|
||||||
| `PGID` | `1000` | File system group ID |
|
| `PGID` | `1000` | File system group ID |
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### Directory layout on the host
|
||||||
|
|
||||||
|
```
|
||||||
|
/opt/archivum/
|
||||||
|
├── config/
|
||||||
|
│ └── config.json ← written by Setup Wizard on first access
|
||||||
|
├── wiki/ ← AsciiDoc files + git repository
|
||||||
|
└── db/
|
||||||
|
└── archivum.db ← SQLite database (auto-created)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Create host directories
|
||||||
|
mkdir -p /opt/archivum/{config,wiki,db}
|
||||||
|
|
||||||
|
# 2. Set ownership to match PUID/PGID (default 1000:1000)
|
||||||
|
chown -R 1000:1000 /opt/archivum
|
||||||
|
|
||||||
|
# 3. Copy and edit the environment file
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env — at minimum check PUID, PGID and HOST_PORT
|
||||||
|
|
||||||
|
# 4. Allow the insecure local registry (if not already done)
|
||||||
|
# Add to /etc/docker/daemon.json:
|
||||||
|
# { "insecure-registries": ["192.168.0.19:5000"] }
|
||||||
|
# Then: sudo systemctl restart docker
|
||||||
|
|
||||||
|
# 5. Pull and start
|
||||||
|
docker compose -f docker/docker-compose.prod.yml pull
|
||||||
|
docker compose -f docker/docker-compose.prod.yml up -d
|
||||||
|
|
||||||
|
# 6. View logs
|
||||||
|
docker compose -f docker/docker-compose.prod.yml logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `http://<host>:8080` and complete the Setup Wizard.
|
||||||
|
|
||||||
|
### Example `.env`
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
REGISTRY=192.168.0.19:5000
|
||||||
|
IMAGE_TAG=latest
|
||||||
|
|
||||||
|
ARCHIVUM_CONFIG=/opt/archivum/config
|
||||||
|
ARCHIVUM_WIKI=/opt/archivum/wiki
|
||||||
|
ARCHIVUM_DB=/opt/archivum/db
|
||||||
|
|
||||||
|
HOST_PORT=8080
|
||||||
|
PUID=1000
|
||||||
|
PGID=1000
|
||||||
|
TZ=Europe/Stockholm
|
||||||
|
```
|
||||||
|
|
||||||
|
> A fully commented template is available at [`.env.example`](.env.example).
|
||||||
|
|
||||||
|
### Volumes at a glance
|
||||||
|
|
||||||
|
| Container path | Maps to (default) | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `/config` | `/opt/archivum/config` | `config.json` (backend) + `settings.json` (frontend) |
|
||||||
|
| `/data/wiki` | `/opt/archivum/wiki` | AsciiDoc source files + git repo |
|
||||||
|
| `/data/db` | `/opt/archivum/db` | SQLite database (`archivum.db`) |
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Wiki content (git repo — just rsync or tar)
|
||||||
|
tar czf archivum-wiki-$(date +%F).tar.gz /opt/archivum/wiki
|
||||||
|
|
||||||
|
# Database
|
||||||
|
cp /opt/archivum/db/archivum.db archivum-db-$(date +%F).db
|
||||||
|
|
||||||
|
# Config
|
||||||
|
cp /opt/archivum/config/config.json archivum-config-$(date +%F).json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## VS Code Tasks
|
## VS Code Tasks
|
||||||
|
|
||||||
Open the Command Palette (`Ctrl+Shift+P`) → **Tasks: Run Task**:
|
Open the Command Palette (`Ctrl+Shift+P`) → **Tasks: Run Task**:
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ func Load(path string) (*Config, error) {
|
|||||||
cfg.ListenAddr = ":4000"
|
cfg.ListenAddr = ":4000"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default DB path to the dedicated db volume so it can be backed up
|
||||||
|
// independently of the wiki content.
|
||||||
|
if cfg.DBPath == "" {
|
||||||
|
cfg.DBPath = "/data/db/archivum.db"
|
||||||
|
}
|
||||||
|
|
||||||
return &cfg, nil
|
return &cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
81
docker/docker-compose.prod.yml
Normal file
81
docker/docker-compose.prod.yml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# ── Production deployment example ─────────────────────────────────────────────
|
||||||
|
#
|
||||||
|
# Uses the pre-built image from your private registry.
|
||||||
|
# Copy this file to your server and run:
|
||||||
|
#
|
||||||
|
# docker compose -f docker-compose.prod.yml up -d
|
||||||
|
#
|
||||||
|
# Prerequisites on the host:
|
||||||
|
# - Create the directories listed under "volumes" (or adjust paths in .env)
|
||||||
|
# - Populate config/config.json (see README for the JSON schema)
|
||||||
|
# OR leave it empty and the Setup Wizard will create it on first access.
|
||||||
|
#
|
||||||
|
# ── Directory layout this file expects ────────────────────────────────────────
|
||||||
|
#
|
||||||
|
# /opt/archivum/ (or whatever ARCHIVUM_BASE points to)
|
||||||
|
# ├── config/
|
||||||
|
# │ └── config.json ← backend configuration (auto-created by wizard)
|
||||||
|
# ├── wiki/ ← AsciiDoc source files (git repo lives here)
|
||||||
|
# └── db/
|
||||||
|
# └── archivum.db ← SQLite database (auto-created on first start)
|
||||||
|
#
|
||||||
|
# ── Quick start ────────────────────────────────────────────────────────────────
|
||||||
|
# cp .env.example .env # edit to match your environment
|
||||||
|
# mkdir -p /opt/archivum/{config,wiki,db}
|
||||||
|
# docker compose -f docker-compose.prod.yml pull
|
||||||
|
# docker compose -f docker-compose.prod.yml up -d
|
||||||
|
# ──────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
services:
|
||||||
|
archivum:
|
||||||
|
image: ${REGISTRY:-192.168.0.19:5000}/archivum:${IMAGE_TAG:-latest}
|
||||||
|
container_name: archivum
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- "${HOST_PORT:-8080}:4000"
|
||||||
|
|
||||||
|
environment:
|
||||||
|
# Path inside the container where config.json is looked up.
|
||||||
|
DOCKER_PATH: /config
|
||||||
|
|
||||||
|
# Path inside the container where the Vue SPA is served from.
|
||||||
|
# Change only if you override the Dockerfile.
|
||||||
|
UI_DIR: /srv/archivum/ui
|
||||||
|
|
||||||
|
# Match the UID/GID of the user that owns the host directories.
|
||||||
|
PUID: ${PUID:-1000}
|
||||||
|
PGID: ${PGID:-1000}
|
||||||
|
|
||||||
|
# Optional: set TZ for correct git commit timestamps.
|
||||||
|
TZ: ${TZ:-Europe/Stockholm}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# ── Configuration ──────────────────────────────────────────────────────
|
||||||
|
# config.json (backend) and settings.json (frontend) live here.
|
||||||
|
# The Setup Wizard writes config.json here on first run.
|
||||||
|
- ${ARCHIVUM_CONFIG:-/opt/archivum/config}:/config
|
||||||
|
|
||||||
|
# ── Wiki files (AsciiDoc source + git repo) ────────────────────────────
|
||||||
|
# This directory becomes the git repository root.
|
||||||
|
# Map it to wherever you want the .adoc files to live on the host.
|
||||||
|
- ${ARCHIVUM_WIKI:-/opt/archivum/wiki}:/data/wiki
|
||||||
|
|
||||||
|
# ── SQLite database ────────────────────────────────────────────────────
|
||||||
|
# Mounting the db directory separately makes it easy to back up the
|
||||||
|
# database independently of the wiki content.
|
||||||
|
- ${ARCHIVUM_DB:-/opt/archivum/db}:/data/db
|
||||||
|
|
||||||
|
# Optional: limit resource usage on a Raspberry Pi 5.
|
||||||
|
# deploy:
|
||||||
|
# resources:
|
||||||
|
# limits:
|
||||||
|
# cpus: "2.0"
|
||||||
|
# memory: 512M
|
||||||
|
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "-qO-", "http://localhost:4000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
Reference in New Issue
Block a user