Operate
Self-hosting
Run one Mica container with OpenID Connect, a repository connection, and one rule that says who can edit.
12 min readDeploy Mica as one container: the published @micacms/self-hosted image. It needs a repository connection, an OpenID Connect provider, a rule that says who can edit, and a persistent volume for its small SQLite file.
A save stages a draft in that database, where only editors see it. An editor's Publish writes everything pending to the repository as one commit.
Mica is pre-1.0. Test upgrades and keep the version fixed in production.
Repository access
Use the GitHub connector for a fine-grained token with read and write access to repository contents. Use the GitLab connector for a project access token with the write_repository scope.
Set REPOSITORY_ROOT to the content directory. Mica rejects paths outside this root even when the provider token can write to more of the repository.
Identity
Mica delegates sign-in to an OpenID Connect provider. It stores no password, and no account.
MICA_OIDC_ISSUER=https://auth.example.com MICA_OIDC_CLIENT_ID=mica MICA_OIDC_CLIENT_SECRET=
Register one redirect URI with the provider: https://cms.example.com/api/auth/callback.
Who can edit
Your provider tells Mica who a person is. It does not tell Mica if that person can edit this website. Set at least one rule; Mica refuses to start without one.
MICA_ADMIT_GROUP=mica-editors MICA_ADMIT_DOMAIN=example.com MICA_ADMIT_SUBJECTS=https://auth.example.com|a1b2c3
The group rule is the usual choice. To add an editor, put the person in that group in your identity provider. Mica does not change, and it keeps no list that can become incorrect. If your provider sends the groups with a different claim name, give the name in MICA_OIDC_GROUPS_CLAIM.
The domain rule applies only to an email address that the provider verified. The subject list uses issuer|subject, and never an email address: a provider can let a person change an address, and the next holder must not get the permission.
There is no user administration in Mica, and no invitation. Each person who the rules admit is an editor of this website.
Removal of access
A change to the rules is immediate, because Mica reads them on each request.
A change in your provider is not immediate. Mica uses the data that the provider sent at sign-in, thus a person who leaves the group continues until the session ends. Keep the sessions short, and disable the account in the provider when a person leaves.
SESSION_TTL_HOURS=8 SESSION_IDLE_HOURS=4
Start the service
curl -o compose.yml https://raw.githubusercontent.com/amuedespacher/micacms/main/deploy/self-hosted/compose.yml curl -o .env https://raw.githubusercontent.com/amuedespacher/micacms/main/deploy/self-hosted/.env.example $EDITOR .env docker compose up -d curl -s https://cms.example.com/health
The compose file pulls the published image from ghcr.io/amuedespacher/micacms. Nothing is built on the server, and there is no clone of the Mica repository: the content model comes out of your content repository at runtime.
Terminate TLS in a reverse proxy and set MICA_PUBLIC_URL to the public HTTPS address. Enable TRUST_PROXY only behind a proxy that you control.
Build the website
The website build needs no CMS URL and no read token. It reads the checked-out files. A normal push trigger is the complete connection between publish and deploy: a publish is a commit on the branch, and the branch already rebuilds on a push.
Backups
The content repository is the content backup, with history from every publish. The SQLite file contains sessions and the drafts that nobody has published yet. If you lose it, editors sign in again and unpublished work is gone; everything published is in the repository. One file to back up covers both.