Files
jmp-stack/README.md
2026-01-10 23:34:39 +01:00

393 lines
8.2 KiB
Markdown

# JMP Server Infrastructure
Docker Compose-based infrastructure deployment for self-hosted services.
## Prerequisites
- Docker and Docker Compose installed
- A domain with DNS records pointing to your server
- Ports 80, 443, and 2222 (SSH for Gitea) open
## Quick Start
1. Create the `.env` file with required variables (see Environment Variables section)
2. Set up ACME storage: `touch acme.json && chmod 600 acme.json`
3. Start services: `./start.sh` or `docker compose up -d`
4. Stop services: `./stop.sh` or `docker compose down`
## Environment Variables
Create a `.env` file in the project root with the following variables:
```bash
# General
DOMAIN=yourdomain.com
PUID=1000
PGID=1000
# Gitea Database
POSTGRES_HOST_GITEA=gitea-db
POSTGRES_NAME_GITEA=gitea
POSTGRES_USER_GITEA=gitea
POSTGRES_PASSWORD_GITEA=<SECURE_PASSWORD>
# Gitea Runner
GITEA_INSTANCE_URL=https://gitea.yourdomain.com
GITEA_RUNNER_REGISTRATION_TOKEN=<TOKEN_FROM_GITEA>
GITEA_RUNNER_NAME=runner-1
GITEA_RUNNER_LABELS=ubuntu-latest:docker://node:16-bullseye
# Bookstack Database
MYSQL_HOST_BOOKSTACK=bookstack-db
MYSQL_PORT_BOOKSTACK=3306
MYSQL_NAME_BOOKSTACK=bookstack
MYSQL_USER_BOOKSTACK=bookstack
MYSQL_PASSWORD_BOOKSTACK=<SECURE_PASSWORD>
MYSQL_TZ_BOOKSTACK=Europe/Rome
# Bookstack App
BOOKSTACK_APP_URL=https://bookstack.yourdomain.com
BOOKSTACK_APP_KEY=<GENERATED_KEY>
# Vikunja
POSTGRES_NAME_VIKUNJA=vikunja
POSTGRES_USER_VIKUNJA=vikunja
POSTGRES_PASSWORD_VIKUNJA=<SECURE_PASSWORD>
VIKUNJA_JWT_SECRET=<RANDOM_SECRET>
```
---
## Traefik
Reverse proxy and load balancer handling routing and HTTPS/TLS via Let's Encrypt.
**URL:** `https://traefik.YOUR_DOMAIN`
### Setup
1. Create the ACME storage file:
```bash
touch acme.json && chmod 600 acme.json
```
2. Update the dashboard Basic Auth in `docker-compose.yaml`:
```bash
# Generate a password hash
echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g
```
Replace the `traefik.http.middlewares.auth.basicauth.users` label value.
3. Update the ACME email in `traefik.yml` (line 54).
---
## Gitea
Git repository hosting with PostgreSQL backend and CI/CD runner support.
**URL:** `https://gitea.YOUR_DOMAIN`
**SSH:** `ssh://git@YOUR_DOMAIN:2222`
### Setup
1. Set the database environment variables in `.env`
2. Start the services
3. Access the web interface to complete initial setup
4. Create the first admin user
### Admin
User registration is disabled by default.
Use admin user to add new users from web UI
### Gitea Runner
To enable CI/CD:
1. In Gitea, go to **Site Administration → Actions → Runners**
2. Click **Create new Runner** and copy the registration token
3. Set `GITEA_RUNNER_REGISTRATION_TOKEN` in `.env`
4. Restart the runner container
---
## Bookstack
Documentation wiki with MariaDB backend.
**URL:** `https://bookstack.YOUR_DOMAIN`
### Setup
1. Generate an APP_KEY:
```bash
docker run -it --rm --entrypoint /bin/bash lscr.io/linuxserver/bookstack:latest appkey
```
2. Add the key to `BOOKSTACK_APP_KEY` in `.env`
3. Set database environment variables in `.env`
4. Start the services
### First Login
- **Email:** admin@admin.com
- **Password:** password
*Change these immediately after first login.*
### Restore Backup From Different Url
Run a shell in bookstack container. For Example
```
docker exec -it bookstack-container sh
```
Then:
```
php artisan bookstack:update-url https://docs.jmpgames.it https://bookstack.jmpgames.it
php artisan migrate
```
---
## Homepage
Dashboard for service discovery and monitoring.
**URL:** `https://home.YOUR_DOMAIN` (or `http://localhost:3001`)
### Setup
A `homepage/` directory is created after first boot containing configuration files.
To enable Docker container auto-detection, edit `homepage/docker.yaml`:
```yaml
my-docker:
socket: /var/run/docker.sock
```
Services with `homepage.*` labels in `docker-compose.yaml` will appear automatically.
---
## Vikunja
Task management and to-do lists with PostgreSQL backend.
**URL:** `https://vikunja.YOUR_DOMAIN`
### Setup
1. Set the database environment variables in `.env`
2. Generate a random JWT secret:
```bash
openssl rand -base64 32
```
3. Set `VIKUNJA_JWT_SECRET` in `.env`
4. Start the services
5. Register the first user (becomes admin)
### Admin
Web UI user registration is disabled.
To add new user:
```
# Example for Docker
docker exec vikunja /app/vikunja/vikunja user create -u "newuser" -e "user@example.com" -p "your_password"
```
To delete a user:
```
# Example for Docker
docker exec vikunja /app/vikunja/vikunja user list # Get user id
docker exec -it vikunja /app/vikunja/vikunja user delete <id> -n
```
---
## Radicale
CalDAV and CardDAV server for calendars and contacts sync.
**URL:** `https://radicale.YOUR_DOMAIN`
### Setup
1. Create the users file:
```bash
touch radicale/config/users
```
2. Add users with bcrypt passwords:
```bash
htpasswd -Bc /dev/stdout USERNAME
```
3. Append the output to `radicale/config/users`:
```
username:$2y$05$...
```
### Client Configuration
Use the following URL for CalDAV/CardDAV clients:
```
https://radicale.YOUR_DOMAIN/USERNAME/
```
**Supported clients:** Thunderbird, DAVx5 (Android), iOS Calendar/Contacts, Evolution, GNOME Calendar.
---
## OpenCloud
Nextcloud-based cloud storage platform.
**URL:** `https://opencloud.YOUR_DOMAIN`
### Setup
1. Navigate to the OpenCloud compose directory:
```bash
cd opencloud-compose
```
2. Create the environment file:
```bash
cp .env.example .env
```
3. Edit `.env` with required settings:
```bash
INSECURE=true
OC_DOCKER_IMAGE=opencloudeu/opencloud-rolling
OC_DOMAIN=opencloud.yourdomain.com
INITIAL_ADMIN_PASSWORD=<SECURE_PASSWORD>
LOG_PRETTY=true
OC_CONFIG_DIR=./opencloud/config
OC_DATA_DIR=./opencloud/data
```
4. Create data directories:
```bash
mkdir -p opencloud/{config,data}
chown -R 1000:1000 opencloud
```
5. For external proxy setup (using the main Traefik), set:
```bash
COMPOSE_FILE=docker-compose.yml:external-proxy/opencloud.yml
```
6. Start OpenCloud:
```bash
docker compose up -d
```
### References
- [Behind External Proxy](https://github.com/opencloud-eu/opencloud-compose?tab=readme-ov-file#behind-external-proxy)
- [GitHub Discussion](https://github.com/orgs/opencloud-eu/discussions/533)
---
## Website
Frontend web application (requires Gitea registry access).
**URL:** `https://YOUR_DOMAIN`
### Setup
The website service is in the `after` profile and requires the container image to be built and pushed to the Gitea registry first.
Start with:
```bash
docker compose --profile after up -d
```
---
## Backup & Restore
Automated cold backups using [docker-volume-backup](https://github.com/offen/docker-volume-backup).
### How It Works
- **Daily backups** at 3:00 AM (configurable in `backup.env`)
- **Cold backups**: Database containers are stopped during backup to ensure data consistency
- **Retention**: Backups older than 7 days are automatically deleted
- **Storage**: Local backups in `./backups/` (optionally to S3/SSH/WebDAV)
### Backed Up Data
| Service | Data |
|---------|------|
| Gitea | Application data + PostgreSQL database |
| Bookstack | Application data + MariaDB database |
| Vikunja | Files + PostgreSQL database |
| Radicale | CalDAV/CardDAV data |
| Homepage | Dashboard configuration |
### Manual Backup
```bash
./backup.sh
```
### Restore from Backup
```bash
# List available backups
./restore.sh
# Restore specific backup
./restore.sh backup-2025-01-05T03-00-00.tar.gz
```
### Configuration
Edit `backup.env` to configure:
- **Schedule**: `BACKUP_CRON_EXPRESSION` (default: daily at 3 AM)
- **Retention**: `BACKUP_RETENTION_DAYS` (default: 7 days)
- **Encryption**: Uncomment `GPG_PASSPHRASE` for encrypted backups
- **Remote storage**: Configure S3, SSH, or WebDAV for offsite backups
- **Notifications**: Configure Discord, Slack, or email alerts
### Remote Backup (S3 Example)
Add to `backup.env`:
```bash
AWS_S3_BUCKET_NAME=your-bucket
AWS_S3_PATH=jmp-server
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_ENDPOINT=s3.amazonaws.com
```
### View Backup Logs
```bash
docker compose logs -f backup
```
---
## Logs
Access logs are stored in `./logs/traefik/` for Fail2Ban integration.
View service logs:
```bash
docker compose logs -f [service_name]
```