refactor: unify config and data structures
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# DAV Server
|
||||
# nidus
|
||||
|
||||
A self-hosted **CalDAV**, **CardDAV**, and **WebDAV** server written in Go.
|
||||
|
||||
@@ -23,56 +23,61 @@ and files, all kept under your own roof instead of a third-party cloud.
|
||||
- **Web UI** — a mobile-friendly app at `/web/` for managing calendars,
|
||||
contacts, files, and account settings (see [Web UI](#web-ui) below),
|
||||
built with templ + Tailwind + htmx
|
||||
- **ICSSubscriptions** — add remote ICS/webcal calendars
|
||||
- **Birthdays calendar** — auto-computed from contacts' BDAY fields
|
||||
- Auto-discovery via `/.well-known/caldav` and `/.well-known/carddav`
|
||||
- Optional **TLS** (or use a reverse proxy)
|
||||
- Structured logging (text or JSON)
|
||||
- Graceful shutdown
|
||||
- Docker & Docker Compose support
|
||||
|
||||
## Quick start
|
||||
|
||||
### 1. Install dependencies
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
### 2. Create your `config.yaml`
|
||||
|
||||
Copy the example config and edit it — `config.yaml` is git-ignored so your
|
||||
real settings never get committed:
|
||||
|
||||
```bash
|
||||
cp config.example.yaml config.yaml
|
||||
```
|
||||
|
||||
Users, calendars, and address books are **no longer configured in
|
||||
`config.yaml`** — they live in the SQLite database and are managed with
|
||||
`nidusctl` (see below).
|
||||
|
||||
### 3. Run the server
|
||||
### 1. Run the server
|
||||
|
||||
```bash
|
||||
make run
|
||||
# or
|
||||
go run ./cmd/server -config config.yaml
|
||||
go run ./cmd/server
|
||||
```
|
||||
|
||||
The server starts at **http://localhost:8080**.
|
||||
|
||||
### 4. Create a user and their resources
|
||||
### 2. Configure the server via environment variables
|
||||
|
||||
The server is configured via environment variables:
|
||||
|
||||
```bash
|
||||
go run ./tools/nidusctl -config config.yaml user create alice \
|
||||
# Required: Set the data directory
|
||||
export NIDUS_DATA_DIR="./data"
|
||||
|
||||
# Optional: Set port, host, and base URL
|
||||
export NIDUS_PORT="8080"
|
||||
export NIDUS_HOST="0.0.0.0"
|
||||
export NIDUS_BASE_URL="https://dav.example.com"
|
||||
|
||||
# Optional: Set auth realm
|
||||
export NIDUS_AUTH_REALM="My DAV Server"
|
||||
|
||||
# Optional: Set logging
|
||||
export NIDUS_LOG_LEVEL="info"
|
||||
export NIDUS_LOG_FORMAT="text"
|
||||
```
|
||||
|
||||
This server does **not** handle TLS — use a reverse proxy (e.g. Nginx, Caddy,
|
||||
Traefik) to terminate TLS and forward requests to the server.
|
||||
|
||||
### 3. Create a user and their resources
|
||||
|
||||
```bash
|
||||
go run ./tools/nidusctl user create alice \
|
||||
--display-name "Alice Smith" --email alice@example.com
|
||||
# (prompts for a password; use --password to skip the prompt, e.g. in scripts)
|
||||
|
||||
go run ./tools/nidusctl -config config.yaml calendar create alice personal
|
||||
go run ./tools/nidusctl -config config.yaml addressbook create alice contacts
|
||||
go run ./tools/nidusctl calendar create alice personal
|
||||
go run ./tools/nidusctl addressbook create alice contacts
|
||||
```
|
||||
|
||||
Users can also be created/removed via the web UI (`/web/`) once logged in
|
||||
as an existing user — see **Web UI** below.
|
||||
Or use the web UI (`/web/`) once logged in — see **Web UI** below.
|
||||
|
||||
---
|
||||
|
||||
@@ -83,27 +88,27 @@ as an existing user — see **Web UI** below.
|
||||
docker compose up --build
|
||||
|
||||
# Or build manually
|
||||
docker build -t davserver .
|
||||
docker build -t nidus .
|
||||
docker run -p 8080:8080 \
|
||||
-v ./config.yaml:/app/config.yaml:ro \
|
||||
-v dav-data:/app/data \
|
||||
davserver
|
||||
-v nidus-data:/app/data \
|
||||
-e NIDUS_DATA_DIR=/app/data \
|
||||
nidus
|
||||
```
|
||||
|
||||
The image also ships `nidusctl`, so once the container is running you can
|
||||
create your first user (and their calendars/address books) with
|
||||
`docker compose exec` — no need to install Go locally:
|
||||
`docker compose exec`:
|
||||
|
||||
```bash
|
||||
docker compose exec davserver nidusctl -config /app/config.yaml user create alice \
|
||||
docker compose exec nidus nidusctl user create alice \
|
||||
--display-name "Alice Smith" --email alice@example.com
|
||||
# (prompts for a password; use --password to skip the prompt, e.g. in scripts)
|
||||
# (prompts for a password; use --password to skip the prompt)
|
||||
|
||||
docker compose exec davserver nidusctl -config /app/config.yaml calendar create alice personal
|
||||
docker compose exec davserver nidusctl -config /app/config.yaml addressbook create alice contacts
|
||||
docker compose exec nidus nidusctl calendar create alice personal
|
||||
docker compose exec nidus nidusctl addressbook create alice contacts
|
||||
```
|
||||
|
||||
### Pre-built images
|
||||
### Using pre-built images
|
||||
|
||||
Pushing a version tag (e.g. `v1.2.3`) or publishing a release triggers
|
||||
[`.github/workflows/docker-release.yml`](.github/workflows/docker-release.yml),
|
||||
@@ -118,25 +123,29 @@ building from a checkout — just fetch `config.example.yaml`, copy it to
|
||||
|
||||
```yaml
|
||||
services:
|
||||
davserver:
|
||||
nidus:
|
||||
image: git.arnef.de/arnef/nidus:latest
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./config.yaml:/app/config.yaml:ro
|
||||
- dav-data:/app/data
|
||||
- nidus-data:/app/data
|
||||
environment:
|
||||
- NIDUS_DATA_DIR=/app/data
|
||||
# Optional: other environment variables
|
||||
# - NIDUS_PORT=8080
|
||||
# - NIDUS_HOST=0.0.0.0
|
||||
# - NIDUS_BASE_URL=https://dav.example.com
|
||||
# - NIDUS_AUTH_REALM="My DAV Server"
|
||||
# - NIDUS_LOG_LEVEL=info
|
||||
# - NIDUS_LOG_FORMAT=text
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
dav-data:
|
||||
nidus-data:
|
||||
```
|
||||
|
||||
---
|
||||
Note: This server does **not** handle TLS. Use a reverse proxy (e.g. Nginx,
|
||||
Caddy, Traefik) to terminate TLS and forward requests to the server.
|
||||
|
||||
## API endpoints
|
||||
|
||||
@@ -208,10 +217,10 @@ mobile browsers:
|
||||
`nidus.db` (`web_sessions` table), independent of DAV Basic Auth. Includes
|
||||
a "Show/Hide" password toggle to rule out typos before submitting.
|
||||
- **Dashboard** (`/web/`) — create/delete your own calendars, address
|
||||
books, and ICS/webcal subscriptions; see who your resources are shared
|
||||
with and what others have shared with you; manage sharing grants
|
||||
directly (same effect as `nidusctl`) — updates happen in place via
|
||||
[htmx](https://htmx.org/) without a full page reload.
|
||||
books, ICS/webcal subscriptions, and the Birthdays calendar; see who your
|
||||
resources are shared with and what others have shared with you; manage
|
||||
sharing grants directly (same effect as `nidusctl`) — updates happen in
|
||||
place via [htmx](https://htmx.org/) without a full page reload.
|
||||
- **Files** (`/web/files/`) — a browser for the same storage the WebDAV
|
||||
endpoint (`/files/`) serves: navigate folders, create new folders,
|
||||
upload files/folders (including via drag & drop), download, and delete
|
||||
@@ -223,8 +232,9 @@ mobile browsers:
|
||||
delete contacts (name, organization, birthday, phone numbers, emails,
|
||||
addresses, photo), and import/export vCards (`.vcf`).
|
||||
- **Calendar** (`/web/calendar`) — month and week views across all your
|
||||
own and shared calendars, create/edit/delete events, per-calendar
|
||||
colors, and import/export `.ics` files.
|
||||
own and shared calendars (including ICS/webcal subscriptions and the
|
||||
Birthdays calendar), create/edit/delete events, per-calendar colors,
|
||||
and import/export `.ics` files.
|
||||
- **Account** (`/web/account`) — update your display name/email and
|
||||
change your password.
|
||||
- **Logout** (`/web/logout`).
|
||||
@@ -248,35 +258,34 @@ make web-assets # regenerate templ code + rebuild web/static/app.css and web/st
|
||||
|
||||
## Configuration reference
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
base_url: "https://dav.example.com" # used in DAV responses
|
||||
Configuration is done via environment variables:
|
||||
|
||||
auth:
|
||||
realm: "My DAV Server"
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `NIDUS_HOST` | `0.0.0.0` | Server listen host |
|
||||
| `NIDUS_PORT` | `8080` | Server listen port |
|
||||
| `NIDUS_BASE_URL` | (auto) | Public URL for DAV responses (e.g. https://dav.example.com) |
|
||||
| `NIDUS_AUTH_REALM` | `DAV Server` | HTTP Basic Auth realm |
|
||||
| `NIDUS_DATA_DIR` | `./data` | Data directory for all user data |
|
||||
| `NIDUS_LOG_LEVEL` | `info` | Log level: debug, info, warn, error |
|
||||
| `NIDUS_LOG_FORMAT` | `text` | Log format: text, json |
|
||||
|
||||
storage:
|
||||
data_dir: "./data" # all user data lives here
|
||||
Example:
|
||||
|
||||
logging:
|
||||
level: "info" # debug | info | warn | error
|
||||
format: "text" # text | json
|
||||
|
||||
tls:
|
||||
enabled: false
|
||||
cert_file: ""
|
||||
key_file: ""
|
||||
```bash
|
||||
export NIDUS_DATA_DIR="./data"
|
||||
export NIDUS_PORT="8080"
|
||||
export NIDUS_BASE_URL="https://dav.example.com"
|
||||
export NIDUS_LOG_LEVEL="info"
|
||||
```
|
||||
|
||||
Users, calendars, and address books are managed via `nidusctl`, not
|
||||
`config.yaml` — see **Managing users** below.
|
||||
This server does **not** handle TLS — use a reverse proxy (e.g. Nginx, Caddy,
|
||||
Traefik) to terminate TLS and forward requests to the server.
|
||||
|
||||
## Managing users
|
||||
|
||||
All user/calendar/address-book management is done with `nidusctl` (or the
|
||||
web UI). Nothing is stored in `config.yaml` anymore.
|
||||
All user/calendar/address-book management is done with `nidusctl` or the
|
||||
web UI (`/web/`). Nothing is stored in `config.yaml` anymore.
|
||||
|
||||
```bash
|
||||
# Users
|
||||
@@ -303,9 +312,10 @@ nidusctl addressbook unshare <owner> <book> <user>
|
||||
nidusctl addressbook shares <owner> <book>
|
||||
```
|
||||
|
||||
Passwords are prompted for interactively (masked, double-entry) when
|
||||
Password are prompted for interactively (masked, double-entry) when
|
||||
`--password` is omitted. The web UI (`/web/`) also lets a logged-in user
|
||||
create/delete their own calendars and address books from the dashboard.
|
||||
create/delete their own calendars, address books, and ICS/webcal subscriptions
|
||||
from the dashboard.
|
||||
|
||||
> **Upgrading from an older version?** The `users:` section in
|
||||
> `config.yaml` is no longer read. Recreate your users with
|
||||
@@ -317,22 +327,22 @@ create/delete their own calendars and address books from the dashboard.
|
||||
## Project layout
|
||||
|
||||
```
|
||||
caldav-server/
|
||||
nidus/
|
||||
├── cmd/server/ # main entrypoint
|
||||
├── internal/
|
||||
│ ├── auth/ # HTTP Basic Auth middleware (DAV endpoints)
|
||||
│ ├── caldav/ # CalDAV backend
|
||||
│ ├── carddav/ # CardDAV backend
|
||||
│ ├── config/ # YAML config loader
|
||||
│ ├── db/ # SQLite store (shares, web UI sessions)
|
||||
│ ├── db/ # SQLite store (users, calendars, shares, sessions)
|
||||
│ ├── store/ # filesystem storage layer
|
||||
│ ├── web/ # web UI (cookie sessions, dashboard, share mgmt)
|
||||
│ │ └── templates/ # templ templates (+ generated *_templ.go)
|
||||
│ └── webdav/ # WebDAV file handler
|
||||
├── tools/hashpwd/ # bcrypt password hasher CLI
|
||||
├── tools/nidusctl/ # sharing-grant admin CLI
|
||||
├── internal/web/ # web UI (templ, dashboard, share mgmt, sessions)
|
||||
│ └── templates/ # templ templates (+ generated *_templ.go)
|
||||
├── cmd/nidusctl/ # admin CLI (users, calendars, address books, sharing)
|
||||
├── web/ # front-end assets: Tailwind input/config, static/
|
||||
│ └── static/ # compiled app.css + htmx.min.js (embedded into the binary)
|
||||
├── tools/migrate/ # data directory migration tool
|
||||
├── config.example.yaml # sample configuration (copy to config.yaml)
|
||||
├── Dockerfile
|
||||
├── docker-compose.yaml
|
||||
|
||||
Reference in New Issue
Block a user