ml 7c690be891 Fix Dovecot passwd-file format and document mbox mail import
- passwd.j2: append '::::::' so entries have full 8-field passwd format.
  Without this Dovecot's userdb lookup fails ('user is missing userdb
  info') even though passdb auth succeeds, causing login to return 401.
- main.yml: fix passwd file mode from 0640 to 0644 so Dovecot can read it.
- Add runbook-mail-import.md: full procedure for migrating mbox-format mail
  (old Dovecot server with ~/mail/ flat files) to Maildir++ including the
  conversion script that handles fetchmail >From envelope lines.
- runbook-configuration.md: reference new runbook in the mail import section.
2026-07-01 06:58:25 +02:00
2026-06-27 14:13:23 +02:00

Info:

Server: Strato STRATO VPS Linux VC4-8 Order Number: 9478462

Customer Number: 73171334
Customer Login: https://www.strato.de/apps/CustomerService

Cores: 4 Cores
RAM: 8 GB RAM
Storage: 240 HDD

IPv4: 217.154.207.148
IPv6: 2a01:239:35b:c400::1

OS: Ubuntu 24.04 LTS

DNS Names: cloud.ladkau.de gitea.ladkau.de nextcloud.ladkau.de sso.ladkau.de mail.ladkau.de cr.ladkau.de k8s.ladkau.de

Purpose:

This repository tracks the complete server configuration so the server can be fully reinstalled from scratch using only this repo. Every configuration change must be committed here. The git history serves as the change log.

Architecture:

Provisioning: Ansible Ansible playbooks configure the OS and deploy all services. Roles are idempotent — re-running them brings the server back to the desired state without side effects. The master playbook is ansible/site.yml.

Service runtime: Docker Compose Each service runs as a Docker Compose stack. Compose files live inside their respective Ansible roles (roles//files/docker-compose.yml). This keeps service definition and deployment config together.

Reverse proxy / TLS: Traefik Traefik is the single entry point for all HTTP/HTTPS traffic. It runs as a Docker Compose service and routes to other containers via Docker labels. TLS certificates are issued automatically via Let's Encrypt (ACME).

Repo layout:

ansible/
	inventory.ini        # host address and connection vars
	site.yml             # master playbook — runs all roles in order
	group_vars/all.yml   # shared variables (domains, image versions, ...)
	roles/
		base/            # OS hardening, non-root user, SSH, ufw firewall
		docker/          # Docker Engine + Compose plugin install
		traefik/         # reverse proxy, TLS termination
		gitea/           # self-hosted Git
		nextcloud/       # file storage and collaboration
		sso/             # Single Sign-On
		mail/            # mail server
		registry/        # container registry (cr.ladkau.de)
		k8s/             # k3s Kubernetes node
docs/
	runbook-provisioning.md  # step-by-step reinstall instructions
	runbook-configuration.md # first-run service configuration
scripts/
	run-bootstrap.sh     # bootstrap deploy user on a fresh server
	bootstrap-deploy-user.sh  # runs on server as root — creates deploy user
	check-vault.sh       # verify vault.yml has all required secrets
keys/
	*.pub                # public SSH keys (private keys are gitignored)

SSH keys:

root_cloud_ladkau_de      — root access (initial setup only)
notroot_cloud_ladkau_de   — non-root deploy user (used by Ansible)
S
Description
Infrastructure-as-code for a Strato VPS at cloud.ladkau.de.
Readme MIT 1.7 MiB
Languages
Jinja 78.2%
Shell 19.4%
HTML 1.4%
Dockerfile 1%