LemonSec/PORTAINER-DEPLOY.md

300 lines
9.1 KiB
Markdown

# Deploy LemonSec via Portainer Git Repository
## Overview
This guide shows how to deploy LemonSec using Portainer's **Git Repository** feature. This is the cleanest deployment method - no manual file copying, just point Portainer to your Git repo!
## Prerequisites
- [ ] Portainer installed on Proxmox VM
- [ ] Git repository at `https://git.lemonlink.eu/impulsivefps/LemonSec`
- [ ] Cloudflare account with `lemonlink.eu` domain
- [ ] TrueNAS Scale running Nextcloud
## Step 1: Prepare Git Repository
### On your local machine (where you created the files):
```bash
# Initialize git repo (if not already)
cd LemonSec
git init
git remote add origin https://git.lemonlink.eu/impulsivefps/LemonSec.git
# Add all files
git add .
git commit -m "Initial LemonSec deployment"
# Push to your Git server
git push -u origin main
# or git push -u origin master
```
### Files that should be in the repo:
```
LemonSec/
├── docker-compose.yml ✅ Main stack
├── stack.env ✅ Environment template
├── traefik/
│ ├── traefik.yml ✅ Static config
│ └── dynamic/
│ ├── middlewares.yml ✅ Security middlewares
│ └── tls.yml ✅ TLS settings
├── authelia/
│ ├── configuration.yml ✅ Authelia config
│ └── users_database.yml ✅ Family users
├── crowdsec/
│ └── acquis.yaml ✅ Log sources
└── docs/ ✅ Documentation
```
### Files to NOT commit (already in .gitignore):
- `.env` - Contains secrets
- `secrets/` directory
- Any `*.log` files
- Backup files
## Step 2: Generate Secrets
Before deploying, generate the Authelia secrets:
### Option A: On Windows (PowerShell)
```powershell
$jwt = -join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Max 256) })
Write-Host "AUTHELIA_JWT_SECRET: $jwt"
$session = -join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Max 256) })
Write-Host "AUTHELIA_SESSION_SECRET: $session"
$storage = -join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Max 256) })
Write-Host "AUTHELIA_STORAGE_KEY: $storage"
```
### Option B: On Linux/macOS
```bash
openssl rand -hex 32 # Run 3 times for each secret
echo "AUTHELIA_JWT_SECRET: $(openssl rand -hex 32)"
echo "AUTHELIA_SESSION_SECRET: $(openssl rand -hex 32)"
echo "AUTHELIA_STORAGE_KEY: $(openssl rand -hex 32)"
```
### Option C: In Portainer (after first failed deploy)
The stack will fail to start without secrets. You can generate them inside the Portainer host:
```bash
docker run --rm authelia/authelia:latest authelia crypto rand --length 64 --hex
docker run --rm alpine openssl rand -hex 32
```
**Save these 3 secrets!** You'll need them in Step 4.
## Step 3: Deploy in Portainer
### 1. Open Portainer
Navigate to your Portainer UI: `http://your-proxmox-vm:9000`
### 2. Create Stack from Git
- Click **Stacks****Add Stack**
- Select **Repository** (not Web editor)
- Fill in:
| Field | Value |
|-------|-------|
| **Name** | `lemonsec` |
| **Repository URL** | `https://git.lemonlink.eu/impulsivefps/LemonSec` |
| **Repository Reference** | `refs/heads/main` (or `refs/heads/master`) |
| **Compose Path** | `docker-compose.yml` |
| **Authentication** | (only if repo is private) |
### 3. Environment Variables
Click **Load variables from .env file** or enter manually:
**Required Variables:**
| Variable | Example Value | Description |
|----------|---------------|-------------|
| `CF_API_EMAIL` | `youremail@example.com` | Cloudflare account email |
| `CF_API_KEY` | `your-cloudflare-global-api-key` | From Cloudflare profile |
| `TRUENAS_IP` | `192.168.1.100` | TrueNAS Scale VM IP |
| `TRUENAS_NEXTCLOUD_PORT` | `9001` | Nextcloud port on TrueNAS |
| `AUTHELIA_JWT_SECRET` | `a1b2c3d4...` (64 hex chars) | Generated secret |
| `AUTHELIA_SESSION_SECRET` | `e5f6g7h8...` (64 hex chars) | Generated secret |
| `AUTHELIA_STORAGE_KEY` | `i9j0k1l2...` (64 hex chars) | Generated secret |
**Optional Variables:**
| Variable | Default | Description |
|----------|---------|-------------|
| `TZ` | `Europe/Stockholm` | Timezone |
| `TAILSCALE_IP` | (empty) | For internal access |
| `CROWDSEC_API_KEY` | (empty) | Add after first deploy |
### 4. Deploy the Stack
- Click **Deploy the stack**
- Portainer will pull from Git and start containers
## Step 4: Initial Configuration
### 1. Check Deployment Status
In Portainer:
- **Stacks** → **lemonsec** → Check all containers are running
- Click on individual containers to view logs
### 2. Generate CrowdSec API Key
Once CrowdSec is running:
```bash
# In Portainer → Containers → crowdsec → Console
# Or SSH to host:
docker exec crowdsec cscli bouncers add traefik-bouncer
# Copy the API key output
```
### 3. Update Environment Variables
- **Stacks** → **lemonsec****Editor** tab
- Add `CROWDSEC_API_KEY=your-key-here`
- Click **Update the stack**
### 4. Configure TrueNAS Nextcloud
In TrueNAS Scale:
1. **Apps****Installed****Nextcloud****Edit**
2. **Environment Variables**:
```
NEXTCLOUD_TRUSTED_DOMAINS=cloud.lemonlink.eu
OVERWRITEPROTOCOL=https
OVERWRITEHOST=cloud.lemonlink.eu
OVERWRITECLIURL=https://cloud.lemonlink.eu
TRUSTED_PROXIES=192.168.1.50
```
(Replace 192.168.1.50 with your Proxmox VM IP)
3. **Save**
### 5. Configure Cloudflare DNS
1. Login to [Cloudflare Dashboard](https://dash.cloudflare.com)
2. Add DNS records:
| Type | Name | Target | Proxy |
|------|------|--------|-------|
| A | cloud | YOUR_PUBLIC_IP | 🟠 Proxied |
| A | auth | YOUR_PUBLIC_IP | 🟠 Proxied |
| A | *.local | YOUR_PUBLIC_IP | 🟠 Proxied |
3. **SSL/TLS****Overview**:
- Set to **Full (strict)**
- Enable **Always Use HTTPS**
## Step 5: Verify Everything Works
### Test Commands
```bash
# From any machine:
curl -I https://cloud.lemonlink.eu
# Expected: HTTP/2 200 or redirect to login
# Check Traefik dashboard (via Tailscale):
curl -k -I https://traefik.local.lemonlink.eu:8443
# Verify SSL certificate:
echo | openssl s_client -servername cloud.lemonlink.eu -connect cloud.lemonlink.eu:443 2>/dev/null | openssl x509 -noout -dates
```
### Web Access
- **Nextcloud**: `https://cloud.lemonlink.eu`
- **Authelia**: `https://auth.lemonlink.eu`
## Step 6: Add Family to Authelia (Optional)
If you enabled Authelia on Nextcloud:
1. Generate password hash:
```bash
docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'FamilyPassword123!'
```
2. Edit `authelia/users_database.yml` in your Git repo
3. Push changes
4. In Portainer: **Stacks****lemonsec****Pull and redeploy**
## Updating the Stack
### Update from Git (new commits)
1. **Stacks****lemonsec**
2. Click **Pull and redeploy**
3. Portainer pulls latest changes and restarts
### Update container images
1. **Stacks****lemonsec****Editor**
2. Click **Update the stack** (this pulls new images)
Or manually:
```bash
# SSH to host
docker-compose -f /var/lib/docker/volumes/portainer_data/_data/compose/lemonsec/docker-compose.yml pull
docker-compose -f /var/lib/docker/volumes/portainer_data/_data/compose/lemonsec/docker-compose.yml up -d
```
## Troubleshooting
### "CF_API_EMAIL not set" error
- Check all required environment variables are filled in Portainer
- Redeploy the stack
### "Bad Gateway" for Nextcloud
- Verify `TRUENAS_IP` and `TRUENAS_NEXTCLOUD_PORT` are correct
- Test: `curl http://TRUENAS_IP:TRUENAS_NEXTCLOUD_PORT` from Proxmox VM
### SSL Certificate issues
- Check Cloudflare API credentials
- Verify DNS records exist
- Check Traefik logs in Portainer
### CrowdSec not blocking
- Verify `CROWDSEC_API_KEY` is set and correct
- Check CrowdSec logs for connection errors
### Can't pull from Git
- Verify Git URL is accessible from Portainer host
- Check if repository requires authentication
- Try: `git ls-remote https://git.lemonlink.eu/impulsivefps/LemonSec` from host
## Portainer Stack vs Docker Compose
| Feature | Portainer Stacks | Docker Compose CLI |
|---------|------------------|-------------------|
| Deployment | Git/Web UI | Command line |
| Updates | One-click pull | Manual git pull |
| Environment | UI variables | .env file |
| Logs | Built-in UI | docker logs |
| Access control | Portainer RBAC | OS level |
## Backup Strategy
### Portainer Backup
Portainer automatically stores stack files in:
```
/var/lib/docker/volumes/portainer_data/_data/compose/
```
### Manual Backup
```bash
# Backup Portainer data
docker run --rm -v portainer_data:/data -v $(pwd):/backup alpine tar czf /backup/portainer-backup.tar.gz -C /data .
# Backup LemonSec volumes
docker volume ls | grep lemonsec
docker run --rm -v lemonsec_traefik-certs:/certs -v $(pwd):/backup alpine tar czf /backup/traefik-certs.tar.gz -C /certs .
```
## Next Steps
1. ✅ Verify Nextcloud is accessible
2. ✅ Test family member logins
3. ✅ Set up mobile apps
4. ✅ Enable monitoring (optional)
5. ✅ Add more services (Vaultwarden, etc.)
## Support
- **Traefik issues**: Check logs in Portainer → Containers → traefik → Logs
- **Authelia issues**: Check logs in Portainer → Containers → authelia → Logs
- **TrueNAS issues**: Check TrueNAS → Apps → Nextcloud → Logs