···11+apiVersion: v2
22+name: lichen
33+description: A Helm chart for lichen CMS
44+type: application
55+version: 0.1.0
66+appVersion: "0.1.0"
+119
lichen/README.md
···11+# Lichen Helm Chart
22+33+## Quickstart
44+55+Prerequisites: a k3s (or k8s) cluster with `helm` installed.
66+77+```bash
88+# Install
99+helm install lichen ./charts/lichen \
1010+ --set dashboardDomain=lichen.example.com
1111+1212+# Get admin password
1313+kubectl get secret lichen-admin-password -o jsonpath='{.data.password}' | base64 -d
1414+```
1515+1616+Point your DNS (both `lichen.example.com` and `*.example.com`) to the server. Visit `https://lichen.example.com` and log in with username `admin` and the password above.
1717+1818+## Upgrading
1919+2020+```bash
2121+helm upgrade lichen ./charts/lichen \
2222+ --set dashboardDomain=lichen.example.com
2323+```
2424+2525+The admin password is preserved across upgrades.
2626+2727+## Configuration
2828+2929+### Dashboard Domain
3030+3131+```bash
3232+--set dashboardDomain=lichen.example.com
3333+```
3434+3535+Sets the domain for the management dashboard. Lichen uses this for routing: requests to this domain go to the dashboard, requests to other domains serve sites.
3636+3737+### TLS with Caddy
3838+3939+Caddy is enabled by default as a reverse proxy with on-demand TLS. It automatically obtains Let's Encrypt certificates for any domain pointed at the server. No cert-manager or ingress controller needed.
4040+4141+```bash
4242+# Disable Caddy (e.g., if using your own ingress controller)
4343+--set caddy.enabled=false
4444+```
4545+4646+### Auth
4747+4848+Auth is enabled by default with `file` and `atproto` providers.
4949+5050+```bash
5151+# Disable auth
5252+--set auth.enabled=false
5353+5454+# File auth only
5555+--set 'auth.providers={file}'
5656+5757+# All providers
5858+--set 'auth.providers={file,atproto,oidc}'
5959+```
6060+6161+### Admin User
6262+6363+An admin user is auto-created on first deploy with a random password stored in a Kubernetes Secret.
6464+6565+```bash
6666+# Custom username
6767+--set auth.adminUser.username=myuser
6868+6969+# Specific password instead of random
7070+--set auth.adminUser.password=mysecretpassword
7171+7272+# Disable auto-creation
7373+--set auth.adminUser.enabled=false
7474+```
7575+7676+Retrieve the password:
7777+```bash
7878+kubectl get secret lichen-admin-password -o jsonpath='{.data.password}' | base64 -d
7979+```
8080+8181+### Ingress (alternative to Caddy)
8282+8383+If you prefer to use an existing ingress controller instead of Caddy:
8484+8585+```bash
8686+helm install lichen ./charts/lichen \
8787+ --set ingress.enabled=true \
8888+ --set ingress.className=nginx \
8989+ --set 'ingress.hosts[0].host=lichen.example.com' \
9090+ --set 'ingress.hosts[0].paths[0].path=/' \
9191+ --set 'ingress.hosts[0].paths[0].pathType=Prefix'
9292+```
9393+9494+### Extra Environment Variables
9595+9696+Pass additional `LM_` environment variables to the lichen container:
9797+9898+```bash
9999+--set env.LM_DEVELOPMENT_MODE=true
100100+```
101101+102102+### Persistence
103103+104104+```bash
105105+--set persistence.size=10Gi
106106+--set persistence.storageClass=local-path
107107+```
108108+109109+Data is stored at `/data/lichen` on the PVC.
110110+111111+## Architecture
112112+113113+```
114114+Internet -> Caddy (:443, on-demand TLS) -> lichen Service (:80) -> lichen Pod (:9000)
115115+```
116116+117117+- **Caddy** runs with `hostNetwork` on ports 80/443 and auto-issues TLS certs via Let's Encrypt for any domain
118118+- **lichen** runs in multi-site mode with persistent storage and auth
119119+- **Init container** writes `lichen.toml` config and creates the admin user on first deploy