280 lines
7.0 KiB
Markdown
280 lines
7.0 KiB
Markdown
# 12 — Euro-Office Deployment (CT 114)
|
|
|
|
> Status: **Planned**
|
|
> Last updated: 2026-06-12
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Euro-Office is an open-source, self-hosted online office suite (compatible with .docx, .xlsx, .pptx).
|
|
Docker image: `ghcr.io/euro-office/documentserver:latest`
|
|
Released: June 9, 2026.
|
|
|
|
Deployed in CT 114 as a privileged Docker LXC, following the standard homelab pattern.
|
|
Exposed via nginx (CT 101) at `office.spendlik.sk`, protected by Authelia (CT 102).
|
|
|
|
---
|
|
|
|
## Container Spec
|
|
|
|
| Property | Value |
|
|
|---|---|
|
|
| **CT ID** | 114 |
|
|
| **Hostname** | euro-office |
|
|
| **IP** | 192.168.1.114 |
|
|
| **Gateway** | 192.168.1.1 |
|
|
| **CPU** | 2 cores |
|
|
| **RAM** | 2 GB |
|
|
| **Disk** | 20 GB |
|
|
| **OS Template** | `debian-13-standard_13.1-2_amd64.tar.zst` |
|
|
| **Privileged** | Yes (Docker requirement) |
|
|
| **Domain** | office.spendlik.sk |
|
|
|
|
---
|
|
|
|
## Phase 1 — Create the LXC Container
|
|
|
|
In Proxmox web UI or via `pct` on the Proxmox host:
|
|
|
|
```bash
|
|
pct create 114 local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \
|
|
--hostname euro-office \
|
|
--cores 2 \
|
|
--memory 2048 \
|
|
--swap 512 \
|
|
--net0 name=eth0,bridge=vmbr0,ip=192.168.1.114/24,gw=192.168.1.1 \
|
|
--rootfs local-lvm:20 \
|
|
--unprivileged 0 \
|
|
--features nesting=1 \
|
|
--start 1 \
|
|
--onboot 1
|
|
```
|
|
|
|
> `nesting=1` is required for Docker inside LXC.
|
|
> `unprivileged 0` = privileged container.
|
|
|
|
---
|
|
|
|
## Phase 2 — Base System Setup
|
|
|
|
Enter the container:
|
|
|
|
```bash
|
|
pct enter 114
|
|
```
|
|
|
|
Update and install essentials:
|
|
|
|
```bash
|
|
apt update && apt upgrade -y
|
|
apt install -y curl nano ca-certificates gnupg lsb-release
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 3 — Install Docker
|
|
|
|
```bash
|
|
install -m 0755 -d /etc/apt/keyrings
|
|
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
chmod a+r /etc/apt/keyrings/docker.gpg
|
|
|
|
echo \
|
|
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
|
|
https://download.docker.com/linux/debian \
|
|
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
|
|
apt update
|
|
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
|
```
|
|
|
|
Verify:
|
|
|
|
```bash
|
|
docker run hello-world
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 4 — Deploy Euro-Office
|
|
|
|
Create the service directory:
|
|
|
|
```bash
|
|
mkdir -p /opt/euro-office
|
|
cd /opt/euro-office
|
|
```
|
|
|
|
Create `docker-compose.yml`:
|
|
|
|
```yaml
|
|
services:
|
|
euro-office:
|
|
image: ghcr.io/euro-office/documentserver:latest
|
|
container_name: euro-office
|
|
restart: unless-stopped
|
|
ports:
|
|
- "80:80"
|
|
environment:
|
|
- JWT_ENABLED=true
|
|
- JWT_SECRET=CHANGE_ME_STRONG_SECRET
|
|
volumes:
|
|
- ./data:/var/lib/euro-office
|
|
- ./logs:/var/log/euro-office
|
|
```
|
|
|
|
> ⚠️ Replace `CHANGE_ME_STRONG_SECRET` with a strong random secret before starting.
|
|
> Generate one with: `openssl rand -hex 32`
|
|
|
|
Start the service:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
docker compose logs -f
|
|
```
|
|
|
|
Verify it responds locally:
|
|
|
|
```bash
|
|
curl -s http://localhost/healthcheck
|
|
```
|
|
|
|
Expected: HTTP 200 or a JSON health response (check Euro-Office docs for exact endpoint).
|
|
|
|
---
|
|
|
|
## Phase 5 — nginx Reverse Proxy (CT 101)
|
|
|
|
On CT 101 (`192.168.1.10`), create `/etc/nginx/sites-available/office.spendlik.sk`:
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name office.spendlik.sk;
|
|
|
|
location / {
|
|
proxy_pass http://192.168.1.114:80;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# Euro-Office requires WebSocket support
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
|
|
# Large file uploads (documents)
|
|
client_max_body_size 100m;
|
|
proxy_read_timeout 300s;
|
|
proxy_send_timeout 300s;
|
|
}
|
|
}
|
|
```
|
|
|
|
Enable and reload:
|
|
|
|
```bash
|
|
ln -s /etc/nginx/sites-available/office.spendlik.sk /etc/nginx/sites-enabled/
|
|
nginx -t && nginx -s reload
|
|
```
|
|
|
|
Test HTTP before adding SSL:
|
|
|
|
```bash
|
|
curl -I http://office.spendlik.sk # from mobile data only (hairpin NAT limitation)
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 6 — SSL Certificate (CT 101)
|
|
|
|
```bash
|
|
certbot --nginx -d office.spendlik.sk
|
|
```
|
|
|
|
⚠️ **Always manually inspect the config after certbot runs:**
|
|
|
|
```bash
|
|
nano /etc/nginx/sites-available/office.spendlik.sk
|
|
```
|
|
|
|
Check for:
|
|
- Duplicate `server_name` directives
|
|
- Missing closing braces
|
|
- Correct `proxy_pass` still pointing to `192.168.1.114:80`
|
|
- WebSocket headers (`Upgrade`, `Connection`) preserved in both HTTP and HTTPS blocks
|
|
|
|
Reload after any manual fix:
|
|
|
|
```bash
|
|
nginx -t && nginx -s reload
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 7 — Authelia Protection (CT 102)
|
|
|
|
Add `office.spendlik.sk` to Authelia's access control rules in CT 102.
|
|
|
|
In `/etc/authelia/configuration.yml` on CT 102, add under `access_control.rules`:
|
|
|
|
```yaml
|
|
- domain: office.spendlik.sk
|
|
policy: two_factor
|
|
```
|
|
|
|
Restart Authelia:
|
|
|
|
```bash
|
|
systemctl restart authelia
|
|
```
|
|
|
|
Add the Authelia middleware to the nginx vhost in CT 101.
|
|
Refer to the existing pattern used for `automation.spendlik.sk` (CT 100) or `email.spendlik.sk` (CT 104) as the template.
|
|
|
|
---
|
|
|
|
## Phase 8 — DNS Record (WebSupport)
|
|
|
|
Add an A record for `office.spendlik.sk` pointing to the public IP (`178.41.205.8`) via the WebSupport DNS panel.
|
|
|
|
⚠️ WebSupport has **two separate DNS management pages** — update both to avoid a repeat of the previous outage.
|
|
|
|
Service ID for API operations: `15056760`
|
|
|
|
---
|
|
|
|
## Post-Deployment Checklist
|
|
|
|
- [ ] Container starts on boot (`onboot=1` confirmed in Proxmox)
|
|
- [ ] Docker service starts on container boot (`restart: unless-stopped`)
|
|
- [ ] `office.spendlik.sk` loads over HTTPS from mobile data
|
|
- [ ] Authelia 2FA prompt appears before reaching the office suite
|
|
- [ ] Document open/edit/save works end-to-end
|
|
- [ ] JWT secret changed from placeholder value
|
|
- [ ] nginx config inspected post-certbot (no duplicates, no missing braces)
|
|
- [ ] `homelab-overview.md` updated with CT 114 entry
|
|
- [ ] `00_index.md` updated — CT 114 row and next available ID bumped
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
| Symptom | Likely Cause | Fix |
|
|
|---|---|---|
|
|
| WebSocket errors / real-time editing broken | Missing `Upgrade`/`Connection` headers in nginx | Re-add WebSocket proxy headers, reload nginx |
|
|
| 502 Bad Gateway | Euro-Office container not responding | `docker compose logs` in CT 114; check if container is up |
|
|
| Large file upload fails | `client_max_body_size` too small | Increase to `200m` or higher in nginx vhost |
|
|
| Slow document loading | Insufficient RAM | Increase CT 114 RAM allocation in Proxmox |
|
|
| certbot breaks config | Known issue on this setup | Manually restore WebSocket headers and proxy_pass after cert issuance |
|
|
|
|
---
|
|
|
|
## Notes
|
|
|
|
- Euro-Office is a relatively new project (released June 2026) — check the [GitHub repo](https://github.com/euro-office/documentserver) for breaking changes before upgrading the Docker image.
|
|
- The JWT secret must match if you integrate Euro-Office with other tools (e.g., Nextcloud or a future document portal). Keep the secret backed up.
|
|
- Docker image tag: always pull `latest` for now; consider pinning to a specific version tag once the project stabilises.
|