# Configuration Runbook First-run configuration steps to perform after the Ansible playbook has provisioned the server. See `runbook-provisioning.md` for the provisioning steps. ## 1. Verify all services are reachable Before configuring individual services, confirm every HTTPS endpoint is up and TLS certificates are valid. Run this from your local machine: ```bash bash scripts/check-services.sh ``` The script checks these endpoints and verifies the expected HTTP status code: | URL | Expected | Notes | |-----|----------|-------| | `https://cloud.ladkau.de/dashboard/` | 401 | Basic-auth prompt — correct without credentials | | `https://gitea.ladkau.de` | 200 | Gitea sign-in page | | `https://nextcloud.ladkau.de` | 200 | First visit triggers setup and takes 1–2 min | | `https://sso.ladkau.de/realms/master` | 200 | Keycloak realm JSON — first start takes ~90 s | | `https://mail.ladkau.de` | 200 | Roundcube webmail login | | `https://cr.ladkau.de/v2/` | 401 | Registry API — auth required, correct without credentials | | `https://k8s.ladkau.de` | 200 | Placeholder page | | `https://vault.ladkau.de` | 200 | Vaultwarden web vault | | `https://dl.ladkau.de` | 200 | Public download server | A `000` result means the connection was refused or timed out — a container that did not start. Keycloak and Nextcloud may return `502` for up to 90 seconds on first boot; wait and retry before investigating. Once the script passes, open `https://cloud.ladkau.de/dashboard/` in a browser and authenticate with the `traefik_dashboard_users` credentials to verify the dashboard loads correctly. ## 2. Keycloak Keycloak is the identity provider for all services. Configure it first so that Gitea and Nextcloud can be wired up to SSO in the steps that follow. Keycloak takes ~90 seconds to start on first boot. If the login page at `https://sso.ladkau.de` is not immediately available, wait and retry. ### 2.1 Log in and change the admin password 1. Go to `https://sso.ladkau.de` and sign in with username `admin` and the value of `keycloak_admin_password` from the vault. 2. Click the **admin** dropdown (top right) → **Manage account** → **Password** → set a new password. The bootstrap credentials are only used on first start. After changing the password, the vault value is no longer authoritative — store the new password in your password manager. ### 2.2 Create an application realm 1. In the left sidebar, click the realm dropdown (shows **master**) → **Create realm**. 2. Set **Realm name** to `ladkau` and click **Create**. 3. Make sure the `ladkau` realm is selected in the sidebar for all steps below. The `master` realm is for Keycloak administration only. All application users and clients live in `ladkau`. ### 2.3 Create users For each user you want to be able to log in to Gitea and Nextcloud: 1. **Users** → **Add user**. 2. Fill in **Username**, **Email**, **First name**, **Last name** → **Create**. 3. Go to the **Credentials** tab → **Set password**. 4. Enter a password, turn off **Temporary**, and click **Save**. ### 2.4 Create the Gitea OIDC client 1. **Clients** → **Create client**. 2. **Client type**: OpenID Connect — **Client ID**: `gitea` → **Next**. 3. Turn **Client authentication** on (confidential client) → **Next**. 4. **Valid redirect URIs**: `https://gitea.ladkau.de/user/oauth2/keycloak/callback` 5. **Web origins**: `https://gitea.ladkau.de` → **Save**. 6. Go to the **Credentials** tab and copy the **Client secret** — you will need it in step 3. ### 2.5 Create the Nextcloud OIDC client 1. **Clients** → **Create client**. 2. **Client type**: OpenID Connect — **Client ID**: `nextcloud` → **Next**. 3. Turn **Client authentication** on → **Next**. 4. **Valid redirect URIs**: `https://nextcloud.ladkau.de/apps/user_oidc/code` 5. **Valid post logout redirect URIs**: `https://nextcloud.ladkau.de/*` 6. **Web origins**: `https://nextcloud.ladkau.de` → **Save**. 7. Go to the **Credentials** tab and copy the **Client secret** — you will need it in step 4. ### 2.6 Create the Vaultwarden OIDC client 1. **Clients** → **Create client**. 2. **Client type**: OpenID Connect — **Client ID**: `vaultwarden` → **Next**. 3. Turn **Client authentication** on → **Next**. 4. **Valid redirect URIs**: `https://vault.ladkau.de/*` 5. **Valid post logout redirect URIs**: `https://vault.ladkau.de/*` 6. **Web origins**: `https://vault.ladkau.de` → **Save**. 7. Go to the **Credentials** tab and copy the **Client secret**. 8. Add it to the vault as `vaultwarden_sso_client_secret` and redeploy: ```bash ansible-vault edit ansible/group_vars/all/vault.yml ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags vaultwarden --ask-vault-pass ``` ## 3. Gitea ### 3.1 Create the admin account 1. Go to `https://gitea.ladkau.de` — Gitea shows an initial configuration dialog on the first visit. 2. Scroll to the bottom of the form to the **Administrator Account Settings** section and fill in the admin username, email, and password. 3. Click **Install Gitea**. Gitea initialises the database and creates the admin account in one step. Public registration is closed — only users authenticating via Keycloak can get an account (controlled by `ALLOW_ONLY_EXTERNAL_REGISTRATION`). ### 3.2 Connect Gitea to Keycloak 1. In Gitea, go to **Site Administration** → **Identity & Access** → **Authentication Sources** → **Add Authentication Source**. 2. Set **Authentication type** to **OAuth2**. 3. Set **OAuth2 provider** to **OpenID Connect**. 4. Fill in: - **Name**: `keycloak` - **Client ID**: `gitea` - **Client secret**: the secret copied in step 2.4 - **OpenID Connect Auto Discovery URL**: `https://sso.ladkau.de/realms/ladkau/.well-known/openid-configuration` 5. Click **Add Authentication Source**. Users can now sign in via **Sign in with keycloak** on the Gitea login page. ## 4. Nextcloud The admin credentials are set via `nextcloud_admin_user` and `nextcloud_admin_password` in the vault. The first HTTP request triggers installation, which takes a minute or two. ### 4.1 Log in 1. Go to `https://nextcloud.ladkau.de` and sign in with the admin credentials from the vault. ### 4.2 Connect Nextcloud to Keycloak 1. Go to **Apps** → search for **OpenID Connect user backend** → **Download and enable**. 2. Go to **Administration settings** → **OpenID Connect** → **Add provider**. 3. Fill in: - **Identifier**: `keycloak` - **Client ID**: `nextcloud` - **Client secret**: the secret copied in step 2.5 - **Discovery endpoint**: `https://sso.ladkau.de/realms/ladkau/.well-known/openid-configuration` 4. Click **Save**. Users can now sign in to Nextcloud with their Keycloak credentials via the **Log in with keycloak** button. ## 5. Mail (Dovecot + Roundcube + Fetchmail) The mail stack runs a local Dovecot IMAP server. Roundcube connects to it internally. External IMAP clients connect to `mail.ladkau.de:993` (IMAPS — TLS terminated by Traefik). Fetchmail polls external POP3 accounts and delivers to Dovecot. Dovecot users and fetchmail accounts are configured in the vault before provisioning — see step 4 of `runbook-provisioning.md`. To add users or accounts after initial deployment, edit the vault and redeploy: ```bash ansible-vault edit ansible/group_vars/all/vault.yml ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags mail --ask-vault-pass ``` ### 5.1 Import mail from an old Dovecot server If the old server uses **Maildir** format, rsync directly: ```bash # Run on the old server — syncs to the new server's maildir volume rsync -av -e "ssh -i keys/root_cloud_ladkau_de" --progress ./* \ root@217.154.207.148:/opt/mail/maildir/alice/Maildir/ # Fix ownership for Dovecot's vmail user (UID 5000) ssh -i keys/root_cloud_ladkau_de root@217.154.207.148 "chown -R 5000:5000 /opt/mail/maildir/alice" ``` If the old server uses **mbox** format (e.g. `mail_location = mbox:~/mail:...`), see `runbook-mail-import.md` for the conversion procedure. Alternatively, use `imapsync` to copy via IMAP from the old server to the new one (works without direct server access): ```bash imapsync \ --host1 old.server.com --user1 alice --password1 oldpass \ --host2 mail.ladkau.de --user2 alice --password2 newpass \ --port2 993 --ssl2 ``` ### 5.2 Connect an IMAP client | Setting | Value | |-----------|----------------------| | Server | `mail.ladkau.de` | | Port | `993` | | Security | SSL/TLS | | Username | as set in vault | ## 6. Vaultwarden Vaultwarden is a self-hosted Bitwarden-compatible password vault. Any official Bitwarden client (browser extension, desktop, mobile) can connect to it. ### 6.1 Log in to the admin panel Go to `https://vault.ladkau.de/admin/` and enter the `vaultwarden_admin_token` from the vault. From here you can invite users and manage the instance. ### 6.2 Sign in with Keycloak SSO Users can sign in at `https://vault.ladkau.de` using the **Enterprise Single Sign-On** button — enter `https://sso.ladkau.de/realms/ladkau` as the organisation identifier. On first login Vaultwarden creates an account automatically (public self-registration is otherwise disabled). ### 6.3 Connect a Bitwarden client In any official Bitwarden client, set the **Server URL** to `https://vault.ladkau.de` before logging in. ## 7. Download server Files placed under `dl.ladkau.de` are publicly browsable and downloadable over HTTPS. Upload is via SFTP on port 2223, key auth only. ### 7.1 Generate the deploy key Run this once locally and keep both files: ```bash ssh-keygen -t ed25519 -f dl_deploy_key -N "" -C "gitea-actions" ``` - Add the contents of `dl_deploy_key.pub` to the vault as `dl_sftp_authorized_keys` and redeploy (`--tags dl`) to authorise the key. - Store `dl_deploy_key` (the private key) as a Gitea Actions secret named `DL_SSH_KEY` in any repository that needs to publish releases. ### 7.2 Upload from Gitea Actions Add a step to your workflow after building the binary: ```yaml - name: Upload release run: | echo "${{ secrets.DL_SSH_KEY }}" > /tmp/deploy_key chmod 600 /tmp/deploy_key ssh -i /tmp/deploy_key -p 2223 \ -o StrictHostKeyChecking=no \ uploader@dl.ladkau.de \ "mkdir -p files/releases/${{ gitea.ref_name }}" scp -i /tmp/deploy_key -P 2223 \ -o StrictHostKeyChecking=no \ dist/myapp-linux-amd64 \ uploader@dl.ladkau.de:files/releases/${{ gitea.ref_name }}/ rm /tmp/deploy_key ``` The file is then available at: `https://dl.ladkau.de/releases/v1.2.3/myapp-linux-amd64` ### 7.3 Connect an SFTP client | Setting | Value | |-----------|--------------------| | Host | `dl.ladkau.de` | | Port | `2223` | | User | `uploader` | | Auth | SSH key | | Root path | `files/` | ## 8. Container registry ```bash # Login docker login cr.ladkau.de # Push docker tag myimage:latest cr.ladkau.de/myimage:latest docker push cr.ladkau.de/myimage:latest # Pull docker pull cr.ladkau.de/myimage:latest ``` Registry users are managed via `registry_users` in the vault — store plaintext passwords, Ansible generates bcrypt hashes at deploy time. To add or rotate a user, edit the vault and redeploy: ```bash ansible-vault edit ansible/group_vars/all/vault.yml ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags registry --ask-vault-pass ```