Files
server_cloud_ladkau_de/docs/runbook-configuration.md
T
ml f53ccbab4a Add public download server at dl.ladkau.de and improve vault validation
- New dl role — nginx serves files publicly over HTTPS with directory
  listing; atmoz/sftp on port 2223 for key-only uploads; both containers
  share /opt/dl/files volume
- check-vault.sh gains a third tier: optional secrets are validated when
  present — vaultwarden_sso_client_secret must be non-empty,
  dl_sftp_authorized_keys must begin with a recognised SSH public key prefix
- dl.ladkau.de added to DNS table, check-services.sh, and status dashboard
- Configuration runbook section 7: deploy key generation, Gitea Actions
  scp workflow example, and SFTP client connection settings
- Provisioning runbook documents the three-tier vault validation behaviour
2026-06-28 16:20:47 +02:00

11 KiB
Raw Blame History

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 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 12 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 accountPassword → 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. UsersAdd user.
  2. Fill in Username, Email, First name, Last nameCreate.
  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. ClientsCreate client.
  2. Client type: OpenID Connect — Client ID: giteaNext.
  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.deSave.
  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. ClientsCreate client.
  2. Client type: OpenID Connect — Client ID: nextcloudNext.
  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.deSave.
  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. ClientsCreate client.
  2. Client type: OpenID Connect — Client ID: vaultwardenNext.
  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.deSave.
  7. Go to the Credentials tab and copy the Client secret.
  8. Add it to the vault as vaultwarden_sso_client_secret and redeploy:
    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 AdministrationIdentity & AccessAuthentication SourcesAdd 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 backendDownload and enable.
  2. Go to Administration settingsOpenID ConnectAdd 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:

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 migrating from an existing Dovecot server, sync the Maildir directly:

# Run on the old server — syncs to the new server's maildir volume
rsync -av --progress /var/mail/alice/Maildir/ \
  root@217.154.207.148:/opt/mail/maildir/alice/Maildir/

# Fix ownership for Dovecot's vmail user (UID 5000)
ssh root@217.154.207.148 "chown -R 5000:5000 /opt/mail/maildir/alice"

Alternatively, use imapsync to copy via IMAP from the old server to the new one (works without direct server access):

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:

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:

- 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

# 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:

ansible-vault edit ansible/group_vars/all/vault.yml
ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags registry --ask-vault-pass