From 37b00787b95968032870f8b98b8047b3fe82840c Mon Sep 17 00:00:00 2001 From: jpmvaz Date: Sun, 13 Sep 2026 20:27:51 +0100 Subject: [PATCH] v_11 --- Documize/README.md | 443 ++++++++++++++++++ Documize/docker-compose.yml | 134 ++++++ Documize/env.template | 59 +++ Gitea/.env | 28 ++ Gitea/README.md | 95 ++++ Gitea/docker-compose.yml | 51 ++ Homar_Martinhal/docker-compose.yml | 15 + Homar_Meu/docker-compose.yml | 15 + Jellyfin/README.md | 374 +++++++++++++++ Jellyfin/docker-compose.yml | 79 ++++ Netbox Docker/.env | 51 ++ Netbox Docker/docker-compose.yml | 144 ++++++ Netbox Docker/files.zip | Bin 0 -> 2636 bytes Open_Project/docker-compose.yml | 302 ++++++++++++ Open_Project/docker-compose_OLD.yml | 280 +++++++++++ Open_Project/env.example | 149 ++++++ UnPoller + InfluxDB 2.x + Grafana/.env | 38 ++ .../docker-compose.yml | 67 +++ Uptime_Kuma/docker-compose.yml | 9 + Vikunja/.env.example | 75 +++ Vikunja/docker-compose.yml | 98 ++++ Vikunja/env.example | 75 +++ WikiJS/wikiJS.zip | Bin 0 -> 4544 bytes 23 files changed, 2581 insertions(+) create mode 100644 Documize/README.md create mode 100644 Documize/docker-compose.yml create mode 100644 Documize/env.template create mode 100644 Gitea/.env create mode 100644 Gitea/README.md create mode 100644 Gitea/docker-compose.yml create mode 100644 Homar_Martinhal/docker-compose.yml create mode 100644 Homar_Meu/docker-compose.yml create mode 100644 Jellyfin/README.md create mode 100644 Jellyfin/docker-compose.yml create mode 100644 Netbox Docker/.env create mode 100644 Netbox Docker/docker-compose.yml create mode 100644 Netbox Docker/files.zip create mode 100644 Open_Project/docker-compose.yml create mode 100644 Open_Project/docker-compose_OLD.yml create mode 100644 Open_Project/env.example create mode 100644 UnPoller + InfluxDB 2.x + Grafana/.env create mode 100644 UnPoller + InfluxDB 2.x + Grafana/docker-compose.yml create mode 100644 Uptime_Kuma/docker-compose.yml create mode 100644 Vikunja/.env.example create mode 100644 Vikunja/docker-compose.yml create mode 100644 Vikunja/env.example create mode 100644 WikiJS/wikiJS.zip diff --git a/Documize/README.md b/Documize/README.md new file mode 100644 index 0000000..a210798 --- /dev/null +++ b/Documize/README.md @@ -0,0 +1,443 @@ +
+ +# πŸ“š Documize Community β€” Docker Deployment + +**Self-hosted knowledge management Β· v5.14.0 Β· MySQL 8 Β· Docker Compose** + +[![Documize](https://img.shields.io/badge/Documize-v5.14.0-2563EB?style=for-the-badge&logo=gitbook&logoColor=white)](https://github.com/documize/community) +[![MySQL](https://img.shields.io/badge/MySQL-8.0-4479A1?style=for-the-badge&logo=mysql&logoColor=white)](https://hub.docker.com/_/mysql) +[![Docker](https://img.shields.io/badge/Docker-Compose-2496ED?style=for-the-badge&logo=docker&logoColor=white)](https://docs.docker.com/compose/) +[![License](https://img.shields.io/badge/License-GNU_AGPL_v3-22C55E?style=for-the-badge)](https://www.gnu.org/licenses/agpl-3.0.en.html) + +A production-ready Docker Compose stack for [Documize Community](https://github.com/documize/community) β€” an open-source, self-hosted alternative to Confluence, built with Go + EmberJS. + +[Quick Start](#-quick-start) Β· [Configuration](#-configuration) Β· [Architecture](#-architecture) Β· [Operations](#-day-to-day-operations) Β· [Troubleshooting](#-troubleshooting) + +
+ +--- + +## ✨ Features + +- **Single binary deployment** β€” Documize ships as one statically-linked Go binary; no runtime dependencies beyond a database +- **Zero reboot-loop risk** β€” Init-container pattern separates the one-time binary download from the always-running app container +- **Full-text search** β€” MySQL configured with `ft-min-word-len=3` and `utf8mb4` collation as required by Documize +- **Secret-free Compose file** β€” All credentials live in `.env`; `docker-compose.yml` contains no plaintext passwords +- **Named volume persistence** β€” Both database data and the app binary survive container restarts and upgrades +- **SMTP support** β€” Optional email notifications configured entirely via environment variables + +--- + +## πŸ“‹ Prerequisites + +| Requirement | Minimum version | +|---|---| +| Docker Engine | 24.0+ | +| Docker Compose | v2.20+ (included with Docker Desktop) | +| Available port | TCP `5001` (configurable) | +| RAM | 512 MB free (1 GB recommended) | +| Disk | 2 GB free | +| Internet | Required on first start to download the Documize binary (~25 MB) | + +--- + +## πŸš€ Quick Start + +```bash +# 1. Clone or download this repository +git clone https://github.com/your-org/documize-docker.git +cd documize-docker + +# 2. Create your environment file from the template +cp .env.template .env + +# 3. Generate and set your secrets +echo "MYSQL_PASSWORD=$(openssl rand -base64 24)" +echo "MYSQL_ROOT_PASSWORD=$(openssl rand -base64 24)" +echo "DOCUMIZE_SALT=$(openssl rand -hex 32)" +# Paste each value into .env + +# 4. Protect the file and add to .gitignore +chmod 600 .env +echo ".env" >> .gitignore + +# 5. Start the stack +docker compose up -d + +# 6. Watch the logs until Documize is ready (~30–60 s) +docker compose logs -f + +# 7. Open the setup wizard +open http://localhost:5001 +``` + +> **Activation key** β€” The Community edition requires a free activation key. Register your email at [documize.com/community/get-started](https://www.documize.com/community/get-started) to receive one instantly. + +--- + +## πŸ— Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Docker Host β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” exits 0 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ documize-initβ”‚ ──────────► β”‚ app_bin volume β”‚ β”‚ +β”‚ β”‚ (alpine:3.19)β”‚ downloads β”‚ /app/bin/documize β”‚ β”‚ +β”‚ β”‚ restart: no β”‚ binary once β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ mounts β”‚ +β”‚ β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ documize-app (alpine:3.19) β”‚ β”‚ +β”‚ β”‚ restart: unless-stopped β”‚ β”‚ +β”‚ β”‚ exec /app/bin/documize │◄───┼── :5001 +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ TCP 3306 (internal only) β”‚ +β”‚ β–Ό β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ documize-db (mysql:8) β”‚ β”‚ +β”‚ β”‚ restart: unless-stopped β”‚ β”‚ +β”‚ β”‚ healthcheck: mysqladmin ping β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ db_data β”‚ β”‚ +β”‚ β”‚ volume β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Startup Sequence + +1. `documize-init` starts β†’ installs `curl` β†’ downloads binary to `app_bin` volume β†’ **exits 0** +2. `documize-db` starts β†’ MySQL initialises β†’ healthcheck passes βœ… +3. `documize-app` starts (only after both conditions above are met) β†’ exec's binary β†’ serves on `:5001` + +### Why the Init-Container Pattern? + +Downloading a binary inside the main container's command creates a reboot loop: any failure causes Docker to restart the container, which retriggers the download. Separating the download into a `restart: "no"` init container means the main app container only ever does one thing β€” run the binary β€” with no network calls or failure modes on restart. + +--- + +## βš™οΈ Configuration + +### File Layout + +``` +documize-docker/ +β”œβ”€β”€ docker-compose.yml # Stack definition β€” references ${VARS} from .env +β”œβ”€β”€ .env.template # Template β€” copy to .env and fill in secrets +β”œβ”€β”€ .env # Your secrets β€” NEVER commit this file +└── README.md # This file +``` + +### Step 1 β€” Set up your `.env` file + +Copy the template and fill in all values marked ⚠️: + +```bash +cp .env.template .env +``` + +### Step 2 β€” Environment Variable Reference + +#### πŸ—„οΈ MySQL Database + +| Variable | Default | Required | Description | +|---|---|---|---| +| `MYSQL_DATABASE` | `documize` | Pre-filled | Database name created on first start | +| `MYSQL_USER` | `documize` | Pre-filled | MySQL user Documize connects as | +| `MYSQL_PASSWORD` | β€” | ⚠️ **Change** | Password for the `documize` MySQL user. Must match the DSN in `DOCUMIZEDB`. Generate: `openssl rand -base64 24` | +| `MYSQL_ROOT_PASSWORD` | β€” | ⚠️ **Change** | MySQL root password for admin access. Not used by Documize. Generate: `openssl rand -base64 24` | + +#### πŸš€ Documize Application + +| Variable | Default | Required | Description | +|---|---|---|---| +| `DOCUMIZE_PORT` | `5001` | Pre-filled | Host port Documize is exposed on. Change the left side of the `ports` mapping. | +| `DOCUMIZE_SALT` | β€” | ⚠️ **Change** | Password hashing salt. Must be β‰₯ 32 random characters. Generate: `openssl rand -hex 32`. **Set once β€” never change after first run.** | + +#### πŸ“§ SMTP Email (Optional) + +All five SMTP variables must be set to enable email. Leave `SMTP_HOST` blank to disable. + +| Variable | Default | Description | +|---|---|---| +| `SMTP_HOST` | _(blank)_ | SMTP server hostname (e.g. `smtp.gmail.com`) | +| `SMTP_PORT` | `587` | SMTP port β€” `587` for STARTTLS, `465` for SSL/TLS | +| `SMTP_USER` | _(blank)_ | SMTP authentication username | +| `SMTP_PASSWORD` | _(blank)_ | SMTP authentication password or app-specific password | +| `SMTP_SENDER` | `documize@example.com` | From address on outgoing emails | + +--- + +### MySQL Startup Flags + +These flags are passed to MySQL 8 via the `command` key in `docker-compose.yml` and are **required** for Documize to function correctly. Do not remove them. + +| Flag | Value | Purpose | +|---|---|---| +| `--character-set-server` | `utf8mb4` | Full Unicode support including emoji | +| `--collation-server` | `utf8mb4_unicode_ci` | Case-insensitive Unicode collation | +| `--ft-min-word-len` | `3` | Minimum word length for full-text search index β€” Documize requires exactly `3` | +| `--innodb-file-per-table` | `1` | Each table in its own `.ibd` file β€” improves storage reclaim | +| `--max-allowed-packet` | `256M` | Maximum packet size for large document imports | + +--- + +### Changing the Host Port + +Edit the `ports` mapping in `docker-compose.yml` **and** the `DOCUMIZE_PORT` value in `.env`: + +```yaml +# docker-compose.yml +ports: + - "${DOCUMIZE_PORT}:5001" # host:container +``` + +```bash +# .env +DOCUMIZE_PORT=8080 +``` + +--- + +### Named Volumes + +| Volume | Mount path | Purpose | +|---|---|---| +| `db_data` | `/var/lib/mysql` | All MySQL data β€” content, users, settings. Never delete unless wiping everything. | +| `app_bin` | `/app/bin` | The Documize binary. Safe to delete to force a re-download on next start. | + +--- + +## πŸ”’ Security + +### Checklist + +- [ ] `MYSQL_PASSWORD` changed from placeholder +- [ ] `MYSQL_ROOT_PASSWORD` changed from placeholder +- [ ] `DOCUMIZE_SALT` generated with `openssl rand -hex 32` +- [ ] `.env` added to `.gitignore` +- [ ] `.env` permissions set to `600` (`chmod 600 .env`) +- [ ] MySQL `ports` mapping removed from `docker-compose.yml` (production only) +- [ ] Documize placed behind a reverse proxy with TLS (production only) + +### Remove the Database Port Mapping (Production) + +The `db` service does not expose a port by default β€” MySQL is only reachable within the `documize_net` Docker network. If you added a port for local debugging, remove it before deploying: + +```yaml +# db service β€” remove or comment out for production: +# ports: +# - "3306:3306" +``` + +### Reverse Proxy with TLS + +Documize serves plain HTTP. In production, terminate TLS at a reverse proxy. Example **Caddy** config: + +``` +docs.example.com { + reverse_proxy localhost:5001 +} +``` + +Example **Nginx** config: + +```nginx +server { + listen 443 ssl; + server_name docs.example.com; + + ssl_certificate /etc/ssl/certs/docs.crt; + ssl_certificate_key /etc/ssl/private/docs.key; + + location / { + proxy_pass http://localhost:5001; + 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; + } +} +``` + +--- + +## πŸ“… Day-to-Day Operations + +### Start / Stop / Restart + +```bash +docker compose up -d # start all services (detached) +docker compose stop # graceful stop β€” data preserved +docker compose start # resume after stop +docker compose restart # restart all services +docker compose down # stop and remove containers (volumes kept) +docker compose down -v # ⚠️ DESTRUCTIVE β€” removes containers AND volumes +``` + +### View Logs + +```bash +docker compose logs -f # all services, follow +docker compose logs -f app # Documize app only +docker compose logs -f db # MySQL only +docker compose logs --tail=100 app # last 100 lines +``` + +### Check Status + +```bash +docker compose ps +``` + +Expected healthy state: + +``` +NAME IMAGE STATUS +documize-init alpine:3.19 Exited (0) ← correct: one-shot +documize-db mysql:8 healthy +documize-app alpine:3.19 running +``` + +### Open a MySQL Shell + +```bash +docker exec -it documize-db mysql -u documize -p documize +# enter MYSQL_PASSWORD when prompted +``` + +--- + +## πŸ’Ύ Backup & Restore + +### Backup the Database + +```bash +docker exec documize-db \ + mysqldump -u documize -p"${MYSQL_PASSWORD}" documize \ + > documize-backup-$(date +%Y%m%d-%H%M%S).sql +``` + +### Restore the Database + +```bash +docker exec -i documize-db \ + mysql -u documize -p"${MYSQL_PASSWORD}" documize \ + < documize-backup-20240101-120000.sql +``` + +### Backup the Raw Volume (optional) + +```bash +docker run --rm \ + -v documize_db_data:/data \ + -v $(pwd):/backup \ + alpine tar czf /backup/db_data-$(date +%Y%m%d).tar.gz -C /data . +``` + +--- + +## ⬆️ Upgrading Documize + +> ⚠️ **Always back up the database before upgrading.** + +```bash +# 1. Back up +docker exec documize-db mysqldump -u documize -p"${MYSQL_PASSWORD}" documize > pre-upgrade-backup.sql + +# 2. Stop the stack +docker compose down + +# 3. Remove the cached binary to force re-download of the new version +docker volume rm documize_app_bin + +# 4. Update the download URL in docker-compose.yml (app-init command) to the new version + +# 5. Start and watch for successful migration messages +docker compose up -d +docker compose logs -f app +``` + +Documize runs database schema migrations automatically on startup. + +--- + +## πŸ› Troubleshooting + +| Symptom | Cause | Resolution | +|---|---|---| +| `app-init` exits with code `127` | `curl` not found β€” `apk` failed | Check internet connectivity and retry: `docker compose down -v && docker compose up -d` | +| `app-init` exits with code `22` or `28` | Binary download failed | Check outbound HTTPS access to `community-downloads.s3.us-east-2.amazonaws.com` | +| `documize-app` keeps restarting | MySQL not healthy or DSN mismatch | Run `docker compose logs db`. Verify `MYSQL_PASSWORD` in `.env` matches the password in `DOCUMIZEDB` | +| Setup wizard shows DB connection error | DSN credentials mismatch | Ensure `MYSQL_PASSWORD` in `.env` is identical to the password in the `DOCUMIZEDB` connection string | +| Port `5001` already in use | Port conflict on host | Change `DOCUMIZE_PORT` in `.env` and restart | +| `app-init` exits with code `0` but binary won't run | Wrong CPU architecture | The default binary is `linux-amd64`. On ARM (e.g. Raspberry Pi, Apple Silicon Linux), replace the download URL with the `linux-arm64` binary | +| Full-text search returns no results | MySQL FTS config missing | Confirm `--ft-min-word-len=3` is present in the `db` `command` block | +| Lost `DOCUMIZE_SALT` β€” users locked out | Salt cannot be recovered | Restore from a database backup taken before the salt was changed | +| Docker Compose variable not substituted | `.env` file missing or wrong path | Ensure `.env` is in the **same directory** as `docker-compose.yml` | + +--- + +## πŸ“ File Reference + +``` +. +β”œβ”€β”€ docker-compose.yml # Stack definition β€” edit to change ports and resource limits +β”œβ”€β”€ .env.template # Commit this β€” safe template with no real secrets +β”œβ”€β”€ .env # Do NOT commit β€” your actual secrets +└── README.md # This file +``` + +| Docker resource | Type | Purpose | +|---|---|---| +| `documize-db` | Container | MySQL 8 database | +| `documize-init` | Container | One-shot binary downloader | +| `documize-app` | Container | Documize application | +| `documize_net` | Network | Private bridge β€” only `app` can reach `db` | +| `db_data` | Volume | MySQL data directory | +| `app_bin` | Volume | Documize binary cache | + +--- + +## πŸ†˜ Quick-Reference Commands + +```bash +# ── Setup ────────────────────────────────────────────────────────────────────── +cp .env.template .env && chmod 600 .env # create secrets file +openssl rand -hex 32 # generate DOCUMIZE_SALT +openssl rand -base64 24 # generate a password + +# ── Stack lifecycle ──────────────────────────────────────────────────────────── +docker compose up -d # start +docker compose down # stop (data kept) +docker compose down -v # ⚠️ wipe everything +docker compose logs -f # live logs +docker compose ps # status + +# ── Database ─────────────────────────────────────────────────────────────────── +docker exec -it documize-db mysql -u documize -p documize # MySQL shell +docker exec documize-db mysqldump -u documize -p"" documize > backup.sql + +# ── Upgrades ─────────────────────────────────────────────────────────────────── +docker compose down && docker volume rm documize_app_bin && docker compose up -d +``` + +--- + +## πŸ“„ License + +Documize Community edition is licensed under the **GNU Affero General Public License v3 (AGPL-3.0)**. +See [LICENSE](https://github.com/documize/community/blob/master/LICENSE) in the upstream repository. + +This Docker configuration is provided as-is for self-hosting purposes. + +--- + +
+ +Made with ❀️ for the self-hosting community · [Documize upstream](https://github.com/documize/community) · [Report an issue](https://github.com/your-org/documize-docker/issues) + +
diff --git a/Documize/docker-compose.yml b/Documize/docker-compose.yml new file mode 100644 index 0000000..eb919a0 --- /dev/null +++ b/Documize/docker-compose.yml @@ -0,0 +1,134 @@ +# ============================================================================== +# Documize Community Edition v5.14.0 β€” Docker Compose +# https://github.com/documize/community +# +# Stack: +# - documize-init one-shot downloader (runs once, then exits cleanly) +# - documize-app Alpine runner (executes the pre-downloaded binary) +# - MySQL 8 self-hosted database (named volume for persistence) +# +# Quick-start: +# 1. Copy .env.template to .env and fill in all ⚠️ values. +# 2. Run: docker compose up -d +# 3. Wait ~60 s, then open http://localhost:5001 +# 4. Complete the one-time setup wizard in your browser. +# +# See README.docx for full documentation. +# ============================================================================== + +services: + + # ── MySQL 8 ────────────────────────────────────────────────────────────────── + db: + image: mysql:8 + container_name: documize-db + restart: unless-stopped + + mem_limit: 1g + cpu_shares: 1024 + + security_opt: + - no-new-privileges:true + + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${MYSQL_USER}", "--password=${MYSQL_PASSWORD}"] + interval: 15s + timeout: 5s + retries: 5 + start_period: 45s + + environment: + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + + # utf8mb4 + full-text search flags required by Documize + command: > + --character-set-server=utf8mb4 + --collation-server=utf8mb4_unicode_ci + --ft-min-word-len=3 + --innodb-file-per-table=1 + --max-allowed-packet=256M + + volumes: + - db_data:/var/lib/mysql + + networks: + - documize_net + + # ── Init container: download binary once into shared volume ────────────────── + app-init: + image: alpine:3.19 + container_name: documize-init + restart: "no" # runs once and exits β€” never restarts + entrypoint: ["/bin/sh", "-c"] + command: + - | + set -e + apk add --no-cache curl ca-certificates + if [ ! -f /app/bin/documize ]; then + echo 'Downloading Documize Community v5.14.0...' + curl -fsSL -o /app/bin/documize https://community-downloads.s3.us-east-2.amazonaws.com/documize-community-linux-amd64 + chmod +x /app/bin/documize + echo 'Download complete.' + else + echo 'Binary already present, skipping download.' + fi + + volumes: + - app_bin:/app/bin + + # ── App: run the pre-downloaded binary ─────────────────────────────────────── + app: + image: alpine:3.19 + container_name: documize-app + restart: unless-stopped + + entrypoint: ["/app/bin/documize"] + + depends_on: + app-init: + condition: service_completed_successfully + db: + condition: service_healthy + + ports: + - "${DOCUMIZE_PORT}:5001" + + environment: + # ── Network ──────────────────────────────────────────────────────────── + DOCUMIZEPORT: "${DOCUMIZE_PORT}" + DOCUMIZELOCATION: selfhost + + # ── Database (MySQL DSN) ──────────────────────────────────────────────── + DOCUMIZEDBTYPE: mysql + DOCUMIZEDB: "${MYSQL_USER}:${MYSQL_PASSWORD}@tcp(db:3306)/${MYSQL_DATABASE}?charset=utf8mb4&parseTime=True&maxAllowedPacket=4194304" + + # ── Security ──────────────────────────────────────────────────────────── + DOCUMIZESALT: "${DOCUMIZE_SALT}" + + # ── SMTP (optional β€” only active when all SMTP_* vars are set) ────────── + DOCUMIZESMTPHOST: "${SMTP_HOST}" + DOCUMIZESMTPPORT: "${SMTP_PORT}" + DOCUMIZESMTPUSER: "${SMTP_USER}" + DOCUMIZESMTPPASSWORD: "${SMTP_PASSWORD}" + DOCUMIZESMTPSENDER: "${SMTP_SENDER}" + + volumes: + - app_bin:/app/bin + + networks: + - documize_net + +# ── Named volumes ───────────────────────────────────────────────────────────── +volumes: + db_data: + driver: local # MySQL data β€” survives container restarts and upgrades + app_bin: + driver: local # Documize binary β€” downloaded once by app-init + +# ── Internal network ────────────────────────────────────────────────────────── +networks: + documize_net: + driver: bridge diff --git a/Documize/env.template b/Documize/env.template new file mode 100644 index 0000000..06816f8 --- /dev/null +++ b/Documize/env.template @@ -0,0 +1,59 @@ +# ============================================================================== +# Documize Community Edition v5.14.0 β€” Environment Variables +# ============================================================================== +# +# USAGE: +# 1. Copy this file: cp .env.template .env +# 2. Fill in every value marked ⚠️ +# 3. NEVER commit .env to version control +# 4. Add .env to your .gitignore: echo ".env" >> .gitignore +# +# All variables here are referenced in docker-compose.yml via ${VARIABLE_NAME} +# ============================================================================== + +# ── MySQL Database ───────────────────────────────────────────────────────────── + +# Name of the database Documize will use (no need to change) +MYSQL_DATABASE=documize + +# MySQL user that Documize connects as (no need to change) +MYSQL_USER=documize + +# ⚠️ Password for the documize MySQL user +# Rules: min 16 chars, mix of upper/lower/numbers/symbols +# Used in BOTH the db service AND the DOCUMIZEDB connection string below +# Generate: openssl rand -base64 24 +MYSQL_PASSWORD=xu05mFDSeCLTMJDjaAAUqr/7Fcv1fbEU + +# ⚠️ Password for the MySQL root account (admin use only, not used by Documize) +# Generate: openssl rand -base64 24 +MYSQL_ROOT_PASSWORD=xu05mFDSeCLTMJDjaAAUqr/7Fcv1fbEU + +# ── Documize Application ─────────────────────────────────────────────────────── + +# Port Documize listens on (inside the container β€” matches docker-compose ports mapping) +DOCUMIZE_PORT=5001 + +# ⚠️ Password hashing salt β€” must be a random string of at least 32 characters +# Generate: openssl rand -hex 32 +# CRITICAL: Set this ONCE before the first run. Changing it later will +# invalidate ALL existing user passwords and lock everyone out. +DOCUMIZE_SALT=52c7337659a635c8541d097c78ac6b93851dabaa09d190337cf0a99265afe9f9 + +# ── SMTP Email Notifications (optional) ─────────────────────────────────────── +# Leave blank to disable email. All five values must be set to enable it. + +# Hostname of your SMTP server (e.g. smtp.gmail.com, mail.example.com) +SMTP_HOST= + +# SMTP port β€” typically 587 (STARTTLS) or 465 (SSL/TLS) +SMTP_PORT=587 + +# SMTP authentication username (usually your full email address) +SMTP_USER= + +# ⚠️ SMTP authentication password or app-specific password +SMTP_PASSWORD= + +# From address shown on outgoing Documize emails +SMTP_SENDER=documize@example.com diff --git a/Gitea/.env b/Gitea/.env new file mode 100644 index 0000000..7a68cfe --- /dev/null +++ b/Gitea/.env @@ -0,0 +1,28 @@ +# ── Container user ─────────────────────────────────────────────── +# Match these to the UID/GID that owns the ./gitea host directory. +# On Linux, run `id -u` and `id -g` to find yours. +USER_UID=1000 +USER_GID=1000 + +# ── PostgreSQL database ────────────────────────────────────────── +POSTGRES_USER=gitea +POSTGRES_PASSWORD=change_me_to_a_strong_password +POSTGRES_DB=gitea + +# ── Host port mappings ─────────────────────────────────────────── +# host:container β€” change the host side if these ports are taken. +GITEA_HTTP_HOST_PORT=3000 +GITEA_SSH_HOST_PORT=222 + +# ── Server settings ────────────────────────────────────────────── +# For a purely local setup, localhost is fine. +GITEA_DOMAIN=localhost +GITEA_ROOT_URL=http://localhost:3000/ + +# ── Security secrets ───────────────────────────────────────────── +# Generate each of these once and keep them stable. Do NOT change +# SECRET_KEY after installation or encrypted data becomes unreadable. +# docker run -it --rm docker.gitea.com/gitea:1 gitea generate secret SECRET_KEY +# docker run -it --rm docker.gitea.com/gitea:1 gitea generate secret INTERNAL_TOKEN +GITEA_SECRET_KEY= +GITEA_INTERNAL_TOKEN= diff --git a/Gitea/README.md b/Gitea/README.md new file mode 100644 index 0000000..02e7c9a --- /dev/null +++ b/Gitea/README.md @@ -0,0 +1,95 @@ +# Local Gitea Deployment (Docker Compose) + +A local, self-hosted [Gitea](https://docs.gitea.com/) instance running Gitea +**1.27.3** with a **PostgreSQL 14** database, following the official Gitea +Docker installation docs. All credentials, ports, and secrets live in the +`.env` file rather than being hardcoded in the compose file. + +## Files + +- `docker-compose.yml` β€” service definitions for Gitea + PostgreSQL +- `.env` β€” configuration (credentials, ports, secrets) +- `README.md` β€” this file + +## Prerequisites + +- Docker Engine with Compose v2 (`docker compose`, included in modern Docker). + If needed, see the [Compose install instructions](https://docs.docker.com/compose/install/). + +## Setup + +Do the following before bringing the stack up. + +### 1. Generate the security secrets + +Run these two commands and paste each result into the matching empty field in +`.env` (`GITEA_SECRET_KEY` and `GITEA_INTERNAL_TOKEN`): + +``` +docker run -it --rm docker.gitea.com/gitea:1 gitea generate secret SECRET_KEY +docker run -it --rm docker.gitea.com/gitea:1 gitea generate secret INTERNAL_TOKEN +``` + +> **Do not change `SECRET_KEY` after the first install.** Encrypted data in the +> database cannot be decrypted if you do. + +### 2. Change the database password + +Replace the placeholder `POSTGRES_PASSWORD` value in `.env` with a strong password. + +### 3. Match the UID/GID + +The setup uses a host volume (`./gitea`), so set `USER_UID` / `USER_GID` in +`.env` to whoever owns that directory. On Linux: + +``` +id -u # -> USER_UID +id -g # -> USER_GID +``` + +Wrong volume permissions are the most common reason the container won't start. + +## Start + +``` +docker compose up -d +``` + +Then open **http://localhost:3000** and finish setup in the browser wizard. + +- If the wizard asks for the **database host**, use `db` (the service name), not `localhost`. +- **SSH** is available on host port **222**. +- Data persists in `./gitea` and `./postgres` next to the compose file. + +## Common commands + +``` +docker compose ps # check status +docker compose logs # view logs +docker compose down # stop and remove containers (volumes/data are kept) +``` + +## Upgrading + +``` +# Edit the image version in docker-compose.yml if you pin a specific release +docker compose pull # pull new images +docker compose up -d # recreate containers with the new images +``` + +> Make sure your data is volumed outside the container (it is, via `./gitea` +> and `./postgres`) before upgrading. + +## Security note + +Keep `.env` out of version control β€” it holds your secrets and database +password. Add it to `.gitignore`: + +``` +echo ".env" >> .gitignore +``` + +## Reference + +- [Gitea Docs β€” Installation with Docker](https://docs.gitea.com/installation/install-with-docker/) +- [Gitea Docs β€” Managing deployments with environment variables](https://docs.gitea.com/installation/install-with-docker/#managing-deployments-with-environment-variables) diff --git a/Gitea/docker-compose.yml b/Gitea/docker-compose.yml new file mode 100644 index 0000000..2e4361c --- /dev/null +++ b/Gitea/docker-compose.yml @@ -0,0 +1,51 @@ +networks: + gitea: + external: false + +services: + server: + image: docker.gitea.com/gitea:1.27.3 + container_name: gitea + restart: always + environment: + # Container user (match to owner of the ./gitea host volume) + - USER_UID=${USER_UID} + - USER_GID=${USER_GID} + # Database connection + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=db:5432 + - GITEA__database__NAME=${POSTGRES_DB} + - GITEA__database__USER=${POSTGRES_USER} + - GITEA__database__PASSWD=${POSTGRES_PASSWORD} + # Server / general settings + - GITEA__server__DOMAIN=${GITEA_DOMAIN} + - GITEA__server__ROOT_URL=${GITEA_ROOT_URL} + - GITEA__server__SSH_DOMAIN=${GITEA_DOMAIN} + - GITEA__server__SSH_PORT=${GITEA_SSH_HOST_PORT} + # Security secrets (generate these β€” see notes) + - GITEA__security__SECRET_KEY=${GITEA_SECRET_KEY} + - GITEA__security__INTERNAL_TOKEN=${GITEA_INTERNAL_TOKEN} + networks: + - gitea + volumes: + - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "${GITEA_HTTP_HOST_PORT}:3000" + - "${GITEA_SSH_HOST_PORT}:22" + depends_on: + - db + + db: + image: docker.io/library/postgres:14 + container_name: gitea-db + restart: always + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + networks: + - gitea + volumes: + - ./postgres:/var/lib/postgresql/data diff --git a/Homar_Martinhal/docker-compose.yml b/Homar_Martinhal/docker-compose.yml new file mode 100644 index 0000000..e64dfbf --- /dev/null +++ b/Homar_Martinhal/docker-compose.yml @@ -0,0 +1,15 @@ +#---------------------------------------------------------------------# +# Homarr - A simple, yet powerful dashboard for your server. # +#---------------------------------------------------------------------# +services: + homarr: + container_name: homarr + image: ghcr.io/homarr-labs/homarr:latest + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration + - ./homarr/appdata:/appdata + environment: + - SECRET_ENCRYPTION_KEY=2eda5bfd55a3e8447a71a5b827eddd458976318f89d36d821a068769b8ef891b + ports: + - '7575:7575' \ No newline at end of file diff --git a/Homar_Meu/docker-compose.yml b/Homar_Meu/docker-compose.yml new file mode 100644 index 0000000..1023f89 --- /dev/null +++ b/Homar_Meu/docker-compose.yml @@ -0,0 +1,15 @@ +#---------------------------------------------------------------------# +# Homarr - A simple, yet powerful dashboard for your server. # +#---------------------------------------------------------------------# +services: + homarr: + container_name: homarr + image: ghcr.io/homarr-labs/homarr:latest + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration + - ./homarr/appdata:/appdata + environment: + - SECRET_ENCRYPTION_KEY=2eda5bfd55a3e8447a71a5b827edff458976318f89d36d821a068769b8ef891b + ports: + - '7575:7575' \ No newline at end of file diff --git a/Jellyfin/README.md b/Jellyfin/README.md new file mode 100644 index 0000000..38ac1bd --- /dev/null +++ b/Jellyfin/README.md @@ -0,0 +1,374 @@ +# 🎬 Jellyfin β€” Self-Hosted Media Server + +![Jellyfin](https://img.shields.io/badge/Jellyfin-00A4DC?style=for-the-badge&logo=jellyfin&logoColor=white) +![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white) +![License](https://img.shields.io/badge/License-GPL--2.0-blue?style=for-the-badge) + +--- + +## πŸ“– What is Jellyfin? + +**Jellyfin** is a free, open-source media server that puts you in full control of your media library. It is the community-driven, privacy-respecting alternative to proprietary platforms like Plex and Emby β€” with **no subscriptions, no tracking, and no vendor lock-in**. + +Jellyfin lets you collect, manage, and stream your movies, TV shows, music, live TV, photos, and books from your own server to any device, anywhere in the world. + +--- + +## ✨ Key Features & Capabilities + +### πŸŽ₯ Media Management +- **Movies & TV Shows** β€” Organizes your video library with rich metadata, posters, fan art, trailers, and ratings pulled from online databases (TMDb, TheTVDB, etc.) +- **Music** β€” Full music library management with MusicBrainz integration, album art, lyrics, and playlists +- **Photos** β€” Browse and share your photo collection; supports slideshow playback +- **Books & Audiobooks** β€” Manage eBooks and audiobooks (via plugins) +- **Live TV & DVR** β€” Watch and record live television using an HDHomeRun tuner or compatible TV backend (Tvheadend, NextPVR) + +### πŸ“‘ Streaming & Playback +- **Direct Play** β€” Streams media in its original format with zero quality loss if the client supports it +- **Transcoding** β€” On-the-fly conversion of media to formats compatible with any client device +- **Hardware Acceleration** β€” Supports Intel Quick Sync, AMD AMF, NVIDIA NVENC, VA-API, and VideoToolbox for fast, low-CPU transcoding +- **Adaptive Bitrate** β€” Automatically adjusts quality based on your network connection +- **Resume Playback** β€” Tracks your watch progress across all devices +- **SyncPlay** β€” Watch content simultaneously with other users in perfect sync + +### πŸ‘₯ User Management +- **Multiple Users** β€” Create separate profiles with individual libraries, permissions, and parental controls +- **Parental Controls** β€” Restrict access by content rating, hide libraries, and set PIN-protected profiles +- **Guest Access** β€” Share your server with friends and family without giving full access +- **Activity Logs** β€” Full audit trail of who watched what and when + +### πŸ“Ί Client Support +Jellyfin has official and community clients for virtually every platform: +- **Web Browser** β€” Built-in web UI accessible from any browser +- **Android & Android TV** +- **iOS & Apple TV** +- **Roku** +- **Fire TV / Kodi** +- **Samsung Tizen & LG webOS Smart TVs** +- **Desktop** β€” Windows, macOS, Linux +- **Xbox** (via browser or Kodi) + +### πŸ”Œ DLNA & Casting +- DLNA server support for smart TVs and media players +- Chromecast support via the web client +- AirPlay via community plugins + +### πŸ”’ Privacy & Security +- **100% self-hosted** β€” your data never leaves your server +- **No telemetry** β€” zero tracking or analytics by default +- **Optional SSL/HTTPS** β€” secure your server with Let's Encrypt or custom certificates +- **API-first architecture** β€” full REST API for automation and integrations + +### 🧩 Plugin Ecosystem +Extend Jellyfin with community plugins: +- Open Subtitles & Subscene for automatic subtitle downloads +- Fanart.tv for enhanced artwork +- Ani-Sync for AniList/MyAnimeList integration +- Playback reporting & statistics dashboards + +--- + +## πŸ–₯️ Prerequisites + +Before you begin, ensure you have the following installed on your **Linux** host: + +| Requirement | Minimum Version | Check Command | +|---|---|---| +| Docker Engine | 24.x+ | `docker --version` | +| Docker Compose | v2.x+ (plugin) | `docker compose version` | +| Available RAM | 2 GB+ | `free -h` | +| Available Disk | Depends on library size | `df -h` | + +> ⚠️ **Linux Only:** Running Jellyfin in Docker on Windows or macOS is **not officially supported** and hardware-accelerated transcoding will not work on those platforms. Install natively on Windows/macOS instead. + +--- + +## πŸ“ Recommended Directory Structure + +Before deploying, set up the following folder layout on your host machine: + +``` +jellyfin-deploy/ +β”œβ”€β”€ docker-compose.yml ← The compose file from this repo +β”œβ”€β”€ jellyfin/ +β”‚ β”œβ”€β”€ config/ ← Jellyfin configuration & database (auto-created) +β”‚ └── cache/ ← Transcoding cache (auto-created) +└── media/ + β”œβ”€β”€ movies/ ← Your movie files + β”œβ”€β”€ tvshows/ ← Your TV show files + └── music/ ← Your music files +``` + +--- + +## πŸš€ Installation Instructions + +### Step 1 β€” Install Docker + +If Docker is not already installed, follow the official guide for your distribution: + +```bash +# Ubuntu / Debian (quick install) +curl -fsSL https://get.docker.com | sudo sh +sudo usermod -aG docker $USER # Allow your user to run Docker without sudo +newgrp docker # Apply group change without logging out +``` + +Verify the installation: + +```bash +docker --version +docker compose version +``` + +--- + +### Step 2 β€” Clone or Download This Repository + +```bash +git clone https://github.com/YOUR_USERNAME/jellyfin-docker.git +cd jellyfin-docker +``` + +Or simply create a working directory and place the provided files inside it: + +```bash +mkdir jellyfin-deploy && cd jellyfin-deploy +# Copy docker-compose.yml and README.md here +``` + +--- + +### Step 3 β€” Create Required Directories + +```bash +mkdir -p jellyfin/config +mkdir -p jellyfin/cache +mkdir -p media/movies +mkdir -p media/tvshows +mkdir -p media/music +``` + +> Your actual media files should be placed in (or symlinked from) the `media/` subdirectories, or you can update the bind mount paths in `docker-compose.yml` to point directly to where your media already lives. + +--- + +### Step 4 β€” Configure `docker-compose.yml` + +Open `docker-compose.yml` in a text editor and customize the following: + +#### 4a. Set your Timezone +```yaml +environment: + - TZ=America/New_York # ← Change to your timezone (e.g. Europe/London) +``` + +Find your timezone string at: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + +#### 4b. Set the Published Server URL *(optional but recommended)* +```yaml +environment: + - JELLYFIN_PublishedServerUrl=http://YOUR_SERVER_IP_OR_DOMAIN:8096 +``` +Replace `YOUR_SERVER_IP_OR_DOMAIN` with your server's LAN IP (e.g., `192.168.1.100`) or public domain name. + +#### 4c. Set Media Paths +By default, the compose file uses relative paths (`./media/movies`, etc.). To point at existing media folders elsewhere on your system, change the `source:` paths: + +```yaml +volumes: + - type: bind + source: /mnt/nas/movies # ← Your actual path + target: /media/movies + read_only: true +``` + +#### 4d. Set User/Group (Recommended) +Find your current user's UID and GID: + +```bash +id +# Example output: uid=1000(youruser) gid=1000(yourgroup) +``` + +Uncomment and update the `user:` line in `docker-compose.yml`: + +```yaml +user: "1000:1000" +``` + +This prevents Jellyfin from running as root and ensures correct file permissions. + +--- + +### Step 5 β€” Start Jellyfin + +```bash +docker compose up -d +``` + +The `-d` flag runs the container in the background (detached mode). + +Check that it started successfully: + +```bash +docker compose ps +docker compose logs -f jellyfin +``` + +--- + +### Step 6 β€” Complete the Setup Wizard + +Open your browser and navigate to: + +``` +http://YOUR_SERVER_IP:8096 +``` + +You will be greeted by the **Jellyfin Setup Wizard**. Follow these steps: + +1. **Create your admin account** β€” Set a username and password +2. **Add media libraries** β€” Point Jellyfin to `/media/movies`, `/media/tvshows`, `/media/music` (these are the container-side paths) +3. **Choose metadata language** β€” Select your preferred language for scraped info +4. **Configure remote access** β€” Enable if you want to access Jellyfin outside your home network +5. **Finish** β€” Jellyfin will begin scanning your media library immediately + +--- + +## πŸ›‘ Managing the Container + +| Action | Command | +|---|---| +| Start | `docker compose up -d` | +| Stop | `docker compose down` | +| Restart | `docker compose restart jellyfin` | +| View logs | `docker compose logs -f jellyfin` | +| Update image | `docker compose pull && docker compose up -d` | +| Remove container & volumes | `docker compose down -v` | + +--- + +## ⚑ Hardware Acceleration (Optional) + +Hardware transcoding dramatically reduces CPU usage during video playback. + +### Intel / AMD (VA-API via `/dev/dri`) + +Uncomment the `devices` section in `docker-compose.yml`: + +```yaml +devices: + - /dev/dri:/dev/dri +``` + +Then in the Jellyfin Admin Dashboard: +1. Go to **Dashboard β†’ Playback β†’ Transcoding** +2. Set **Hardware acceleration** to **Video Acceleration API (VAAPI)** +3. Set the VA-API device to `/dev/dri/renderD128` +4. Save and test + +### NVIDIA GPU + +Requires the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html). Add to `docker-compose.yml`: + +```yaml +deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] +``` + +Then in Jellyfin, set Hardware acceleration to **NVENC**. + +--- + +## 🌐 Exposing Jellyfin to the Internet (Optional) + +### Option A β€” Port Forwarding +Forward TCP port `8096` on your router to your server's LAN IP. + +### Option B β€” Reverse Proxy with HTTPS (Recommended) +Use **Nginx Proxy Manager**, **Traefik**, or **Caddy** in front of Jellyfin to enable HTTPS. Example Nginx config snippet: + +```nginx +server { + listen 443 ssl; + server_name jellyfin.yourdomain.com; + + location / { + proxy_pass http://localhost:8096; + 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; + } +} +``` + +--- + +## πŸ”§ DLNA Configuration (Optional) + +For DLNA support (smart TVs discovering Jellyfin automatically), you need host networking: + +```yaml +network_mode: host +``` + +> ⚠️ When using host networking, remove the `ports:` section entirely β€” host network mode exposes all ports directly. + +--- + +## πŸ—‚οΈ Backup & Restore + +The only directory you need to back up is `./jellyfin/config/`. This contains: +- The Jellyfin database (`jellyfin.db`) +- All server settings and user data +- API keys and plugin configurations + +```bash +# Backup +tar -czf jellyfin-backup-$(date +%Y%m%d).tar.gz ./jellyfin/config + +# Restore +tar -xzf jellyfin-backup-YYYYMMDD.tar.gz +``` + +--- + +## πŸ› Troubleshooting + +| Problem | Solution | +|---|---| +| Port 8096 not accessible | Check firewall: `sudo ufw allow 8096/tcp` | +| Permission denied on media | Set correct `user: UID:GID` in compose file | +| Media not appearing | Check that bind mount paths are correct; restart and re-scan | +| High CPU during playback | Enable hardware acceleration; ensure Direct Play is used when possible | +| Container won't start | Run `docker compose logs jellyfin` to inspect errors | + +--- + +## πŸ“š Useful Links + +- 🏠 [Jellyfin Official Website](https://jellyfin.org) +- πŸ“– [Official Documentation](https://jellyfin.org/docs/) +- 🐳 [Docker Hub Image](https://hub.docker.com/r/jellyfin/jellyfin) +- πŸ’¬ [Jellyfin Forum](https://forum.jellyfin.org) +- πŸ”Œ [Plugin Catalogue](https://jellyfin.org/docs/general/server/plugins/) +- ⚑ [Hardware Acceleration Guide](https://jellyfin.org/docs/general/post-install/transcoding/hardware-acceleration) +- πŸ›‘οΈ [Backup & Restore Guide](https://jellyfin.org/docs/general/administration/backup-and-restore) + +--- + +## πŸ“œ License + +Jellyfin is released under the [GNU General Public License v2.0](https://github.com/jellyfin/jellyfin/blob/master/LICENSE). +This deployment configuration is provided as-is for personal use. + +--- + +*Made with ❀️ for the self-hosting community* diff --git a/Jellyfin/docker-compose.yml b/Jellyfin/docker-compose.yml new file mode 100644 index 0000000..05d8cbe --- /dev/null +++ b/Jellyfin/docker-compose.yml @@ -0,0 +1,79 @@ +services: + jellyfin: + image: jellyfin/jellyfin:latest + container_name: jellyfin + # Optional: run as a specific user/group instead of root + # Replace 1000:1000 with your actual UID:GID (run `id` in terminal to find yours) + # user: "1000:1000" + + ports: + - 8096:8096/tcp # Main HTTP web UI & API + - 8920:8920/tcp # HTTPS web UI (optional, requires cert setup) + - 7359:7359/udp # Local network auto-discovery (DLNA) + - 1900:1900/udp # DLNA service discovery (optional, requires host network) + + volumes: + # Jellyfin configuration & metadata database + - ./jellyfin/config:/config + + # Transcoding cache (can be tmpfs for better performance) + - ./jellyfin/cache:/cache + + # --- Media Libraries --- + # Add as many bind mounts as you need for your media folders. + # Set read_only: true for libraries Jellyfin should not modify. + - type: bind + source: ./media/movies + target: /media/movies + read_only: true + + - type: bind + source: ./media/tvshows + target: /media/tvshows + read_only: true + + - type: bind + source: ./media/music + target: /media/music + read_only: true + + # Optional: custom fonts for subtitle burn-in during transcoding + # - type: bind + # source: ./fonts + # target: /usr/local/share/fonts/custom + # read_only: true + + # Optional: fallback fonts directory + # (set fallback font path to /fallback_fonts in Jellyfin server settings) + # - type: bind + # source: ./fallback_fonts + # target: /fallback_fonts + # read_only: true + + environment: + # Optional: set this to your server's public URL for correct autodiscovery + - JELLYFIN_PublishedServerUrl=http://tube.martinhal.tech:8096 + + # Timezone (change to your local timezone) + - TZ=Europe/Lisbon + + # Optional: enable GPU hardware acceleration (Intel/AMD iGPU via /dev/dri) + # Uncomment the section below if your host has a compatible GPU + # devices: + # - /dev/dri:/dev/dri + + # Required if using host network mode for full DLNA support + # network_mode: host + + # Needed for Docker healthcheck to pass in host network mode + extra_hosts: + - "host.docker.internal:host-gateway" + + restart: unless-stopped + + # Optional: resource limits to prevent Jellyfin from consuming all system resources + # deploy: + # resources: + # limits: + # memory: 4G + # cpus: "4.0" diff --git a/Netbox Docker/.env b/Netbox Docker/.env new file mode 100644 index 0000000..6bf05e0 --- /dev/null +++ b/Netbox Docker/.env @@ -0,0 +1,51 @@ +############################################################################### +# NetBox β€” all secrets & tunable configuration +# +# Docker Compose auto-loads this file (must be named ".env" and sit next to +# docker-compose.yml). Keep it OUT of version control: echo ".env" >> .gitignore +############################################################################### + +# ── Image version ─────────────────────────────────────────────────────────── +# Keep the NetBox Docker image tag in sync with the compose file you deploy. +VERSION=v4.6-5.0.2 + +# ── Web exposure ──────────────────────────────────────────────────────────── +# Host port that maps to NetBox's internal 8080. Change if 8000 is taken. +NETBOX_PORT=8000 +# Comma-separated hostnames/IPs allowed to reach NetBox. Tighten in production, +# e.g. ALLOWED_HOSTS=netbox.example.com +ALLOWED_HOSTS=* + +# ── Core secrets (generated β€” do not reuse elsewhere) ─────────────────────── +SECRET_KEY=2HDStlQcTKmJyE_Wvf7ItgRmXet4sxdK_z9cw42_kShXnCjioRUltX2dTt0mAK2Z0yI +API_TOKEN_PEPPER_1=t5t-KOSYfm3gqPsYJzwiefcOsRmIwxNce7MMUDmXc-qWG96mNVyfvugE_dcH1J_wlaA + +# ── PostgreSQL ────────────────────────────────────────────────────────────── +DB_NAME=netbox +DB_USER=netbox +DB_PASSWORD=6ihrE0FOUH3HVs4BSnEW8IT4 + +# ── Redis / Valkey (two separate instances need two separate passwords) ────── +REDIS_PASSWORD=jArceFdnYgevnBPyevdjMpna +REDIS_CACHE_PASSWORD=0T2NXivbsaulVrQrjI9otiQP + +# ── Email / SMTP β€” PurelyMail ─────────────────────────────────────────────── +# smtp.purelymail.com : 465 over SSL/TLS. +# EMAIL_USE_SSL and EMAIL_USE_TLS are mutually exclusive β€” do NOT set both true. +EMAIL_SERVER=smtp.purelymail.com +EMAIL_PORT=465 +EMAIL_USE_SSL=true +EMAIL_USE_TLS=false +EMAIL_USERNAME=you@yourdomain.com +EMAIL_PASSWORD=CHANGE_ME_purelymail_password +EMAIL_FROM=you@yourdomain.com +EMAIL_TIMEOUT=10 + +# ── Initial superuser ─────────────────────────────────────────────────────── +# Set SKIP_SUPERUSER=false to have the container create this account on first +# boot. Change the password/token before deploying, then set back to true. +SKIP_SUPERUSER=false +SUPERUSER_NAME=admin +SUPERUSER_EMAIL=admin@yourdomain.com +SUPERUSER_PASSWORD=CHANGE_ME_admin_password +SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567 diff --git a/Netbox Docker/docker-compose.yml b/Netbox Docker/docker-compose.yml new file mode 100644 index 0000000..1b6fea8 --- /dev/null +++ b/Netbox Docker/docker-compose.yml @@ -0,0 +1,144 @@ +services: + netbox: &netbox + image: docker.io/netboxcommunity/netbox:${VERSION:-v4.6-5.0.2} + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + redis-cache: + condition: service_healthy + user: "netbox:root" + ports: + - "${NETBOX_PORT:-8000}:8080" + environment: + # Core + SECRET_KEY: ${SECRET_KEY} + API_TOKEN_PEPPER_1: ${API_TOKEN_PEPPER_1} + ALLOWED_HOSTS: ${ALLOWED_HOSTS:-*} + # Database + DB_HOST: postgres + DB_NAME: ${DB_NAME:-netbox} + DB_USER: ${DB_USER:-netbox} + DB_PASSWORD: ${DB_PASSWORD} + # Redis β€” task queue + REDIS_HOST: redis + REDIS_DATABASE: "0" + REDIS_PASSWORD: ${REDIS_PASSWORD} + REDIS_SSL: "false" + REDIS_INSECURE_SKIP_TLS_VERIFY: "false" + # Redis β€” cache + REDIS_CACHE_HOST: redis-cache + REDIS_CACHE_DATABASE: "1" + REDIS_CACHE_PASSWORD: ${REDIS_CACHE_PASSWORD} + REDIS_CACHE_SSL: "false" + REDIS_CACHE_INSECURE_SKIP_TLS_VERIFY: "false" + # Email / SMTP (PurelyMail) + EMAIL_SERVER: ${EMAIL_SERVER:-smtp.purelymail.com} + EMAIL_PORT: ${EMAIL_PORT:-465} + EMAIL_USE_SSL: ${EMAIL_USE_SSL:-true} + EMAIL_USE_TLS: ${EMAIL_USE_TLS:-false} + EMAIL_USERNAME: ${EMAIL_USERNAME} + EMAIL_PASSWORD: ${EMAIL_PASSWORD} + EMAIL_FROM: ${EMAIL_FROM} + EMAIL_TIMEOUT: ${EMAIL_TIMEOUT:-10} + EMAIL_SSL_CERTFILE: "" + EMAIL_SSL_KEYFILE: "" + # Initial superuser + SKIP_SUPERUSER: ${SKIP_SUPERUSER:-true} + SUPERUSER_NAME: ${SUPERUSER_NAME:-admin} + SUPERUSER_EMAIL: ${SUPERUSER_EMAIL:-admin@example.com} + SUPERUSER_PASSWORD: ${SUPERUSER_PASSWORD:-admin} + SUPERUSER_API_TOKEN: ${SUPERUSER_API_TOKEN:-} + # Misc + GRAPHQL_ENABLED: "true" + WEBHOOKS_ENABLED: "true" + METRICS_ENABLED: "false" + MEDIA_ROOT: /opt/netbox/netbox/media + RELEASE_CHECK_URL: https://api.github.com/repos/netbox-community/netbox/releases + healthcheck: + test: curl -f http://localhost:8080/login/ || exit 1 + start_period: 90s + timeout: 3s + interval: 15s + volumes: + - netbox-media-files:/opt/netbox/netbox/media:rw + - netbox-reports-files:/opt/netbox/netbox/reports:rw + - netbox-scripts-files:/opt/netbox/netbox/scripts:rw + + netbox-worker: + <<: *netbox + ports: [] + depends_on: + netbox: + condition: service_healthy + command: + - /opt/netbox/venv/bin/python + - /opt/netbox/netbox/manage.py + - rqworker + healthcheck: + test: ps -aux | grep -v grep | grep -q rqworker || exit 1 + start_period: 20s + timeout: 3s + interval: 15s + + # postgres + postgres: + image: docker.io/postgres:18-alpine + environment: + POSTGRES_DB: ${DB_NAME:-netbox} + POSTGRES_USER: ${DB_USER:-netbox} + POSTGRES_PASSWORD: ${DB_PASSWORD} + healthcheck: + test: pg_isready -q -t 2 -d $$POSTGRES_DB -U $$POSTGRES_USER + start_period: 20s + timeout: 30s + interval: 10s + retries: 5 + volumes: + - netbox-postgres:/var/lib/postgresql + + # redis β€” task queue (persistent) + redis: + image: docker.io/valkey/valkey:9.1-alpine + command: + - sh + - -c # this is to evaluate the $REDIS_PASSWORD from the env + - valkey-server --appendonly yes --requirepass $$REDIS_PASSWORD + environment: + REDIS_PASSWORD: ${REDIS_PASSWORD} + healthcheck: &redis-healthcheck + test: '[ $$(valkey-cli --pass "$${REDIS_PASSWORD}" ping) = ''PONG'' ]' + start_period: 5s + timeout: 3s + interval: 1s + retries: 5 + volumes: + - netbox-redis-data:/data + + # redis-cache β€” transient cache + redis-cache: + image: docker.io/valkey/valkey:9.1-alpine + command: + - sh + - -c # this is to evaluate the $REDIS_PASSWORD from the env + - valkey-server --requirepass $$REDIS_PASSWORD + environment: + REDIS_PASSWORD: ${REDIS_CACHE_PASSWORD} + healthcheck: *redis-healthcheck + volumes: + - netbox-redis-cache-data:/data + +volumes: + netbox-media-files: + driver: local + netbox-postgres: + driver: local + netbox-redis-cache-data: + driver: local + netbox-redis-data: + driver: local + netbox-reports-files: + driver: local + netbox-scripts-files: + driver: local diff --git a/Netbox Docker/files.zip b/Netbox Docker/files.zip new file mode 100644 index 0000000000000000000000000000000000000000..775ce8ebae7283cd65bd354caed9b1b62157f915 GIT binary patch literal 2636 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 Km-e#!cK-q+`1oG{ literal 0 HcmV?d00001 diff --git a/Open_Project/docker-compose.yml b/Open_Project/docker-compose.yml new file mode 100644 index 0000000..92266c1 --- /dev/null +++ b/Open_Project/docker-compose.yml @@ -0,0 +1,302 @@ +# ============================================================================== +# OpenProject β€” Docker Compose (stable/17) +# With SMTP outbound-email support +# ============================================================================== +# Based on: +# https://www.openproject.org/docs/installation-and-operations/installation/docker-compose/ +# https://github.com/opf/openproject-docker-compose (branch: stable/17) +# https://www.openproject.org/docs/installation-and-operations/configuration/outbound-emails/ +# https://www.openproject.org/docs/installation-and-operations/configuration/environment/ +# +# Usage: +# 1. cp .env.example .env # then edit .env with your real values +# 2. sudo mkdir -p /var/openproject/assets +# 3. sudo chown 1000:1000 -R /var/openproject/assets +# 4. docker compose up -d --build --pull always +# +# SMTP variables live in the .env file (see .env.example). +# They are injected into every OpenProject container via the x-op-app anchor. +# ============================================================================== + +version: "3.7" + +# --------------------------------------------------------------------------- +# Networks – frontend faces the proxy; backend is DB / cache only. +# --------------------------------------------------------------------------- +networks: + frontend: + backend: + +# --------------------------------------------------------------------------- +# Volumes – persisted between restarts / upgrades. +# pgdata – PostgreSQL WAL + tables +# opdata – uploaded attachments & assets +# --------------------------------------------------------------------------- +volumes: + pgdata: + opdata: + +# =========================================================================== +# YAML Anchors – shared restart policy, image tag, and environment block. +# =========================================================================== + +x-op-restart-policy: &restart_policy + restart: unless-stopped + +x-op-image: &image + image: openproject/openproject:${TAG:-17-slim} + +# --------------------------------------------------------------------------- +# x-op-app – merged into every OpenProject container. +# All SMTP_* variables are pulled from the .env file so that secrets are +# never hard-coded in this file. See .env.example for every placeholder. +# --------------------------------------------------------------------------- +x-op-app: &app + <<: [*image, *restart_policy] + environment: + # --- Core OpenProject ------------------------------------------------ + OPENPROJECT_HTTPS: "${OPENPROJECT_HTTPS:-true}" + OPENPROJECT_HOST__NAME: "${OPENPROJECT_HOST__NAME:-localhost:8080}" + OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" + OPENPROJECT_EDITION: "${OPENPROJECT_EDITION:-standard}" + + # Allow hocuspocus to reach the web container by its service name + OPENPROJECT_ADDITIONAL__HOST__NAMES: "${OPENPROJECT_ADDITIONAL__HOST__NAMES:-web}" + + # --- Database --------------------------------------------------------- + DATABASE_URL: "${DATABASE_URL:-postgres://postgres:${POSTGRES_PASSWORD:-p4ssw0rd}@db/openproject?pool=20&encoding=unicode&reconnect=true}" + + # --- Cache ------------------------------------------------------------ + OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211" + OPENPROJECT_RAILS__CACHE__STORE: "memcache" + + # --- Threads ---------------------------------------------------------- + RAILS_MIN_THREADS: "${RAILS_MIN_THREADS:-4}" + RAILS_MAX_THREADS: "${RAILS_MAX_THREADS:-16}" + + # --- Collaborative editing (Hocuspocus) ------------------------------ + OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__URL: "${COLLABORATIVE_SERVER_URL:-wss://${OPENPROJECT_HOST__NAME}/hocuspocus}" + OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__SECRET: "${COLLABORATIVE_SERVER_SECRET:-OVERRIDE_ME_PLEASE}" + + # --- Inbound email (IMAP) – disabled by default ----------------------- + IMAP_ENABLED: "${IMAP_ENABLED:-false}" + + # ================================================================ + # SMTP – Outbound e-mail configuration + # ================================================================ + EMAIL_DELIVERY_METHOD: "${EMAIL_DELIVERY_METHOD:-smtp}" + SMTP_ADDRESS: "${SMTP_ADDRESS}" + SMTP_PORT: "${SMTP_PORT:-587}" + SMTP_DOMAIN: "${SMTP_DOMAIN}" + SMTP_AUTHENTICATION: "${SMTP_AUTHENTICATION:-plain}" + SMTP_USER_NAME: "${SMTP_USER_NAME}" + SMTP_PASSWORD: "${SMTP_PASSWORD}" + SMTP_ENABLE_STARTTLS_AUTO: "${SMTP_ENABLE_STARTTLS_AUTO:-true}" + SMTP_SSL: "${SMTP_SSL:-false}" + SMTP_TIMEOUT: "${SMTP_TIMEOUT:-5}" + + OPENPROJECT_MAILER__FROM__ADDRESS: "${MAILER_FROM_ADDRESS:-openproject@example.com}" + + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" + +# =========================================================================== +# Services +# =========================================================================== + +services: + # ----------------------------------------------------------------------- + # db – PostgreSQL 16 + # ----------------------------------------------------------------------- + db: + <<: *restart_policy + image: postgres:16-alpine + networks: + - backend + volumes: + - pgdata:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-p4ssw0rd}" + POSTGRES_DB: openproject + POSTGRES_USER: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d openproject"] + interval: 10s + timeout: 5s + retries: 5 + + # ----------------------------------------------------------------------- + # cache – Memcached + # ----------------------------------------------------------------------- + cache: + <<: *restart_policy + image: memcached:alpine + networks: + - backend + + # ----------------------------------------------------------------------- + # seeder – one-shot container + # + # FIX: Must NOT inherit the restart policy from x-op-app. The seeder is a + # one-shot job that exits with code 0 on success. If restart: unless-stopped + # is in effect Docker will keep restarting it and it will appear permanently + # "waiting" to dependent services that expect service_completed_successfully. + # + # We use the *image anchor only (no *restart_policy) and set + # restart: "no" explicitly. + # ----------------------------------------------------------------------- + seeder: + <<: *image + restart: "no" + environment: + # Minimal env required for seeder (DB + cache) + OPENPROJECT_HTTPS: "${OPENPROJECT_HTTPS:-true}" + OPENPROJECT_HOST__NAME: "${OPENPROJECT_HOST__NAME:-localhost:8080}" + OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" + OPENPROJECT_EDITION: "${OPENPROJECT_EDITION:-standard}" + DATABASE_URL: "${DATABASE_URL:-postgres://postgres:${POSTGRES_PASSWORD:-p4ssw0rd}@db/openproject?pool=20&encoding=unicode&reconnect=true}" + OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211" + OPENPROJECT_RAILS__CACHE__STORE: "memcache" + RAILS_MIN_THREADS: "${RAILS_MIN_THREADS:-4}" + RAILS_MAX_THREADS: "${RAILS_MAX_THREADS:-16}" + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" + networks: + - backend + command: ["./docker/prod/seeder"] + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + + # ----------------------------------------------------------------------- + # web – Puma application server + # + # FIX: healthcheck timings tightened to match official stable/17 repo + # (interval 10s / timeout 3s / retries 3 / start_period 30s). + # The previous values (30s/5s/5/60s) caused downstream containers that + # depend on service_healthy to wait far too long, making them appear stuck. + # ----------------------------------------------------------------------- + web: + <<: *app + networks: + - frontend + - backend + command: ["./docker/prod/web"] + hostname: "${OPENPROJECT_HOST__NAME:-localhost:8080}" + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + seeder: + condition: service_completed_successfully + labels: + - autoheal=true + healthcheck: + test: + - "CMD" + - "curl" + - "-f" + - "http://localhost:8080${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}/health_checks/default" + interval: 10s + timeout: 3s + retries: 3 + start_period: 30s + expose: + - "8080" + + # ----------------------------------------------------------------------- + # autoheal – automatically restarts unhealthy containers + # FIX: Added from official stable/17 compose. Without autoheal, an + # unhealthy web container (e.g. stuck in a loop) is never restarted even + # though Docker marks it unhealthy, which can block the seeder indirectly. + # ----------------------------------------------------------------------- + autoheal: + image: willfarrell/autoheal:1.2.0 + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + environment: + AUTOHEAL_CONTAINER_LABEL: autoheal + AUTOHEAL_START_PERIOD: 600 + AUTOHEAL_INTERVAL: 30 + + # ----------------------------------------------------------------------- + # worker – Active Job background processor + # ----------------------------------------------------------------------- + worker: + <<: *app + networks: + - frontend # needs outbound access for SMTP + - backend + command: ["./docker/prod/worker"] + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + seeder: + condition: service_completed_successfully + # Explicit DNS – prevents "Network is unreachable" when the container + # tries to connect to an external SMTP server. See OP#44515. + dns: + - "8.8.8.8" + + # ----------------------------------------------------------------------- + # cron – periodic background tasks (e.g. sending digest emails) + # FIX: Added from official stable/17 compose. Missing cron can prevent + # certain background jobs from running, which can mask seeder-related + # issues or cause incomplete initialisation. + # ----------------------------------------------------------------------- + cron: + <<: *app + networks: + - backend + command: ["./docker/prod/cron"] + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + seeder: + condition: service_completed_successfully + + # ----------------------------------------------------------------------- + # proxy – Caddy reverse proxy + # ----------------------------------------------------------------------- + proxy: + <<: *restart_policy + image: openproject/openproject:${TAG:-17-slim} + networks: + - frontend + ports: + - "${PORT:-8080}:80" + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" + command: ["./docker/prod/proxy"] + depends_on: + web: + condition: service_healthy + environment: + OPENPROJECT_HTTPS: "${OPENPROJECT_HTTPS:-true}" + OPENPROJECT_HOST__NAME: "${OPENPROJECT_HOST__NAME:-localhost:8080}" + OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" + + # ----------------------------------------------------------------------- + # hocuspocus – WebSocket collaboration server + # ----------------------------------------------------------------------- + hocuspocus: + <<: *restart_policy + image: openproject/openproject:${TAG:-17-slim} + networks: + - frontend + - backend + command: ["./docker/prod/hocuspocus"] + depends_on: + web: + condition: service_healthy + environment: + OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__SECRET: "${COLLABORATIVE_SERVER_SECRET:-OVERRIDE_ME_PLEASE}" + expose: + - "3000" diff --git a/Open_Project/docker-compose_OLD.yml b/Open_Project/docker-compose_OLD.yml new file mode 100644 index 0000000..a14123e --- /dev/null +++ b/Open_Project/docker-compose_OLD.yml @@ -0,0 +1,280 @@ +# ============================================================================== +# OpenProject β€” Docker Compose (stable/17) +# With SMTP outbound-email support +# ============================================================================== +# Based on: +# https://www.openproject.org/docs/installation-and-operations/installation/docker-compose/ +# https://github.com/opf/openproject-docker-compose (branch: stable/17) +# https://www.openproject.org/docs/installation-and-operations/configuration/outbound-emails/ +# https://www.openproject.org/docs/installation-and-operations/configuration/environment/ +# +# Usage: +# 1. cp .env.example .env # then edit .env with your real values +# 2. sudo mkdir -p /var/openproject/assets +# 3. sudo chown 1000:1000 -R /var/openproject/assets +# 4. docker compose up -d --build --pull always +# +# SMTP variables live in the .env file (see .env.example). +# They are injected into every OpenProject container via the x-op-app anchor. +# ============================================================================== + +version: "3.7" + +# --------------------------------------------------------------------------- +# Networks – frontend faces the proxy; backend is DB / cache only. +# --------------------------------------------------------------------------- +networks: + frontend: + backend: + +# --------------------------------------------------------------------------- +# Volumes – persisted between restarts / upgrades. +# pgdata – PostgreSQL WAL + tables +# opdata – uploaded attachments & assets +# --------------------------------------------------------------------------- +volumes: + pgdata: + opdata: + +# =========================================================================== +# YAML Anchors – shared restart policy, image tag, and environment block. +# =========================================================================== + +x-op-restart-policy: &restart_policy + restart: unless-stopped + +x-op-image: &image + image: openproject/openproject:${TAG:-17-slim} + +# --------------------------------------------------------------------------- +# x-op-app – merged into every OpenProject container. +# All SMTP_* variables are pulled from the .env file so that secrets are +# never hard-coded in this file. See .env.example for every placeholder. +# --------------------------------------------------------------------------- +x-op-app: &app + <<: [*image, *restart_policy] + environment: + # --- Core OpenProject ------------------------------------------------ + OPENPROJECT_HTTPS: "${OPENPROJECT_HTTPS:-true}" + OPENPROJECT_HOST__NAME: "${OPENPROJECT_HOST__NAME:-localhost:8080}" + OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" + OPENPROJECT_EDITION: "${OPENPROJECT_EDITION:-standard}" + + # --- Database --------------------------------------------------------- + DATABASE_URL: "${DATABASE_URL:-postgres://postgres:${POSTGRES_PASSWORD:-p4ssw0rd}@db/openproject?pool=20&encoding=unicode&reconnect=true}" + + # --- Cache ------------------------------------------------------------ + OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211" + OPENPROJECT_RAILS__CACHE__STORE: "memcache" + + # --- Threads ---------------------------------------------------------- + RAILS_MIN_THREADS: "${RAILS_MIN_THREADS:-4}" + RAILS_MAX_THREADS: "${RAILS_MAX_THREADS:-16}" + + # --- Collaborative editing (Hocuspocus) ------------------------------ + OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__URL: "${COLLABORATIVE_SERVER_URL:-wss://${OPENPROJECT_HOST__NAME}/hocuspocus}" + OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__SECRET: "${COLLABORATIVE_SERVER_SECRET:-OVERRIDE_ME_PLEASE}" + + # --- Inbound email (IMAP) – disabled by default ----------------------- + IMAP_ENABLED: "${IMAP_ENABLED:-false}" + + # ================================================================ + # SMTP – Outbound e-mail configuration + # ================================================================ + # Every variable below maps to an OpenProject environment variable + # that is documented at: + # /docs/installation-and-operations/configuration/outbound-emails/ + # /docs/installation-and-operations/configuration/environment/ + # + # Setting these via environment variables **disables** the matching + # form in Administration β†’ Emails and notifications (by design). + # + # Common SMTP_PORT values: + # 587 – submission with STARTTLS (most providers, recommended) + # 465 – implicit SSL/TLS + # 25 – unencrypted (never use in production) + # + # Common SMTP_AUTHENTICATION values: + # plain – most cloud providers (Gmail, Outlook, SendGrid …) + # login – some legacy / on-premises servers + # cram_md5 + # + # For SendGrid specifically: + # SMTP_USER_NAME=apikey + # SMTP_PASSWORD= + # ================================================================ + EMAIL_DELIVERY_METHOD: "${EMAIL_DELIVERY_METHOD:-smtp}" + SMTP_ADDRESS: "${SMTP_ADDRESS}" + SMTP_PORT: "${SMTP_PORT:-587}" + SMTP_DOMAIN: "${SMTP_DOMAIN}" + SMTP_AUTHENTICATION: "${SMTP_AUTHENTICATION:-plain}" + SMTP_USER_NAME: "${SMTP_USER_NAME}" + SMTP_PASSWORD: "${SMTP_PASSWORD}" + SMTP_ENABLE_STARTTLS_AUTO: "${SMTP_ENABLE_STARTTLS_AUTO:-true}" + SMTP_SSL: "${SMTP_SSL:-false}" + SMTP_TIMEOUT: "${SMTP_TIMEOUT:-5}" + + # Envelope sender – the "From" address that appears in every mail. + # Must be a valid address on your SMTP account unless your provider + # allows arbitrary senders. + OPENPROJECT_MAILER__FROM__ADDRESS: "${MAILER_FROM_ADDRESS:-openproject@example.com}" + + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" + +# =========================================================================== +# Services +# =========================================================================== + +services: + # ----------------------------------------------------------------------- + # db – PostgreSQL 16 + # Stores all application data. The named volume pgdata persists the + # data directory so it survives container re-creations. + # ----------------------------------------------------------------------- + db: + <<: *restart_policy + image: postgres:16-alpine + networks: + - backend + volumes: + - pgdata:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-p4ssw0rd}" + POSTGRES_DB: openproject + POSTGRES_USER: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d openproject"] + interval: 10s + timeout: 5s + retries: 5 + + # ----------------------------------------------------------------------- + # cache – Memcached + # Used by Rails for fragment / page caching. + # ----------------------------------------------------------------------- + cache: + <<: *restart_policy + image: memcached:alpine + networks: + - backend + + # ----------------------------------------------------------------------- + # seeder – one-shot container + # Runs database migrations and seeds the initial admin user. + # Exits with code 0 after the first successful run; subsequent starts + # are no-ops. + # ----------------------------------------------------------------------- + seeder: + <<: *app + networks: + - backend + command: ["seeds"] + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + + # ----------------------------------------------------------------------- + # web – Puma application server (serves HTTP requests) + # ----------------------------------------------------------------------- + web: + <<: *app + networks: + - frontend + - backend + command: ["web"] + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + seeder: + condition: service_completed_successfully + healthcheck: + test: + - "CMD" + - "curl" + - "-f" + - "http://localhost:8080${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}/health_checks/default" + interval: 30s + timeout: 5s + retries: 5 + start_period: 60s + expose: + - "8080" + + # ----------------------------------------------------------------------- + # worker – Active Job background processor + # Handles asynchronous tasks such as sending notification mails, + # exporting, repository indexing, etc. + # + # DNS block below resolves the SMTP issue documented in OP#44515: + # "SMTP setup fails: Network is unreachable." + # If your corporate DNS is sufficient, replace 8.8.8.8 with your + # internal resolver. + # ----------------------------------------------------------------------- + worker: + <<: *app + networks: + - frontend # needs outbound access for SMTP + - backend + command: ["worker"] + depends_on: + db: + condition: service_healthy + cache: + condition: service_started + seeder: + condition: service_completed_successfully + # Explicit DNS – prevents "Network is unreachable" when the container + # tries to connect to an external SMTP server. See OP#44515. + dns: + - "8.8.8.8" + + # ----------------------------------------------------------------------- + # proxy – Caddy reverse proxy + # Terminates TLS (if a certificate is available) and forwards to web. + # Exposes the single public port defined by $PORT (default 8080). + # + # NOTE: In production, it is strongly recommended to place OpenProject + # behind your own TLS-terminating reverse proxy (Nginx, Traefik, …) + # and configure Caddy's trusted_proxies accordingly. + # ----------------------------------------------------------------------- + proxy: + <<: *restart_policy + image: openproject/openproject:${TAG:-17-slim} + networks: + - frontend + ports: + - "${PORT:-8080}:80" + volumes: + - "${OPDATA:-opdata}:/var/openproject/assets" + command: ["proxy"] + depends_on: + web: + condition: service_healthy + environment: + OPENPROJECT_HTTPS: "${OPENPROJECT_HTTPS:-true}" + OPENPROJECT_HOST__NAME: "${OPENPROJECT_HOST__NAME:-localhost:8080}" + OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}" + + # ----------------------------------------------------------------------- + # hocuspocus – WebSocket collaboration server + # Enables real-time co-editing of documents. + # ----------------------------------------------------------------------- + hocuspocus: + <<: *restart_policy + image: openproject/openproject:${TAG:-17-slim} + networks: + - frontend + - backend + command: ["hocuspocus"] + depends_on: + web: + condition: service_healthy + environment: + OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__SECRET: "${COLLABORATIVE_SERVER_SECRET:-OVERRIDE_ME_PLEASE}" + expose: + - "3000" diff --git a/Open_Project/env.example b/Open_Project/env.example new file mode 100644 index 0000000..8ca79ba --- /dev/null +++ b/Open_Project/env.example @@ -0,0 +1,149 @@ +# ============================================================================== +# .env.example – OpenProject Docker Compose environment template +# ============================================================================== +# 1. cp .env.example .env +# 2. Edit .env with real values (never commit .env to version control) +# 3. docker compose up -d --build --pull always +# ============================================================================== + +# --------------------------------------------------------------------------- +# Core – OpenProject behaviour +# --------------------------------------------------------------------------- +# Docker image tag. Use XX-slim for the compose setup (recommended). +TAG=17-slim + +# Protocol flag. Set to "false" for first-run / local dev without TLS. +# In production set to "true" and terminate TLS at your reverse proxy. +OPENPROJECT_HTTPS=true + +# Public hostname + optional port that appears in every generated URL and +# e-mail link. Must match what end-users type in the browser. +OPENPROJECT_HOST__NAME=project.martinhal.tech + +# If OpenProject is mounted at a sub-path (e.g. /op), set it here. +# Leave empty for root mount. +OPENPROJECT_RAILS__RELATIVE__URL__ROOT= + +# Edition: "standard" (community) or "bim" +OPENPROJECT_EDITION=standard + +# --------------------------------------------------------------------------- +# Database – PostgreSQL +# --------------------------------------------------------------------------- +# Password for the postgres superuser created by the db container. +# Must match the :password segment in DATABASE_URL below. +POSTGRES_PASSWORD=Chu929qw4Nf67r + +# Full connection string. Edit only if you point at an external database. +DATABASE_URL=postgres://postgres:Chu929qw4Nf67r@db/openproject?pool=20&encoding=unicode&reconnect=true + +# Where Docker stores the PostgreSQL data volume. +# Use a named volume (default) or an absolute host path. +PGDATA=pgdata + +# --------------------------------------------------------------------------- +# Attachments / assets volume +# --------------------------------------------------------------------------- +# Use a named volume (default) or an absolute host path, e.g. +# OPDATA=/var/openproject/assets +# If using an absolute path, run: +# sudo mkdir -p /var/openproject/assets +# sudo chown 1000:1000 -R /var/openproject/assets +OPDATA=opdata + +# --------------------------------------------------------------------------- +# Networking +# --------------------------------------------------------------------------- +# Port exposed by the Caddy proxy to the host. +# Bind to 0.0.0.0 (public) or 127.0.0.1 (localhost-only). +PORT=8080 + +# --------------------------------------------------------------------------- +# Threads +# --------------------------------------------------------------------------- +RAILS_MIN_THREADS=4 +RAILS_MAX_THREADS=16 + +# --------------------------------------------------------------------------- +# Collaborative editing – Hocuspocus +# --------------------------------------------------------------------------- +# URL where the browser connects for real-time collaboration. +# Leave empty to use the auto-generated value: wss:///hocuspocus +COLLABORATIVE_SERVER_URL= + +# ⚠️ CHANGE THIS in production – it protects the WebSocket endpoint. +COLLABORATIVE_SERVER_SECRET=replace_with_a_long_random_string + +# --------------------------------------------------------------------------- +# Inbound email (IMAP) – optional +# --------------------------------------------------------------------------- +IMAP_ENABLED=false + +# =========================================================================== +# SMTP – Outbound e-mail ← fill these in to enable notification mails +# =========================================================================== +# Docs: +# /docs/installation-and-operations/configuration/outbound-emails/ +# /docs/installation-and-operations/configuration/environment/ +# +# These variables are forwarded to *every* OpenProject container that may +# need to send mail (web, worker). Setting them here disables the manual +# SMTP form inside Administration β†’ Emails and notifications. +# =========================================================================== + +# Delivery method – keep as "smtp". +EMAIL_DELIVERY_METHOD=smtp + +# Hostname of your SMTP relay. +# Examples: +# Gmail β†’ smtp.gmail.com +# Outlook/O365 β†’ smtp-mail.outlook.com (or smtp.office365.com) +# SendGrid β†’ smtp.sendgrid.net +# Mailgun β†’ smtp.mailgun.org +# Custom/on-prem β†’ smtp.yourdomain.com +SMTP_ADDRESS=smtp.purelymail.com + +# Port – 587 (STARTTLS, recommended) | 465 (implicit SSL) | 25 (plain, avoid) +SMTP_PORT=587 + +# HELO / EHLO domain sent to the SMTP server. +# Usually the public domain of your OpenProject instance. +SMTP_DOMAIN=smtp.purelymail.com + +# Authentication method. +# plain – most cloud providers (Gmail, O365, SendGrid, Mailgun …) +# login – some on-premises / legacy servers +# cram_md5 – rarely used +SMTP_AUTHENTICATION=plain + +# SMTP user name. +# Gmail β†’ your full Gmail address +# SendGrid β†’ apikey (literal string) +# Mailgun β†’ postmaster@your-sandbox.mailgun.org +# On-premises β†’ usually an e-mail address +SMTP_USER_NAME=projects@martinhakl.tech + +# SMTP password / API key. +# ⚠️ Never commit this file after editing – use .gitignore on .env. +# Gmail β†’ App Password (not your Google password) +# SendGrid β†’ API key starting with SG.xxxxx +# Mailgun β†’ API key from Mailgun dashboard +SMTP_PASSWORD=Chu929qw4Nf67r + +# STARTTLS – upgrade a plain connection to encrypted mid-session. +# Set to "true" when SMTP_PORT=587 (the common case). +# Set to "false" when SMTP_PORT=465 (implicit SSL) or 25. +SMTP_ENABLE_STARTTLS_AUTO=true + +# Implicit SSL – set to "true" only when SMTP_PORT=465. +SMTP_SSL=false + +# Connection timeout in seconds. Increase if your SMTP relay is slow. +SMTP_TIMEOUT=5 + +# --------------------------------------------------------------------------- +# Envelope sender ("From" address in outgoing mails) +# --------------------------------------------------------------------------- +# Must be a valid address on the SMTP account, unless your provider +# allows arbitrary sender addresses. +MAILER_FROM_ADDRESS=projects@martinhakl.tech diff --git a/UnPoller + InfluxDB 2.x + Grafana/.env b/UnPoller + InfluxDB 2.x + Grafana/.env new file mode 100644 index 0000000..427a43a --- /dev/null +++ b/UnPoller + InfluxDB 2.x + Grafana/.env @@ -0,0 +1,38 @@ +# ============================================================ +# UnPoller stack configuration +# This file MUST sit in the same folder as docker-compose.yml +# Do NOT use quotes. Do NOT put spaces around the = sign. +# ============================================================ + +# ---------- InfluxDB (v2) ---------- +INFLUXDB_ADMIN_USER=unpoller +INFLUXDB_ADMIN_PASSWORD=CHANGEME_influx_password +INFLUXDB_ORG=unpoller +INFLUXDB_BUCKET=unpoller +# Generate a real token with: openssl rand -hex 32 +INFLUXDB_ADMIN_TOKEN=REPLACE_WITH_LONG_RANDOM_TOKEN + +# ---------- Grafana ---------- +GRAFANA_USERNAME=admin +GRAFANA_PASSWORD=CHANGEME_grafana_password + +# ---------- UnPoller ---------- +POLLER_TAG=latest +POLLER_DEBUG=false +# Set to true only if you enabled DPI on your controller and want per-app data +POLLER_SAVE_DPI=false + +# ---------- UniFi Controller ---------- +# This is the account you create ON the controller (see instructions). +UNIFI_USER=unpoller +UNIFI_PASS=CHANGEME_set_this_on_your_controller +# +# IMPORTANT: This must be the address of your UniFi CONTROLLER, +# which may or may not be the same box as your Docker host. +# +# * UniFi OS device (UDM / UDM-Pro / UDR / UXG / CloudKey Gen2+): +# NO port -> https://192.168.69.180 +# * Self-hosted Network app / older CloudKey: +# WITH port -> https://192.168.69.180:8443 +# +UNIFI_URL=https://192.168.69.180 diff --git a/UnPoller + InfluxDB 2.x + Grafana/docker-compose.yml b/UnPoller + InfluxDB 2.x + Grafana/docker-compose.yml new file mode 100644 index 0000000..962e32b --- /dev/null +++ b/UnPoller + InfluxDB 2.x + Grafana/docker-compose.yml @@ -0,0 +1,67 @@ +# UnPoller + InfluxDB 2.x + Grafana +# Run on the Docker host at 192.168.69.180 +# All secrets/config live in the .env file next to this file. + +services: + influxdb: + image: influxdb:2.7 + container_name: unpoller-influxdb + restart: unless-stopped + ports: + - '8086:8086' + volumes: + - influxdb-storage:/var/lib/influxdb2 + - influxdb-config:/etc/influxdb2 + environment: + - DOCKER_INFLUXDB_INIT_MODE=setup + - DOCKER_INFLUXDB_INIT_USERNAME=${INFLUXDB_ADMIN_USER} + - DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_ADMIN_PASSWORD} + - DOCKER_INFLUXDB_INIT_ORG=${INFLUXDB_ORG} + - DOCKER_INFLUXDB_INIT_BUCKET=${INFLUXDB_BUCKET} + - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=${INFLUXDB_ADMIN_TOKEN} + - DOCKER_INFLUXDB_INIT_RETENTION=0s # 0s = keep data forever + + grafana: + image: grafana/grafana:latest + container_name: unpoller-grafana + restart: unless-stopped + ports: + - '3000:3000' + volumes: + - grafana-storage:/var/lib/grafana + depends_on: + - influxdb + environment: + - GF_SECURITY_ADMIN_USER=${GRAFANA_USERNAME} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD} + - GF_INSTALL_PLUGINS=grafana-clock-panel,natel-discrete-panel,grafana-piechart-panel + + unpoller: + image: ghcr.io/unpoller/unpoller:${POLLER_TAG} + container_name: unpoller + restart: unless-stopped + ports: + - '9130:9130' # Prometheus /metrics endpoint (optional health check) + depends_on: + - influxdb + - grafana + environment: + # ---- InfluxDB 2.x output ---- + - UP_INFLUXDB_URL=http://influxdb:8086 + - UP_INFLUXDB_ORG=${INFLUXDB_ORG} + - UP_INFLUXDB_BUCKET=${INFLUXDB_BUCKET} + - UP_INFLUXDB_AUTH_TOKEN=${INFLUXDB_ADMIN_TOKEN} + # ---- UniFi controller to poll ---- + - UP_UNIFI_DEFAULT_URL=${UNIFI_URL} + - UP_UNIFI_DEFAULT_USER=${UNIFI_USER} + - UP_UNIFI_DEFAULT_PASS=${UNIFI_PASS} + - UP_UNIFI_DEFAULT_VERIFY_SSL=false # UniFi uses a self-signed cert + - UP_UNIFI_DEFAULT_SAVE_SITES=true + - UP_UNIFI_DEFAULT_SAVE_DPI=${POLLER_SAVE_DPI} + # ---- General ---- + - UP_POLLER_DEBUG=${POLLER_DEBUG} + +volumes: + influxdb-storage: + influxdb-config: + grafana-storage: diff --git a/Uptime_Kuma/docker-compose.yml b/Uptime_Kuma/docker-compose.yml new file mode 100644 index 0000000..6bffe15 --- /dev/null +++ b/Uptime_Kuma/docker-compose.yml @@ -0,0 +1,9 @@ +services: + uptime-kuma: + image: louislam/uptime-kuma:2 + restart: unless-stopped + volumes: + - ./data:/app/data + ports: + # : + - "3001:3001" \ No newline at end of file diff --git a/Vikunja/.env.example b/Vikunja/.env.example new file mode 100644 index 0000000..8b1257b --- /dev/null +++ b/Vikunja/.env.example @@ -0,0 +1,75 @@ +# ============================================================================= +# Vikunja – environment variables +# Copy this file to .env and fill in real values. The .env file is read +# automatically by "docker compose" in the same directory. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# 1. Core / Service +# ----------------------------------------------------------------------------- +# The URL browsers will use to reach Vikunja (no trailing slash). +# This is mandatory when CORS is enabled (the default). +PUBLIC_URL=http://localhost:3456 + +# A long, random secret used to sign JWT tokens. +# Generate one with: openssl rand -hex 32 +JWT_SECRET=REPLACE_ME_WITH_A_RANDOM_64_CHAR_HEX_STRING + +# IANA tz name – e.g. Europe/Lisbon, America/New_York, Asia/Tokyo +TIMEZONE=Europe/Lisbon + +# Set to "false" after you have created all desired user accounts. +ENABLE_REGISTRATION=true + +# ----------------------------------------------------------------------------- +# 2. PostgreSQL +# ----------------------------------------------------------------------------- +DB_USER=vikunja +DB_PASSWORD=REPLACE_WITH_A_STRONG_PASSWORD +DB_NAME=vikunja + +# ----------------------------------------------------------------------------- +# 3. SMTP / Mailer +# ----------------------------------------------------------------------------- +# --- Host & port ------------------------------------------------------------ +# Common presets: +# Gmail smtp.gmail.com 587 (STARTTLS) or 465 (SSL) +# Outlook/M365 smtp-auth.outlook.com 587 +# Postfix (local) 127.0.0.1 25 (set SMTP_FORCE_SSL=false, AUTH=none) +# Mailgun smtp.mailgun.org 587 +# Custom/self your.smtp.server 587 +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 + +# --- Credentials ------------------------------------------------------------ +# For Gmail with 2-FA enabled, use an *App Password*, not your real password. +SMTP_USER=your-email@gmail.com +SMTP_PASSWORD=REPLACE_WITH_APP_OR_REAL_PASSWORD + +# --- Sender address --------------------------------------------------------- +# The "From:" field in outgoing mails. Many providers require this to match +# SMTP_USER or an authorised alias. +SMTP_FROM=your-email@gmail.com + +# --- TLS / SSL options ------------------------------------------------------ +# SMTP_FORCE_SSL – wraps the connection in TLS immediately on connect. +# β€’ true β†’ typically paired with port 465 (implicit TLS / SMTPS) +# β€’ false β†’ expects STARTTLS on port 587 (or plain on 25) +SMTP_FORCE_SSL=false + +# SMTP_SKIP_TLS_VERIFY – skip server-certificate validation. +# Set to true ONLY if you use a self-signed certificate. +SMTP_SKIP_TLS_VERIFY=false + +# SMTP_AUTH_TYPE – authentication method the SMTP server expects: +# plain – username + password in a single base64 blob (default) +# login – username and password sent in two separate challenges +# none – no authentication (e.g. local Postfix accepting anonymous relay) +SMTP_AUTH_TYPE=plain + +# ----------------------------------------------------------------------------- +# 4. Optional – host-side port mapping +# ----------------------------------------------------------------------------- +# The port exposed on the Docker host (maps to container port 3456). +# Leave empty to default to 3456. +HOST_PORT=3456 diff --git a/Vikunja/docker-compose.yml b/Vikunja/docker-compose.yml new file mode 100644 index 0000000..cb9fe5c --- /dev/null +++ b/Vikunja/docker-compose.yml @@ -0,0 +1,98 @@ +# ============================================================================= +# Vikunja β€” Docker Compose with PostgreSQL + SMTP e-mail support +# ============================================================================= +# Before starting the stack run: +# +# mkdir -p ./files ./db +# chown 1000:1000 ./files # Vikunja runs as UID 1000 +# chown 999:999 ./db # PostgreSQL runs as UID 999 +# +# (On some systems you may need: sudo chown -R 999:999 ./db) +# +# Then copy .env.example β†’ .env and fill in every value. +# Start with: docker compose up -d +# Test mailer: docker compose exec vikunja /app/vikunja/vikunja testmail
+# ============================================================================= + +services: + # --------------------------------------------------------------------------- + # PostgreSQL database + # --------------------------------------------------------------------------- + db: + image: postgres:18 + restart: unless-stopped + security_opt: + - no-new-privileges:true + user: "999:999" # PostgreSQL official image default UID/GID + environment: + POSTGRES_USER: ${DB_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: ${DB_NAME} + volumes: + # PostgreSQL 18+ requires mounting at /var/lib/postgresql (not /data subfolder) + # Data will be stored in ./db/18/data automatically + - ./db:/var/lib/postgresql + healthcheck: + test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER -d $$POSTGRES_DB"] + interval: 5s + timeout: 3s + retries: 5 + start_period: 10s + + # --------------------------------------------------------------------------- + # Vikunja (API + frontend in one container) + # --------------------------------------------------------------------------- + vikunja: + image: vikunja/vikunja:latest + restart: unless-stopped + security_opt: + - no-new-privileges:true + # The container defaults to UID 1000 / no group. + # Adjust if your host folders need a different owner. + # user: "1000:1000" + ports: + - "${HOST_PORT:-3456}:3456" + volumes: + - ./files:/app/vikunja/files # uploaded / generated files + depends_on: + db: + condition: service_healthy # wait for postgres to be ready + + # ----------------------------------------------------------------------- + # Environment β€” all sensitive values come from .env + # ----------------------------------------------------------------------- + environment: + # --- Core service ------------------------------------------------------- + VIKUNJA_SERVICE_PUBLICURL: ${PUBLIC_URL} + VIKUNJA_SERVICE_JWTSECRET: ${JWT_SECRET} + VIKUNJA_SERVICE_TIMEZONE: ${TIMEZONE:-UTC} + VIKUNJA_SERVICE_ENABLEREGISTRATION: ${ENABLE_REGISTRATION:-true} + VIKUNJA_SERVICE_ENABLETASKATTACHMENTS: "true" + VIKUNJA_SERVICE_ENABLEEMAILREMINDERS: "true" + + # --- Database ------------------------------------------------------------ + VIKUNJA_DATABASE_TYPE: postgres + VIKUNJA_DATABASE_HOST: db + VIKUNJA_DATABASE_USER: ${DB_USER} + VIKUNJA_DATABASE_PASSWORD: ${DB_PASSWORD} + VIKUNJA_DATABASE_DATABASE: ${DB_NAME} + VIKUNJA_DATABASE_SSLMODE: disable # set to 'require' if TLS is enabled on PG + + # --- SMTP / Mailer ------------------------------------------------------- + # When VIKUNJA_MAILER_ENABLED is true Vikunja sends: + # β€’ registration confirmation mails + # β€’ password-reset mails + # β€’ task-reminder mails (when ENABLEEMAILREMINDERS is also true) + VIKUNJA_MAILER_ENABLED: "true" + VIKUNJA_MAILER_HOST: ${SMTP_HOST} + VIKUNJA_MAILER_PORT: ${SMTP_PORT:-587} + VIKUNJA_MAILER_USERNAME: ${SMTP_USER} + VIKUNJA_MAILER_PASSWORD: ${SMTP_PASSWORD} + VIKUNJA_MAILER_FROMEMAIL: ${SMTP_FROM} + VIKUNJA_MAILER_FORCESSL: ${SMTP_FORCE_SSL:-true} # wraps the connection in TLS from the start (use with port 465) + VIKUNJA_MAILER_SKIPTLSVERIFY: ${SMTP_SKIP_TLS_VERIFY:-false} # set true only for self-signed certs + VIKUNJA_MAILER_AUTHTYPE: ${SMTP_AUTH_TYPE:-plain} # plain | login | none + + # --- CORS (required when frontend & API share the same origin) ---------- + VIKUNJA_CORS_ENABLE: "true" + VIKUNJA_CORS_ORIGINS: ${PUBLIC_URL} \ No newline at end of file diff --git a/Vikunja/env.example b/Vikunja/env.example new file mode 100644 index 0000000..8b1257b --- /dev/null +++ b/Vikunja/env.example @@ -0,0 +1,75 @@ +# ============================================================================= +# Vikunja – environment variables +# Copy this file to .env and fill in real values. The .env file is read +# automatically by "docker compose" in the same directory. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# 1. Core / Service +# ----------------------------------------------------------------------------- +# The URL browsers will use to reach Vikunja (no trailing slash). +# This is mandatory when CORS is enabled (the default). +PUBLIC_URL=http://localhost:3456 + +# A long, random secret used to sign JWT tokens. +# Generate one with: openssl rand -hex 32 +JWT_SECRET=REPLACE_ME_WITH_A_RANDOM_64_CHAR_HEX_STRING + +# IANA tz name – e.g. Europe/Lisbon, America/New_York, Asia/Tokyo +TIMEZONE=Europe/Lisbon + +# Set to "false" after you have created all desired user accounts. +ENABLE_REGISTRATION=true + +# ----------------------------------------------------------------------------- +# 2. PostgreSQL +# ----------------------------------------------------------------------------- +DB_USER=vikunja +DB_PASSWORD=REPLACE_WITH_A_STRONG_PASSWORD +DB_NAME=vikunja + +# ----------------------------------------------------------------------------- +# 3. SMTP / Mailer +# ----------------------------------------------------------------------------- +# --- Host & port ------------------------------------------------------------ +# Common presets: +# Gmail smtp.gmail.com 587 (STARTTLS) or 465 (SSL) +# Outlook/M365 smtp-auth.outlook.com 587 +# Postfix (local) 127.0.0.1 25 (set SMTP_FORCE_SSL=false, AUTH=none) +# Mailgun smtp.mailgun.org 587 +# Custom/self your.smtp.server 587 +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 + +# --- Credentials ------------------------------------------------------------ +# For Gmail with 2-FA enabled, use an *App Password*, not your real password. +SMTP_USER=your-email@gmail.com +SMTP_PASSWORD=REPLACE_WITH_APP_OR_REAL_PASSWORD + +# --- Sender address --------------------------------------------------------- +# The "From:" field in outgoing mails. Many providers require this to match +# SMTP_USER or an authorised alias. +SMTP_FROM=your-email@gmail.com + +# --- TLS / SSL options ------------------------------------------------------ +# SMTP_FORCE_SSL – wraps the connection in TLS immediately on connect. +# β€’ true β†’ typically paired with port 465 (implicit TLS / SMTPS) +# β€’ false β†’ expects STARTTLS on port 587 (or plain on 25) +SMTP_FORCE_SSL=false + +# SMTP_SKIP_TLS_VERIFY – skip server-certificate validation. +# Set to true ONLY if you use a self-signed certificate. +SMTP_SKIP_TLS_VERIFY=false + +# SMTP_AUTH_TYPE – authentication method the SMTP server expects: +# plain – username + password in a single base64 blob (default) +# login – username and password sent in two separate challenges +# none – no authentication (e.g. local Postfix accepting anonymous relay) +SMTP_AUTH_TYPE=plain + +# ----------------------------------------------------------------------------- +# 4. Optional – host-side port mapping +# ----------------------------------------------------------------------------- +# The port exposed on the Docker host (maps to container port 3456). +# Leave empty to default to 3456. +HOST_PORT=3456 diff --git a/WikiJS/wikiJS.zip b/WikiJS/wikiJS.zip new file mode 100644 index 0000000000000000000000000000000000000000..df9f10f76be1bbb7702c3972b5e1116c7265c49b GIT binary patch literal 4544 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 literal 0 HcmV?d00001