diff --git a/README.md b/README.md index 497c4dd..a7cb1ea 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ ScaleTail provides ready-to-run [Docker Compose](https://docs.docker.com/compose | 📝 **Nanote** | A lightweight, self-hosted note-taking app with Markdown support. | [Details](services/nanote) | | 🤖 **Open WebUI** | A self-hosted AI platform with a ChatGPT-style interface for local and cloud-based models. | [Details](services/open-webui) | | 🔗 **Pingvin Share** | **PROJECT ARCHIVED** A self-hosted file sharing platform. | [Details](services/pingvin-share) | +| 📅 **Radicale** | A lightweight CalDAV and CardDAV server for self-hosted calendar, to-do, and contact sync. | [Details](services/radicale) | | 🔄 **Resilio Sync** | A fast, reliable, and simple file sync and share solution. | [Details](services/resilio-sync) | | 🗂️ **Stirling-PDF** | A web application for managing and editing PDF files. | [Details](services/stirlingpdf) | | 📄 **BentoPDF** | A lightweight, self-hosted web app for viewing and managing PDF documents. | [Details](services/bentopdf) | @@ -173,6 +174,7 @@ ScaleTail provides ready-to-run [Docker Compose](https://docs.docker.com/compose | 🛠️ **Coder** | Self-hosted cloud dev environments with browser IDEs, Terraform-managed workspaces. | [Details](services/coder) | | 🔧 **Cyberchef** | A web app for encryption, encoding, compression, and data analysis. | [Details](services/cyberchef) | | 🐳 **Dockhand** | A modern, lightweight Docker management UI for containers and Compose stacks. | [Details](services/dockhand) | +| 🐳 **Dockge** | A lightweight, self-hosted Docker Compose stack manager with a clean web UI. | [Details](services/dockge) | | 🖥️ **Dozzle** | A real-time log viewer for Docker containers. | [Details](services/dozzle) | | 🔁 **FossFLOW** | A self-hosted tool to make beautiful isometric infrastructure diagrams. | [Details](services/fossflow) | | 🖥️ **GitSave** | A self-hosted service to back up your GitHub repositories via a simple REST API and scheduled runs. | [Details](services/gitsave) | @@ -269,6 +271,13 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod jackspiering + + + michaelhodges +
+ michaelhodges +
+ ChillBill77 @@ -277,10 +286,10 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod - - michaelhodges + + lcs-crr
- michaelhodges + lcs-crr
@@ -290,6 +299,8 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod adamsthws + + theryukverse @@ -297,8 +308,6 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod theryukverse - - KhaaL @@ -334,6 +343,8 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod MajnuRangeela + + mikkotor @@ -341,8 +352,6 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod mikkotor - - NI-R0 @@ -378,6 +387,8 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod guybrush115 + + pjv @@ -385,8 +396,6 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod pjv - - wedge22 @@ -422,6 +431,8 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod gaetan-petit + + dfilvtov @@ -429,8 +440,6 @@ A huge thank you to all our contributors! ScaleTail wouldn’t be what it is tod dfilvtov - - cdkooistra diff --git a/services/dockge/.env b/services/dockge/.env new file mode 100644 index 0000000..147037d --- /dev/null +++ b/services/dockge/.env @@ -0,0 +1,19 @@ +#version=1.1 +#URL=https://github.com/tailscale-dev/ScaleTail +#COMPOSE_PROJECT_NAME= # Optional: only use when running multiple deployments on the same infrastructure. + +# Service Configuration +SERVICE=dockge # Service name (e.g., adguard). Used as hostname in Tailscale and for container naming (app-${SERVICE}). +IMAGE_URL=louislam/dockge:1 # Docker image URL from container registry (e.g., adguard/adguard-home). + +# Network Configuration +SERVICEPORT= # Port to expose to local network. Uncomment the "ports:" section in compose.yaml to enable. +DNS_SERVER=9.9.9.9 # Preferred DNS server for Tailscale. Uncomment the "dns:" section in compose.yaml to enable. + +# Tailscale Configuration +TS_AUTHKEY= # Auth key from https://tailscale.com/admin/authkeys. See: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key for instructions. + +# Optional Service variables +STACKS_DIR= # Absolute path on host to store stack files. Must be bind mounted to the same path in compose.yaml. +PUID=1000 # Set the stack file/dir ownership to this user +PGID=1000 # Set the stack file/dir ownership to this group \ No newline at end of file diff --git a/services/dockge/README.md b/services/dockge/README.md new file mode 100644 index 0000000..9fae38d --- /dev/null +++ b/services/dockge/README.md @@ -0,0 +1,23 @@ +# Dockge with Tailscale Sidecar Configuration + +This Docker Compose configuration sets up Dockge with a Tailscale sidecar container, enabling secure, private access to your Docker Compose management UI over your Tailnet. With this setup, your Dockge instance is not exposed to the public internet and is only accessible from authorized devices connected via Tailscale. + +## Dockge + +[Dockge](https://github.com/louislam/dockge) is a lightweight, self-hosted Docker Compose stack manager built for simplicity and control. Created by the developer behind Uptime Kuma, Dockge provides an intuitive web interface for managing, editing, and deploying docker-compose.yml stacks without relying solely on the CLI. + +It is especially well-suited for homelabs, self-hosted environments, and DevOps workflows where multiple services are managed via Docker Compose. + +## Key Features + +* 🐳 Web-based Docker Compose stack management +* ✏️ Live editing of docker-compose.yml files +* ▶️ One-click start, stop, and restart of stacks +* 📜 Real-time container logs viewer +* 📦 Multi-stack organization via directories +* ⚡ Lightweight and fast interface +* 🔍 Clear visibility into container status + +## Important Notice + +Make sure to populate the `STACKS_DIR=` variable in the `.env` before first startup. diff --git a/services/dockge/compose.yaml b/services/dockge/compose.yaml new file mode 100644 index 0000000..5a30dd1 --- /dev/null +++ b/services/dockge/compose.yaml @@ -0,0 +1,67 @@ +configs: + ts-serve: + content: | + {"TCP":{"443":{"HTTPS":true}}, + "Web":{"$${TS_CERT_DOMAIN}:443": + {"Handlers":{"/": + {"Proxy":"http://127.0.0.1:5001"}}}}, + "AllowFunnel":{"$${TS_CERT_DOMAIN}:443":false}} + +services: + # Make sure you have updated/checked the .env file with the correct variables. + # All the ${ xx } need to be defined there. + # Tailscale Sidecar Configuration + tailscale: + image: tailscale/tailscale:latest # Image to be used + container_name: tailscale-${SERVICE} # Name for local container management + hostname: ${SERVICE} # Name used within your Tailscale environment + environment: + - TS_AUTHKEY=${TS_AUTHKEY} + - TS_STATE_DIR=/var/lib/tailscale + - TS_SERVE_CONFIG=/config/serve.json # Tailscale Serve configuration to expose the web interface on your local Tailnet - remove this line if not required + - TS_USERSPACE=false + - TS_ENABLE_HEALTH_CHECK=true # Enable healthcheck endpoint: "/healthz" + - TS_LOCAL_ADDR_PORT=127.0.0.1:41234 # The : for the healthz endpoint + #- TS_ACCEPT_DNS=true # Uncomment when using MagicDNS + - TS_AUTH_ONCE=true + configs: + - source: ts-serve + target: /config/serve.json + volumes: + - ./config:/config # Config folder used to store Tailscale files - you may need to change the path + - ./ts/state:/var/lib/tailscale # Tailscale requirement - you may need to change the path + devices: + - /dev/net/tun:/dev/net/tun # Network configuration for Tailscale to work + cap_add: + - net_admin # Tailscale requirement + #ports: + # - 0.0.0.0:${SERVICEPORT}:${SERVICEPORT} # Binding port ${SERVICE}PORT to the local network - may be removed if only exposure to your Tailnet is required + # If any DNS issues arise, use your preferred DNS provider by uncommenting the config below + #dns: + # - ${DNS_SERVER} + healthcheck: + test: [ "CMD", "wget", "--spider", "-q", "http://127.0.0.1:41234/healthz" ] # Check Tailscale has a Tailnet IP and is operational + interval: 1m # How often to perform the check + timeout: 10s # Time to wait for the check to succeed + retries: 3 # Number of retries before marking as unhealthy + start_period: 10s # Time to wait before starting health checks + restart: always + + # ${SERVICE} + application: + image: ${IMAGE_URL} # Image to be used + network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale + container_name: app-${SERVICE} # Name for local container management + environment: + # Varibles are delared in .env file. + - DOCKGE_STACKS_DIR=${STACKS_DIR} # Tell Dockge where your stacks directory is + - PUID=${PUID} # Set the stack file/dir ownership to this user + - PGID=${PGID} # Set the stack file/dir ownership to this group + volumes: + - ./${SERVICE}-data/app/config:/app/data + - /var/run/docker.sock:/var/run/docker.sock + - ${STACKS_DIR}:${STACKS_DIR} + depends_on: + tailscale: + condition: service_healthy + restart: always \ No newline at end of file diff --git a/services/radicale/.env b/services/radicale/.env new file mode 100644 index 0000000..199dbfe --- /dev/null +++ b/services/radicale/.env @@ -0,0 +1,17 @@ +#version=1.1 +#URL=https://github.com/tailscale-dev/ScaleTail +#COMPOSE_PROJECT_NAME= # Optional: only use when running multiple deployments on the same infrastructure. + +# Service Configuration +SERVICE=radicale # Service name (e.g., adguard). Used as hostname in Tailscale and for container naming (app-${SERVICE}). +IMAGE_URL=tomsquest/docker-radicale # Docker image URL from container registry (e.g., adguard/adguard-home). + +# Network Configuration +SERVICEPORT=5232 # Port to expose to local network. Uncomment the "ports:" section in compose.yaml to enable. +DNS_SERVER=9.9.9.9 # Preferred DNS server for Tailscale. Uncomment the "dns:" section in compose.yaml to enable. + +# Tailscale Configuration +TS_AUTHKEY=... # Auth key from https://tailscale.com/admin/authkeys. See: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key for instructions. + +# Optional Service variables +# PUID=1000 diff --git a/services/radicale/README.md b/services/radicale/README.md new file mode 100644 index 0000000..d3271c6 --- /dev/null +++ b/services/radicale/README.md @@ -0,0 +1,73 @@ +# Radicale with Tailscale Sidecar Configuration + +This Docker Compose configuration sets up [Radicale](https://radicale.org/) with Tailscale as a sidecar container to keep the app reachable over your Tailnet. + +## Radicale + +[Radicale](https://radicale.org/) is a small but powerful CalDAV (calendars, to-do lists) and CardDAV (contacts) server. It is lightweight, easy to configure, and requires minimal resources, making it a great self-hosted alternative to cloud-based calendar and contact sync services. + +## Key Features + +- CalDAV and CardDAV support for syncing calendars, to-do lists, and contacts +- Works with any compliant client (Thunderbird, GNOME Calendar, DAVx5, Apple Calendar, etc.) +- Lightweight with minimal resource usage +- Simple file-based storage +- Web interface for managing collections +- Built-in access control and authentication + +## Configuration Overview + +In this setup, the `tailscale-radicale` service runs Tailscale, which manages secure networking for Radicale. The `radicale` service utilizes the Tailscale network stack via Docker's `network_mode: service:` configuration. This keeps the app Tailnet-only unless you intentionally expose ports. + +The container runs with hardened security settings: read-only filesystem, no new privileges, dropped capabilities, and resource limits (256M memory, 50 pids). + +## Prerequisites + +- This image uses [tomsquest/docker-radicale](https://github.com/tomsquest/docker-radicale). Refer to their documentation for advanced configuration options. +- To configure users and authentication, mount a custom config file or refer to the [Radicale documentation](https://radicale.org/v3.html#configuration). + +## Creating Users + +Radicale uses `htpasswd` for authentication. To set up users: + +1. **Create the required directories:** + + ```bash + mkdir -p ./${SERVICE}-data ./config + ``` + +2. **Create an `htpasswd` file** with your first user (requires `apache2-utils` on Debian/Ubuntu or `httpd-tools` on Fedora): + + ```bash + htpasswd -B -c ./${SERVICE}-data/users + ``` + + To add more users without overwriting the file, omit `-c`: + + ```bash + htpasswd -B ./${SERVICE}-data/users + ``` + +3. **Fill out config file** at `./config/${SERVICE}.conf`: + + ```ini + [auth] + type = htpasswd + htpasswd_filename = /config/users + htpasswd_encryption = bcrypt + + [storage] + filesystem_folder = /data/collections + ``` + +4. **Restart the stack:** + + ```bash + docker compose down && docker compose up -d + ``` + +## Files to check + +Please check the following contents for validity as some variables need to be defined upfront. + +- `.env` — Main variable: `TS_AUTHKEY` diff --git a/services/radicale/compose.yaml b/services/radicale/compose.yaml new file mode 100644 index 0000000..dffcb6b --- /dev/null +++ b/services/radicale/compose.yaml @@ -0,0 +1,73 @@ +configs: + ts-serve: + content: | + {"TCP":{"443":{"HTTPS":true}}, + "Web":{"$${TS_CERT_DOMAIN}:443": + {"Handlers":{"/": + {"Proxy":"http://127.0.0.1:5232"}}}}, + "AllowFunnel":{"$${TS_CERT_DOMAIN}:443":false}} + +services: + # Make sure you have updated/checked the .env file with the correct variables. + # All the ${ xx } need to be defined there. + # Tailscale Sidecar Configuration + tailscale: + image: tailscale/tailscale:latest # Image to be used + container_name: tailscale-${SERVICE} # Name for local container management + hostname: ${SERVICE} # Name used within your Tailscale environment + environment: + - TS_AUTHKEY=${TS_AUTHKEY} + - TS_STATE_DIR=/var/lib/tailscale + - TS_SERVE_CONFIG=/config/serve.json # Tailscale Serve configuration to expose the web interface on your local Tailnet - remove this line if not required + - TS_USERSPACE=false + - TS_ENABLE_HEALTH_CHECK=true # Enable healthcheck endpoint: "/healthz" + - TS_LOCAL_ADDR_PORT=127.0.0.1:41234 # The : for the healthz endpoint + #- TS_ACCEPT_DNS=true # Uncomment when using MagicDNS + - TS_AUTH_ONCE=true + configs: + - source: ts-serve + target: /config/serve.json + volumes: + - ./config:/config # Config folder used to store Tailscale files - you may need to change the path + - ./ts/state:/var/lib/tailscale # Tailscale requirement - you may need to change the path + devices: + - /dev/net/tun:/dev/net/tun # Network configuration for Tailscale to work + cap_add: + - net_admin # Tailscale requirement + #ports: + # - 0.0.0.0:${SERVICEPORT}:${SERVICEPORT} # Binding port ${SERVICE}PORT to the local network - may be removed if only exposure to your Tailnet is required + # If any DNS issues arise, use your preferred DNS provider by uncommenting the config below + #dns: + # - ${DNS_SERVER} + healthcheck: + test: [ "CMD", "wget", "--spider", "-q", "http://127.0.0.1:41234/healthz" ] # Check Tailscale has a Tailnet IP and is operational + interval: 1m # How often to perform the check + timeout: 10s # Time to wait for the check to succeed + retries: 3 # Number of retries before marking as unhealthy + start_period: 10s # Time to wait before starting health checks + restart: always + + # ${SERVICE} + application: + image: ${IMAGE_URL} # Image to be used + network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale + container_name: app-${SERVICE} # Name for local container management + environment: + - TAKE_FILE_OWNERSHIP=true + volumes: + - ./${SERVICE}-data/app/data:/data + - ./config/${SERVICE}.conf:/config/radicale.conf + - ./${SERVICE}-data/users:/config/users + command: ["/venv/bin/radicale", "--config", "/config/radicale.conf"] + depends_on: + tailscale: + condition: service_healthy + healthcheck: + test: + - CMD-SHELL + - wget -qO- http://127.0.0.1:5232/.well-known/carddav || exit 1 + interval: 1m # How often to perform the check + timeout: 10s # Time to wait for the check to succeed + retries: 3 # Number of retries before marking as unhealthy + start_period: 30s # Time to wait before starting health checks + restart: always