Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ This setup includes:
- Radicale as a CalDAV (calendars, to-do lists) and CardDAV (contacts) server
- Users access to a Personal Calendar and Addressbook

Clients connect to `https://<your-domain>/caldav/` (calendar) and
`https://<your-domain>/carddav/` (contacts) — note the required trailing
slash — using an App Token as password. See [radicale/README.md](radicale/README.md)
for client setup (GNOME Online Accounts, Thunderbird) and troubleshooting.

### With Monitoring

Enable monitoring capabilities with metrics endpoints using either method:
Expand Down
17 changes: 13 additions & 4 deletions config/opencloud/proxy.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# This adds four additional routes to the proxy. Forwarding
# request on '/carddav/', '/caldav/' and the respective '/.well-knwown'
# This adds four additional routes to the proxy, forwarding requests
# on '/caldav/', '/carddav/' and the respective '/.well-known'
# endpoints to the radicale container and setting the required headers.
#
# Client URLs (trailing slash required, see radicale/README.md):
# CalDAV: https://<your-domain>/caldav/
# CardDAV: https://<your-domain>/carddav/
additional_policies:
- name: default
routes:
Expand All @@ -10,10 +14,15 @@ additional_policies:
skip_x_access_token: true
additional_headers:
- X-Script-Name: /caldav
# The '.well-known' endpoints are 'unprotected' so that DAV clients
# can discover the CalDAV/CardDAV URLs (RFC 6764) before they
# authenticate. Radicale only ever answers these paths with a 301
# redirect to '/caldav/' or '/carddav/' and serves no data here
# (deeper paths return 404), so no authentication is required.
- endpoint: /.well-known/caldav
backend: http://radicale:5232
remote_user_header: X-Remote-User
skip_x_access_token: true
unprotected: true
additional_headers:
- X-Script-Name: /caldav
- endpoint: /carddav/
Expand All @@ -24,8 +33,8 @@ additional_policies:
- X-Script-Name: /carddav
- endpoint: /.well-known/carddav
backend: http://radicale:5232
remote_user_header: X-Remote-User
skip_x_access_token: true
unprotected: true
additional_headers:
- X-Script-Name: /carddav
# To enable the radicale web UI add this rule.
Expand Down
77 changes: 77 additions & 0 deletions radicale/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Radicale — CalDAV / CardDAV

This module adds [Radicale](https://radicale.org/) as a CalDAV (calendars,
to-do lists) and CardDAV (contacts) server behind the OpenCloud proxy. Every
user gets a personal calendar and address book on first access.

## Enabling

Add `radicale/radicale.yml` to your `COMPOSE_FILE`:

```
COMPOSE_FILE=docker-compose.yml:radicale/radicale.yml:traefik/opencloud.yml
```

The routes are defined in [`config/opencloud/proxy.yaml`](../config/opencloud/proxy.yaml),
which `radicale.yml` mounts into the opencloud container.

## Connecting clients

### URLs

| Service | URL |
|---|---|
| CalDAV (calendar) | `https://<your-domain>/caldav/` |
| CardDAV (contacts) | `https://<your-domain>/carddav/` |

**The trailing slash is required.** `https://<your-domain>/caldav` (without
the slash) is not routed to Radicale and returns the OpenCloud web UI instead.

Clients that implement DAV service discovery (RFC 6764) can also be pointed
at the bare domain `https://<your-domain>/` — the `/.well-known/caldav` and
`/.well-known/carddav` endpoints redirect them to the URLs above. Clients
that don't (or that get confused by the web UI at the base URL) need the full
URL including the suffix.

### Authentication: use an App Token

DAV clients authenticate with **username + App Token** — not your account
password. With the default configuration (`PROXY_ENABLE_BASIC_AUTH=false`)
the account password is rejected with `401 Unauthorized`; App Tokens work out
of the box.

Create a token either

- in the web UI under **Settings → App Tokens**, or
- on the CLI:

```bash
docker compose exec opencloud opencloud auth-app create --user-name=<user> --expiration=72h
```

### GNOME Online Accounts

GNOME expects a directly answering DAV endpoint per account, so calendars and
contacts are added as two separate accounts:

1. **Settings → Online Accounts → Add Account → Calendar (CalDAV)**
— URL `https://<your-domain>/caldav/`, your username, an App Token as
password.
2. **Settings → Online Accounts → Add Account → Contacts (CardDAV)**
— URL `https://<your-domain>/carddav/`, same credentials.

### Thunderbird

- Calendar: *New Calendar → On the Network*, URL `https://<your-domain>/caldav/`
- Address book: *New Address Book → Add CardDAV Address Book*, URL
`https://<your-domain>/carddav/`

Use an App Token as the password in both dialogs.

## Troubleshooting

| Symptom | Cause |
|---|---|
| `401 Unauthorized` | Account password used instead of an App Token (or the token expired). |
| `405 Method Not Allowed` / HTML response | Trailing slash missing — the request landed on the web UI, not Radicale. |
| Client says "not a (Cal)DAV server" at the base URL | The client doesn't do RFC 6764 discovery. Use the full `/caldav/` / `/carddav/` URL. |