Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ ScaleTail provides ready-to-run [Docker Compose](https://docs.docker.com/compose
| 📅 **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) |
| 📁 **Seafile** | A self-hosted file syncing and collaboration platform with file sharing, versioning, and team library support. | [Details](services/seafile) |
| 🔄 **Skerry Sync** | A self-hosted, zero-knowledge sync server for the Skerry SSH client. | [Details](services/skerry-sync) |
| 🗂️ **Stirling-PDF** | A web application for managing and editing PDF files. | [Details](services/stirlingpdf) |
| 💰 **Sure Finance** | A self-hosted personal finance and budgeting app with optional AI insights. | [Details](services/sure) |
| 🏦 **Subtrackr** | A self-hosted web app to track subscriptions, renewal dates, costs, and payment methods. | [Details](services/subtrackr) |
Expand Down Expand Up @@ -198,6 +199,7 @@ ScaleTail provides ready-to-run [Docker Compose](https://docs.docker.com/compose
| 🖥️ **Portainer** | A lightweight management UI which allows you to easily manage your Docker environments. | [Details](services/portainer) |
| 🔍 **searXNG** | A free internet metasearch engine which aggregates results from various search services. | [Details](services/searxng) |
| 🧠 **Ollama** | A self-hosted solution for running open large language models (LLMs) locally with an OpenAI-compatible API. | [Details](services/ollama) |
| 🖥️ **Termix** | A self-hosted server management platform with SSH terminals, remote desktops, tunnels, and Docker management. | [Details](services/termix) |

### 📈 Monitoring and Analytics

Expand Down
32 changes: 32 additions & 0 deletions services/matrix/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#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=matrix
IMAGE_URL=matrixdotorg/synapse:latest

# Network Configuration
SERVICEPORT=443 ## The webport will be exposed to the tailnet. Change if needed.
DNS_SERVER=9.9.9.9 # Preferred DNS server for Tailscale. Uncomment the "dns:" section in compose.yaml to enable.

# Tailscale Configuration
TS_AUTHKEY=

# Time Zone setting for containers
TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

# Matrix Synapse Settings
SYNAPSE_SERVER_NAME=matrix.<tailnet>.ts.net ## Change to your server name (e.g., matrix.yourdomain.com)
SYNAPSE_REPORT_STATS=no ## Set to "yes" to enable anonymous statistics reporting

# UID/GID for Synapse container (default: 991)
UID=991
GID=991

# Postgres Settings (recommended for production)
POSTGRES_USER=synapse ## Please Change
POSTGRES_PASSWORD=
POSTGRES_DB=synapse

#EXAMPLE_VAR="Environment variable"
107 changes: 107 additions & 0 deletions services/matrix/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
configs:
ts-serve:
content: |
{"TCP":{"443":{"HTTPS":true}},
"Web":{"$${TS_CERT_DOMAIN}:443":
{"Handlers":{
"/":{"Proxy":"http://127.0.0.1:8008"},
"/.well-known/matrix/client":{"Static":{"Path":"/config/well-known-matrix-client.json"}},
"/.well-known/matrix/server":{"Static":{"Path":"/config/well-known-matrix-server.json"}}
}}},
"AllowFunnel":{"$${TS_CERT_DOMAIN}:443":true}}

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 <addr>:<port> 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

# Matrix Synapse
application:
image: ${IMAGE_URL} # Image to be used
container_name: app-${SERVICE} # Name for local container management
network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale
environment:
- TZ=${TZ}
- SYNAPSE_SERVER_NAME=${SYNAPSE_SERVER_NAME}
- SYNAPSE_REPORT_STATS=${SYNAPSE_REPORT_STATS}
- SYNAPSE_CONFIG_DIR=/data
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
- SYNAPSE_DATA_DIR=/data
- UID=${UID:-991}
- GID=${GID:-991}
volumes:
- ./${SERVICE}-data:/data
depends_on:
database:
condition: service_healthy
tailscale:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"]
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

# PostgreSQL Database (recommended for production)
database:
image: postgres:16-alpine
container_name: db-${SERVICE}
restart: always
security_opt:
- no-new-privileges:true
pids_limit: 100
read_only: true
tmpfs:
- /tmp
- /var/run/postgresql
volumes:
- ./${SERVICE}-data/postgres:/var/lib/postgresql/data
environment:
- TZ=${TZ}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
36 changes: 36 additions & 0 deletions services/nextcloud/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#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=nextcloud
IMAGE_URL=nextcloud:apache # Docker image URL from container registry

# Network Configuration
SERVICEPORT=80 # 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.
TAILNET_NAME= # Your Tailscale network name (found in admin console)

# Time Zone setting for containers
TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

# Database Configuration (MariaDB)
MYSQL_ROOT_PASSWORD=
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
MYSQL_PASSWORD=

# Nextcloud Admin Credentials (auto-created on first run)
NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=
NEXTCLOUD_TRUSTED_DOMAINS=

# Optional Service variables
# PUID=1000
# PHP_MEMORY_LIMIT=512M
# PHP_UPLOAD_LIMIT=512M

#EXAMPLE_VAR="Environment varibale"
115 changes: 115 additions & 0 deletions services/nextcloud/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
configs:
ts-serve:
content: |
{"TCP":{"443":{"HTTPS":true}},
"Web":{"$${TS_CERT_DOMAIN}:443":
{"Handlers":{"/":
{"Proxy":"http://127.0.0.1:80"}}}},
"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 <addr>:<port> for the healthz endpoint
- TS_ACCEPT_DNS=true # Enable MagicDNS for Tailnet DNS resolution
- 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:8085:${SERVICEPORT} # Binding port ${SERVICEPORT} 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:
- MYSQL_HOST=127.0.0.1
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- REDIS_HOST=localhost
- REDIS_HOST_PORT=6379
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS}
- OVERWRITEPROTOCOL=https
- OVERWRITECLI_URL=https://${SERVICE}.${TAILNET_NAME}.ts.net
- TZ=${TZ}
volumes:
- ./${SERVICE}-data/html:/var/www/html
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
tailscale:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/status.php"] # Check if Nextcloud status endpoint responds
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: 60s # Time to wait before starting health checks - Nextcloud needs time to initialize
restart: always

db:
image: mariadb:lts # MariaDB LTS for production use
network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale
container_name: app-${SERVICE}-database # Name for local container management
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW # Required MariaDB configuration for Nextcloud
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
volumes:
- ./${SERVICE}-data/db:/var/lib/mysql
healthcheck:
test: ["CMD", "mariadb-admin", "ping", "-h", "localhost"] # Check if MariaDB is responsive
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

redis:
image: redis:alpine # Redis for caching and file locking
network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale
container_name: app-${SERVICE}-redis # Name for local container management
healthcheck:
test: ["CMD", "redis-cli", "ping"] # Check if Redis responds to ping
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
41 changes: 41 additions & 0 deletions services/skerry-sync/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#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=skerry-sync
IMAGE_URL=secherkasov/skerry-sync:latest

# Network Configuration
SERVICEPORT=8080
DNS_SERVER=9.9.9.9

# Tailscale Configuration
TS_AUTHKEY=

# Time Zone setting for containers
TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

# Skerry Sync Configuration
# SQLite database URL inside the container. Default file is /data/skerry-sync.db.
SKERRY_DB_URL=jdbc:sqlite:/data/skerry-sync.db
# Database credentials (PostgreSQL). Leave empty for SQLite.
SKERRY_DB_USER=
SKERRY_DB_PASSWORD=
# REQUIRED: stable JWT signing secret. Generate with: openssl rand -base64 48
# Keep it stable across restarts, otherwise all issued tokens are invalidated.
# The server refuses to start with the upstream default unless SKERRY_DEV=1.
SKERRY_JWT_SECRET="REPLACE_WITH_STABLE_SECRET"
# Operator console token for /console and /admin/*. Generate with: openssl rand -hex 16
# Empty means the admin data endpoints stay closed.
SKERRY_ADMIN_TOKEN=

# --- PostgreSQL (optional, instead of SQLite) ---
# To switch, uncomment the `db` service in compose.yaml, uncomment the
# `depends_on` entry for it, and set:
#SKERRY_DB_URL=jdbc:postgresql://localhost:5432/skerry
#SKERRY_DB_USER=skerry
#SKERRY_DB_PASSWORD="REPLACE_WITH_DB_PASSWORD"
# Initial database password. Generate with: openssl rand -hex 24
# Keep it in sync with SKERRY_DB_PASSWORD above.
#POSTGRES_PASSWORD="REPLACE_WITH_DB_PASSWORD"
Loading