Add Radicale deployment guide (planning stage, not yet deployed)
This commit is contained in:
parent
b3ed41bcca
commit
9b32a93b44
185
117_radicale_deployment.md
Normal file
185
117_radicale_deployment.md
Normal file
@ -0,0 +1,185 @@
|
||||
# 117 — Radicale Deployment Guide
|
||||
|
||||
> Status: **NOT YET DEPLOYED** — planning reference only. Do not treat CT 117 or this config as live until each step is physically completed and confirmed.
|
||||
|
||||
**Service:** Radicale (lightweight CalDAV/CardDAV server)
|
||||
**CT ID:** 117
|
||||
**IP:** 192.168.1.117
|
||||
**Domain:** cal.spendlik.sk
|
||||
**Container type:** Unprivileged LXC, Debian 13 (trixie) — no Docker required, Radicale is a single Python package
|
||||
**Auth:** Authelia (CT 102) in front, plus Radicale's own htpasswd file as a second layer (CalDAV clients need Basic Auth to authenticate directly — Authelia SSO alone doesn't work well with CalDAV client protocols)
|
||||
|
||||
---
|
||||
|
||||
## Phase overview
|
||||
|
||||
1. Create LXC container
|
||||
2. Install Radicale + dependencies
|
||||
3. Configure Radicale (storage path, users, rights)
|
||||
4. Create systemd service
|
||||
5. nginx reverse proxy (CT 101)
|
||||
6. DNS — WebSupport A record (both management pages) + DDNS updater (CT 108)
|
||||
7. Let's Encrypt SSL via certbot + manual nginx config inspection
|
||||
8. Authelia bypass/config decision
|
||||
9. Create first calendar + test with a CalDAV client
|
||||
10. Client setup — Thunderbird (CachyOS) + DAVx⁵ (Galaxy S25)
|
||||
11. Update `00_index.md` and `homelab-overview.md` — **only after physical deployment**
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Create LXC container
|
||||
|
||||
```bash
|
||||
pct create 117 local:vztmpl/debian-13-standard_13.0-1_amd64.tar.zst \
|
||||
--hostname radicale \
|
||||
--cores 1 \
|
||||
--memory 256 \
|
||||
--net0 name=eth0,bridge=vmbr0,ip=192.168.1.117/24,gw=192.168.1.1 \
|
||||
--unprivileged 1 \
|
||||
--features nesting=0 \
|
||||
--storage local-lvm \
|
||||
--rootfs local-lvm:4
|
||||
```
|
||||
|
||||
- 256MB RAM / 4GB disk is generous for Radicale — it's a single-user Python app with a flat-file backend
|
||||
- `nesting=0` — no Docker needed, so no privileged container required, unlike your other services
|
||||
|
||||
## Phase 2 — Install Radicale
|
||||
|
||||
```bash
|
||||
pct start 117
|
||||
pct enter 117
|
||||
|
||||
apt update && apt install -y python3-pip python3-venv nano
|
||||
|
||||
python3 -m venv /opt/radicale
|
||||
source /opt/radicale/bin/activate
|
||||
pip install radicale
|
||||
```
|
||||
|
||||
- `nano` installed per your standing convention for new containers
|
||||
|
||||
## Phase 3 — Configure Radicale
|
||||
|
||||
```bash
|
||||
mkdir -p /etc/radicale /var/lib/radicale/collections
|
||||
htpasswd -c /etc/radicale/users spendlik
|
||||
```
|
||||
|
||||
`/etc/radicale/config`:
|
||||
```ini
|
||||
[server]
|
||||
hosts = 0.0.0.0:5232
|
||||
|
||||
[auth]
|
||||
type = htpasswd
|
||||
htpasswd_filename = /etc/radicale/users
|
||||
htpasswd_encryption = bcrypt
|
||||
|
||||
[storage]
|
||||
filesystem_folder = /var/lib/radicale/collections
|
||||
|
||||
[rights]
|
||||
type = owner_only
|
||||
```
|
||||
|
||||
- `owner_only` — each authenticated user only sees their own collections; fine for single-user use, revisit if you ever add a second account
|
||||
|
||||
## Phase 4 — systemd service
|
||||
|
||||
`/etc/systemd/system/radicale.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Radicale CalDAV/CardDAV server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/opt/radicale/bin/radicale --config /etc/radicale/config
|
||||
Restart=on-failure
|
||||
User=radicale
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
useradd -r -s /usr/sbin/nologin radicale
|
||||
chown -R radicale:radicale /var/lib/radicale /etc/radicale
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now radicale
|
||||
systemctl status radicale
|
||||
```
|
||||
|
||||
## Phase 5 — nginx reverse proxy (CT 101)
|
||||
|
||||
New vhost, HTTP-only first (per your certbot gotcha — always issue on a working HTTP config before adding SSL):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name cal.spendlik.sk;
|
||||
|
||||
location / {
|
||||
proxy_pass http://192.168.1.117:5232/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Script-Name /;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Phase 6 — DNS
|
||||
|
||||
- Add `cal.spendlik.sk` A record in **both** WebSupport management pages ⚠️
|
||||
- Add `cal.spendlik.sk` to the DDNS updater script in CT 108, with record ID once created
|
||||
- Update `00_index.md` WebSupport DNS Record ID table — after the record actually exists
|
||||
|
||||
## Phase 7 — SSL
|
||||
|
||||
```bash
|
||||
certbot --nginx -d cal.spendlik.sk
|
||||
```
|
||||
|
||||
- ⚠️ Manually inspect the resulting nginx config afterward — check for duplicate `server_name` and missing closing braces (known recurring certbot issue in this environment)
|
||||
|
||||
## Phase 8 — Authelia
|
||||
|
||||
CalDAV clients (Thunderbird, DAVx⁵) authenticate via HTTP Basic Auth on every request — they don't handle browser-based SSO redirects well. Recommended: **bypass Authelia entirely for `cal.spendlik.sk`** and rely on Radicale's own htpasswd auth + HTTPS. Add the bypass rule in CT 102's Authelia config, ordered before the catch-all 2FA rule (same pattern as your n8n `/api/*` bypass).
|
||||
|
||||
## Phase 9 — Create calendar + test
|
||||
|
||||
Radicale auto-creates collections on first client connection, or manually:
|
||||
```bash
|
||||
mkdir -p /var/lib/radicale/collections/spendlik/personal
|
||||
chown -R radicale:radicale /var/lib/radicale/collections/spendlik
|
||||
```
|
||||
|
||||
Test with `curl` first:
|
||||
```bash
|
||||
curl -u spendlik https://cal.spendlik.sk/spendlik/personal/
|
||||
```
|
||||
|
||||
## Phase 10 — Clients
|
||||
|
||||
**CachyOS (Thunderbird):**
|
||||
- Calendar → New Calendar → On the Network → CalDAV
|
||||
- URL: `https://cal.spendlik.sk/spendlik/personal/`
|
||||
|
||||
**Galaxy S25 (DAVx⁵):**
|
||||
- Add account → base URL `https://cal.spendlik.sk/spendlik/`
|
||||
- Syncs to native Samsung Calendar app once configured
|
||||
|
||||
## Phase 11 — Documentation (after physical deployment only)
|
||||
|
||||
- Add CT 117 row to `00_index.md` inventory table
|
||||
- Add `cal.spendlik.sk` DNS record ID once known
|
||||
- Add `117_radicale_deployment.md` to Documentation Map
|
||||
- Move Radicale from "Active Projects" to deployed state
|
||||
- Update `homelab-overview.md` container table
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- No Docker, no privileged container — smallest-footprint service in the stack
|
||||
- Backup: `/var/lib/radicale/collections` is the only stateful data — include in existing LXC nightly backup job, no special handling needed
|
||||
Loading…
Reference in New Issue
Block a user