No description
Find a file
2026-05-30 07:42:57 +02:00
.gitignore v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_1.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_2.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_3.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_4.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_5_part1.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_5_part2.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_6.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_7.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_8_9.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
chapter_10_to_13.yml v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
hosts.ini v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
README.md v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
sync_here.sh v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00
vars.yml.example v0.5.1 CHANGED: README descritpion and roadmap 2026-05-30 07:42:57 +02:00

ansible-nextcloud

Ansible playbooks for a fully automated, production-ready Nextcloud installation on Debian 13 Trixie inside an LXC container running on Proxmox. The setup is designed to sit behind an external reverse proxy (I use Caddy) and is split into numbered chapters that are run in sequence. Why don't I just use the Nextcloud AIO? Two reasons: a) Running Nextcloud AIO in a homelab/selfhost situation will "block" ports 80 and 443 so nothing else can be (easily) hosted there. b) Since I do like Proxmox (it does take away many of the complexities of managing containers and VMs), but running Docker (required for Nextcloud AIO) in an LXC container creates networking issues that aren't easily solved, and running Nextcloud AIO in a full blown virtual machine (to avoid the LXC / Deocker networking issue) is much much more resource intensive. That's why I separated the proxy to its own machine. I strongly recommend this as it allows the usual n+1 habit of self-hosters.

With the help of an LLM I have translated these (excellent!) instructions into an Ansible playbook. https://www.c-rieger.de/nextcloud-installationsanleitung/

Still to do

  • more storage options (I specifically want to start using some kind of distributed storage system)
  • test the playbook on an actual VM to simulate actual bare metal installation, my gut feeling is that it's already there, but I haven't tested it yet.
  • mirror this Repo to my public account on my Forgejo instance (meaning learn forgejo automation/runners)

Architecture overview

Internet → Caddy (reverse proxy, TLS) → LXC container (Nginx + PHP-FPM + MariaDB + Redis)
  • Nginx handles incoming requests from Caddy on the backend node
  • PHP 8.4-FPM runs Nextcloud
  • MariaDB 11.8 stores all Nextcloud data
  • Redis provides distributed locking and session caching (APCu for local cache)
  • Gotify receives SSH login and system alert notifications
  • Notify-Push (high-performance push daemon) backs the Nextcloud client sync

Prerequisites

  • Ansible installed on your control machine
  • A target Debian 13 Trixie LXC container accessible over SSH as root
  • A Caddy reverse proxy already running somewhere on your local network
  • A Gotify instance for notifications (chapter 7)

Setup

1. Configure the inventory

Edit hosts.ini and replace the hostname, IP, and user with your own:

[nextcloud_servers]
your-host.example.com ansible_host=192.168.x.x ansible_user=root

2. Configure variables

Copy the example vars file and fill in your own values:

cp vars.yml.example vars.yml

Then edit vars.yml:

Variable Description
server_hostname Friendly name for the Nextcloud instance
server_fqdn Public FQDN managed by your Caddy proxy
caddy_proxy_ip Local IP of your Caddy server (for trusted proxy config)
ntp_servers List of NTP servers
php_ver PHP version to install (default: 8.4)
nc_admin_user Nextcloud admin username
nc_admin_pass Nextcloud admin password
nextcloud_db_name MariaDB database name
nextcloud_db_user MariaDB database user
nextcloud_db_pass MariaDB database password
redis_password Redis authentication password
gotify_url URL of your Gotify instance
gotify_token API token from your Gotify application

vars.yml is listed in .gitignore and will never be committed.


Running the playbooks

Run each chapter in order. Every chapter builds on the previous one.

Of you're doing this on Proxmox I recommend creating a snapshot after running each playbook.

# Chapter 1 — Base system, Nginx, PHP 8.4
ansible-playbook -i hosts.ini chapter_1.yml

# Chapter 2 — PHP 8.4 extensions and optimizations
ansible-playbook -i hosts.ini chapter_2.yml

# Chapter 3 — MariaDB 11.8 installation and hardening
ansible-playbook -i hosts.ini chapter_3.yml

# Chapter 4 — Redis caching layer
ansible-playbook -i hosts.ini chapter_4.yml

# Chapter 5 — Nextcloud core installation and initial configuration
ansible-playbook -i hosts.ini chapter_5_part1.yml
ansible-playbook -i hosts.ini chapter_5_part2.yml

# Chapter 6 — Reverse proxy alignment layer (no credentials required)
ansible-playbook -i hosts.ini chapter_6.yml

# Chapter 7 — Gotify alerting (SSH login notifications)
ansible-playbook -i hosts.ini chapter_7.yml

# Chapters 8 & 9 — Performance optimizations and push service
ansible-playbook -i hosts.ini chapter_8_9.yml

# Chapters 1013 — Notify-Push daemon, bash aliases, sysctl network hardening
ansible-playbook -i hosts.ini chapter_10_to_13.yml

Security notes

  • vars.yml and notes.txt are both in .gitignore. Do not remove them from it.
  • All credentials in the playbooks are referenced via variables — no secrets are hardcoded in the chapter files.
  • The target container runs as root — tighten this if your environment requires it.