Docker and config

This commit is contained in:
moeny-matt 2025-02-05 15:34:33 -05:00
parent 49f57f61a2
commit a2683187f9
5 changed files with 242 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.DS_Store
.env
generate-bcrypt-hash.py
config/users

View File

@ -1,2 +1,30 @@
# radicale # radicale
[Radicale](https://radicale.org/v3.html) is a small but powerful CalDAV (calendars, to-do lists) and CardDAV (contacts) server. The Docker configuration is based off of the work in [docker-radicale](https://github.com/tomsquest/docker-radicale).
## Quick start
1. All of the necessary files to start a Radicale server are in this repo. Begin by editing the following lines in the docker-compose.yaml file to reflect your hostname and the email address you want to use for Let's Encrypt.
``` yaml
services:
radicale:
labels:
- "traefik.http.routers.radicale.rule=Host(`radicale.moeny.ai`)"
```
and
``` yaml
services:
traefik:
command:
- --certificatesresolvers.le.acme.email=radicale@moeny.ai
```
Make sure you also have a domain DNS A record pointed to your server's public IP for the hostname you gave to traefik. To set up your own DNS server, see our [bind9 repo](https://gitea.moeny.ai/moeny/bind9).
2. Rename `config/users.sample` to `users` and edit the usernames and passwords it contains. Ensure that each line contains a username and bcrypt-hashed password, separated by a colon (:).
3. Once ready, run `docker-compose up -d` to start the server.
4. You should then be able to access Radicale at the URL you set up with traefik earlier. The usernames and passwords to log in are the ones added to the `users` file. Use the non-hashed password.

138
config/config Normal file
View File

@ -0,0 +1,138 @@
# -*- mode: conf -*-
# vim:ft=cfg
# Config file for Radicale - A simple calendar server
#
# Place it into /etc/radicale/config (global)
# or ~/.config/radicale/config (user)
#
# The current values are the default ones
[server]
# CalDAV server hostnames separated by a comma
# IPv4 syntax: address:port
# IPv6 syntax: [address]:port
# Hostname syntax (using "getaddrinfo" to resolve to IPv4/IPv6 adress(es)): hostname:port
# For example: 0.0.0.0:9999, [::]:9999, localhost:9999
#hosts = localhost:5232
hosts = 0.0.0.0:5232
# Max parallel connections
#max_connections = 8
# Max size of request body (bytes)
#max_content_length = 100000000
# Socket timeout (seconds)
#timeout = 30
# SSL flag, enable HTTPS protocol
#ssl = False
# SSL certificate path
#certificate = /etc/ssl/radicale.cert.pem
# SSL private key
#key = /etc/ssl/radicale.key.pem
# CA certificate for validating clients. This can be used to secure
# TCP traffic between Radicale and a reverse proxy
#certificate_authority =
[encoding]
# Encoding for responding requests
#request = utf-8
# Encoding for storing local collections
#stock = utf-8
[auth]
# Authentication method
# Value: none | htpasswd | remote_user | http_x_remote_user
type = htpasswd
# Htpasswd filename
htpasswd_filename = /config/users
# Htpasswd encryption method
# Value: plain | bcrypt | md5 | sha256 | sha512 | autodetect
# bcrypt requires the installation of 'bcrypt' module.
htpasswd_encryption = bcrypt
# Incorrect authentication delay (seconds)
#delay = 1
# Message displayed in the client when a password is needed
#realm = Radicale - Password Required
# Сonvert username to lowercase, must be true for case-insensitive auth providers
#lc_username = False
[rights]
# Rights backend
# Value: none | authenticated | owner_only | owner_write | from_file
#type = owner_only
# File for rights management from_file
#file = /etc/radicale/rights
# Permit delete of a collection (global)
#permit_delete_collection = True
[storage]
# Storage backend
# Value: multifilesystem | multifilesystem_nolock
#type = multifilesystem
# Folder for storing local collections, created if not present
#filesystem_folder = /var/lib/radicale/collections
filesystem_folder = /data/collections
# Delete sync token that are older (seconds)
#max_sync_token_age = 2592000
# Command that is run after changes to storage
# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
#hook =
[web]
# Web interface backend
# Value: none | internal
#type = internal
[logging]
# Threshold for the logger
# Value: debug | info | warning | error | critical
#level = info
# Don't include passwords in logs
#mask_passwords = True
[headers]
# Additional HTTP headers
#Access-Control-Allow-Origin = *
[hook]
# Hook types
# Value: none | rabbitmq
#type = none
#rabbitmq_endpoint =
#rabbitmq_topic =
#rabbitmq_queue_type = classic

2
config/users.sample Normal file
View File

@ -0,0 +1,2 @@
john:$2b$12$l1Se4qIaRlfOnaC1pGt32uNe/Dr61r4JrZQCNnY.kTx2KgJ70GPSm
sarah:$2b$12$lKEHYHjrZ.QHpWQeB/feWe/0m4ZtckLI.cYkVOITW8/0xoLCp1/Wy

70
docker-compose.yaml Normal file
View File

@ -0,0 +1,70 @@
# Can be enhanced with an additional compose file
# See also https://docs.docker.com/compose/production/#modify-your-compose-file-for-production
services:
radicale:
image: tomsquest/docker-radicale
container_name: radicale
init: true
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- SETUID
- SETGID
- CHOWN
- KILL
deploy:
resources:
limits:
memory: 256M
pids: 50
healthcheck:
test: curl -f http://127.0.0.1:5232 || exit 1
interval: 30s
retries: 3
restart: always
volumes:
- ./data:/data
- ./config:/config:ro
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.radicale.rule=Host(`radicale.moeny.ai`)"
- "traefik.http.routers.radicale.entrypoints=https"
- "traefik.http.routers.radicale.tls.certresolver=le"
- "traefik.http.services.radicale.loadbalancer.server.port=5232"
traefik:
image: traefik:v2.10
container_name: traefik
restart: always
command:
- --api.insecure=false
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entryPoint.to=https
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.https.address=:443
- --certificatesresolvers.le.acme.tlschallenge=true
- --certificatesresolvers.le.acme.email=radicale@moeny.ai
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
ports:
- "80:80"
- "443:443"
volumes:
- traefik:/letsencrypt:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- proxy
networks:
proxy:
driver: bridge
volumes:
traefik: { driver: local }