Updated text

This commit is contained in:
Wesley R. Elsberry 2025-11-19 13:37:01 -05:00
parent 99996be1a3
commit 7ac09ff6da
1 changed files with 311 additions and 1 deletions

312
README.md
View File

@ -1,3 +1,313 @@
# VHostLoom
Software stack for virtual host serving based on Docker + Traefik + Authelia.
A Docker Hosting Framework: Traefik + Authelia + Modular Sites
This repository provides a reusable framework for running multiple
virtual-hosted web services on a single server using:
- [Traefik](https://traefik.io/) as a reverse proxy and TLS terminator
- [Authelia](https://www.authelia.com/) as an SSO / authentication gateway
- Docker Compose for container orchestration
- Modular per-site stacks with bind-mounted volumes
The design goals are:
> **Add or change sites without constantly editing core proxy config**
> and keep application data available natively on the host filesystem.
Under the view that hacking is inevitable, it seemed to me that making
it so a hacker has to hack each container separately makes the system
less brittle and less exposed to threats like ransomware. With modest
backup discipline, this system should permit porting or getting back
up expeditiously.
---
## Features
- **Core proxy stack** (`core-proxy/`) with Traefik and Authelia
- Lets Encrypt HTTP-01 certificates
- Traefik dashboard at `https://traefik.example.com`, protected by Authelia
- Authelia at `https://auth.example.com` for login
- **Modular site stacks** under `sites/`:
- `static-site`: static file hosting at `https://example.com`
- `wordpress-site`: WordPress at `https://example.com/wp`
- `forgejo`: Forgejo (Git hosting) + CI runner at `https://git.example.com`
- `nextcloud`: Nextcloud cloud storage at `https://cloud.example.com`
- **Security model**
- Default-deny firewall template (`firewall/nftables.conf.example`)
- Only 80/443 exposed publicly (and optionally a few others)
- Authelia used to put an extra auth layer in front of sensitive apps
- Easy integration with ZeroTier or other VPNs for “VPN-only” services
- **Host-friendly data layout**
- Each sites data lives in bind-mounted directories under `sites/`
- Easy to back up, rsync, or inspect without entering containers
---
## Prerequisites
- Linux host (e.g., Ubuntu Server 22.04+)
- Docker and Docker Compose plugin installed
- A public IP address (static or effectively static)
- Control over DNS records for your domains
For HTTPS, youll need DNS `A` (and/or `AAAA`) records pointing to your server:
- `example.com` → server IP
- `auth.example.com` → server IP
- `traefik.example.com` → server IP
- `git.example.com` → server IP
- `cloud.example.com` → server IP
---
## Quick Start
1. **Clone the repo**
```bash
git clone https://example.com/your/hosting-framework.git
cd hosting-framework
````
2. **Create shared Docker network**
```bash
docker network create traefik_proxy
```
3. **Prepare Traefik ACME storage**
```bash
cd core-proxy
mkdir -p traefik/dynamic
touch traefik/acme.json
chmod 600 traefik/acme.json
```
4. **Edit core config**
* `core-proxy/docker-compose.yml`
* Change `admin@example.com` to a real email
* Adjust domains in Traefik labels for your use case
* `core-proxy/traefik/dynamic/authelia.yml`
* Set `auth.example.com` (or equivalent)
* `core-proxy/authelia/configuration.yml`
* Change `example.com`, secrets, etc.
* `core-proxy/authelia/users_database.yml`
* Generate a password hash:
```bash
docker run --rm authelia/authelia:latest authelia hash-password 'yourpassword'
```
Paste the hash into `password:`.
5. **Start the core stack**
```bash
cd core-proxy
docker compose up -d
```
6. **Configure DNS**
Create DNS records pointing your domains to the servers public IP.
Lets Encrypt will fail if DNS is wrong or not propagated.
7. **Bring up example sites**
```bash
# Static site
cd ../sites/static-site
docker compose up -d
# WordPress
cd ../wordpress-site
docker compose up -d
# Forgejo
cd ../forgejo
docker compose up -d
# Nextcloud
cd ../nextcloud
docker compose up -d
```
8. **Test**
* `https://traefik.<your-domain>` → Authelia login → Traefik dashboard
* `https://auth.<your-domain>` → Authelia portal
* `https://example.com` → static site
* `https://example.com/wp` → WordPress installer
* `https://git.<your-domain>` → Authelia login → Forgejo setup
* `https://cloud.<your-domain>` → Authelia login → Nextcloud setup
---
## Rationale & Design
### Separation of concerns
* **Core proxy** (Traefik + Authelia) is stable and rarely changed.
* **Sites** live in separate directories with their own `docker-compose.yml`.
* **Firewall** is independent of Docker and enforces network boundaries.
This makes it easy to:
* Add new virtual hosts (just add a new `sites/<name>/docker-compose.yml`)
* Share the framework without embedding secrets
* Back up only what matters (`sites/**`, Authelia DB, maybe Traefik `acme.json`)
### Minimal coupling
The only shared assumptions between stacks:
* A Docker network named `traefik_proxy`
* Authelias forward-auth middleware named `authelia-auth@file`
* Traefiks Lets Encrypt resolver named `letsencrypt`
Everything else is per-site.
---
## Configuration Details
### Traefik labels
Each service defines its routing behavior entirely via labels:
* Match host and path:
`traefik.http.routers.<name>.rule=Host(`example.com`) && PathPrefix(`/wp`)`
* Bind to entrypoint:
`...entrypoints=web` or `websecure`
* Enable HTTPS / certificates:
`...tls.certresolver=letsencrypt`
* HTTP→HTTPS redirect using a middleware:
* Define middleware:
`traefik.http.middlewares.foo-https-redirect.redirectscheme.scheme=https`
* Attach it to an HTTP router:
`traefik.http.routers.foo-http.middlewares=foo-https-redirect`
### Authelia protection
To require login via Authelia before an app:
```yaml
labels:
- "traefik.http.routers.<name>-https.middlewares=authelia-auth@file"
```
Remove or comment this label to make a site public.
### Authelia users
Defined in `core-proxy/authelia/users_database.yml`:
```yaml
users:
admin:
displayname: "Admin User"
email: "admin@example.com"
groups: [admins]
password: "<argon2id hash>"
```
You can use groups and more complex access_control rules if desired; the default config in this repo simply treats any authenticated user as allowed.
---
## Security & Firewall
The `firewall/nftables.conf.example` file contains a default-deny firewall with:
* Loopback and established connections allowed
* ICMP allowed (optional but recommended)
* SSH allowed only over a VPN interface (e.g., ZeroTier)
* 80/443 open for Traefik
* Example ports restricted to the VPN interface
You can adapt it and enable with:
```bash
sudo cp firewall/nftables.conf.example /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo systemctl enable nftables
```
Always test SSH access before locking down too far.
---
## Maintenance
### Updating containers
For each stack:
```bash
cd core-proxy
docker compose pull
docker compose up -d
cd ../sites/<site-name>
docker compose pull
docker compose up -d
```
### Backups
At minimum, back up:
* `core-proxy/traefik/acme.json` (certificates)
* `core-proxy/authelia/` (configuration + DB)
* `sites/**/` data directories:
* `sites/static-site/html/`
* `sites/wordpress-site/db/` and `wp/`
* `sites/forgejo/data/`, `db/`, `runner/`
* `sites/nextcloud/nextcloud/`, `db/`, `redis/`
Use `rsync`, `borg`, `restic`, or your favorite solution.
### Logs
* Traefik logs: stdout (use `docker logs traefik` or a log collector)
* Authelia logs: stdout + `notification.log` (if configured)
* Site logs: as exposed via each container
---
## Extending the Framework
To add a new site:
1. Create `sites/<new-site>/docker-compose.yml`.
2. Attach it to `traefik_proxy`.
3. Add Traefik labels for hostnames, HTTPS, redirect, and optionally Authelia.
4. Bind volumes for data so they live on the host.
5. `docker compose up -d` in that directory.
6. Add DNS records for the new hostname(s).
You never need to edit the core proxy configuration for new sites.
---
## License
This software is licensed under the MIT license.
## Disclaimer
Beyond the MIT license statement, this software was produced by
iterative prompting of OpenAI's GPT 5.1 LLM.