initial commit

This commit is contained in:
2026-03-04 06:03:45 +01:00
commit 49c75768ba
17 changed files with 572 additions and 0 deletions
+572
View File
@@ -0,0 +1,572 @@
#!/usr/bin/env bash
set -euo pipefail
# Ensure script is run as root (required for apt + /etc)
if [[ "$EUID" -ne 0 ]]; then
echo "Please run as root (or use sudo)." >&2
exit 1
fi
# what this script needs to do:
# request all install parameters needed from user
# ---- User input ----
read -rp "Admin email: " adminemail < /dev/tty
read -rsp "Admin password: " adminpass < /dev/tty
echo
read -rp "Timezone (e.g. Europe/Amsterdam): " timezone < /dev/tty
read -rp "Domain (e.g. example.com): " domain < /dev/tty
# Public IP (tries multiple services)
publicip="$(curl -fsS https://api.ipify.org || curl -fsS https://ifconfig.me || echo "UNKNOWN")"
# Local IP (first non-loopback)
localip="$(hostname -I | awk '{print $1}')"
# generate random passwords for DB hosts and other secrets
# ---- Random generators ----
rand_hex() { openssl rand -hex 24; }
rand_b64() { openssl rand -base64 32; }
ownclouddbpass="$(rand_hex)"
ownclouddbrootpass="$(rand_hex)"
convertxJWT="$(rand_hex)"
bookstackkey="$(rand_b64)" # base64 as requested
bookstackdbpass="$(rand_hex)"
bookstackdbrootpass="$(rand_hex)"
onlyofficeJWT="$(rand_hex)"
# ---- Debug print (optional — remove in production) ----
echo "Configuration summary:"
printf "%-25s %s\n" \
"Admin email:" "$adminemail" \
"Timezone:" "$timezone" \
"Domain:" "$domain" \
"Public IP:" "$publicip" \
"Local IP:" "$localip"
# install docker
echo "Updating apt and installing prerequisites..."
apt update
apt install -y ca-certificates curl
echo "Setting up Docker GPG key..."
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "Adding Docker apt repository..."
. /etc/os-release
cat > /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: ${UBUNTU_CODENAME:-$VERSION_CODENAME}
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
echo "Updating apt and installing Docker..."
apt update
apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
echo "Docker installation complete."
docker --version
# install dockge
mkdir -p /opt/stacks /opt/dockge
cd /opt/dockge
# Download your compose.yaml
curl "https://dockge.kuma.pet/compose.yaml?port=5001&stacksPath=%2Fopt%2Fstacks" --output compose.yaml
# Start the Server
# docker compose up -d
# create directories in /opt/stacks for containers
# directories needed: npm,dozzle,kuma,browser,site,owncloud,vaultwarden,wireguard,convertx,it-tools,bookstack,jellyfin,onlyoffice,downloader,dashboard,pihole
cd /opt/stacks
mkdir /opt/stacks/{npm,dozzle,kuma,browser,site,owncloud,vaultwarden,wireguard,convertx,it-tools,bookstack,jellyfin,onlyoffice,downloader,dashboard,pihole}
# write docker setup for each component to correct directories
# Nginx Proxy:
# needed: compose.yml, auto-generated proxy host files
# variables needed: domain, admin email, admin pass
cat > /opt/stacks/npm/compose.yml <<EOF
services:
app:
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
networks:
- dockge_default
ports:
# These ports are in format <host-port>:<container-port>
- 80:80 # Public HTTP Port
- 443:443 # Public HTTPS Port
- 81:81 # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
TZ: $timezone
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
dockge_default:
external: true
EOF
# Uptime Kuma:
# needed: compose.yml
# variables needed: admin email, admin pass
cat > /opt/stacks/kuma/compose.yml <<EOF
services:
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./data:/app/data
networks:
- dockge_default
dns:
- 1.1.1.1
- 8.8.8.8
networks:
dockge_default:
external: true
EOF
# File Browser:
# needed: compose.yml
# variables needed: admin email, admin pass
cat > /opt/stacks/browser/compose.yml <<EOF
services:
browser:
image: filebrowser/filebrowser
privileged: true
container_name: browser
user: root
networks:
- dockge_default
volumes:
- /opt/stacks:/srv/stacks
- ./filebrowser.db:/database.db
restart: unless-stopped
networks:
dockge_default:
external: true
EOF
# Main Site:
# needed: compose.yml
cat > /opt/stacks/site/compose.yml <<EOF
services:
site:
image: lscr.io/linuxserver/nginx:latest
restart: unless-stopped
user: root
networks:
- dockge_default
environment:
TZ: $timezone
volumes:
- ./config:/config
networks:
dockge_default:
external: true
EOF
# owncloud:
# needed: compose.yml, additional config?
# variables needed: admin email, admin pass
cat > /opt/stacks/owncloud/compose.yml <<EOF
services:
owncloud_server:
image: owncloud/server:latest
container_name: owncloud_server
restart: always
networks:
- dockge_default
depends_on:
- owncloud_db
- owncloud_redis
environment:
OWNCLOUD_DOMAIN: https://cloud.$domain
OWNCLOUD_TRUSTED_DOMAINS: localhost, cloud.$domain
OWNCLOUD_DB_TYPE: mysql
OWNCLOUD_DB_NAME: owncloud
OWNCLOUD_DB_USERNAME: owncloud
OWNCLOUD_DB_PASSWORD: $ownclouddbpass
OWNCLOUD_DB_HOST: owncloud_db
OWNCLOUD_ADMIN_USERNAME: $adminemail
OWNCLOUD_ADMIN_PASSWORD: $adminpass
OWNCLOUD_MYSQL_UTF8MB4: true
OWNCLOUD_REDIS_ENABLED: true
OWNCLOUD_REDIS_HOST: owncloud_redis
healthcheck:
test: ["CMD", "/usr/bin/healthcheck"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- ./data:/mnt/data
owncloud_db:
image: mariadb:10.11 # minimum required ownCloud version is 10.9
container_name: owncloud_db
restart: always
networks:
- dockge_default
environment:
- MYSQL_ROOT_PASSWORD=$ownclouddbrootpass
- MYSQL_USER=owncloud
- MYSQL_PASSWORD=$ownclouddbpass
- MYSQL_DATABASE=owncloud
- MARIADB_AUTO_UPGRADE=1
command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- ./mysql:/var/lib/mysql
owncloud_redis:
image: redis:6
container_name: owncloud_redis
restart: always
networks:
- dockge_default
command: ["--databases", "1"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- ./redis:/data
networks:
dockge_default:
external: true
EOF
# vaultwarden:
# needed: compose.yml
cat > /opt/stacks/vaultwarden/compose.yml <<EOF
services:
vaultwarden:
container_name: vaultwarden
image: vaultwarden/server:latest
restart: unless-stopped
volumes:
- ./data:/data/
networks:
- dockge_default
networks:
dockge_default:
external: true
EOF
# wireguard-easy:
# needed: compose.yml
# variables needed: admin email, admin pass
cat > /opt/stacks/wireguard/compose.yml <<EOF
services:
wireguard:
container_name: wireguard
environment:
WG_HOST: $publicip
PASSWORD: $adminpass
volumes:
- ./wireguard:/etc/wireguard
ports:
-51820/udp
networks:
- dockge_default
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
restart: unless-stopped
image: weejewel/wg-easy
networks:
dockge_default:
external: true
EOF
# convertx:
# needed: compose.yml
cat > /opt/stacks/convertx/compose.yml <<EOF
services:
convertx:
image: ghcr.io/c4illin/convertx
container_name: convertx
restart: unless-stopped
networks:
- dockge_default
environment:
JWT_SECRET: $convertxJWT
HTTP_ALLOWED: true
ALLOW_UNAUTHENTICATED: true
ACCOUNT_REGISTRATION: false
volumes:
- ./data:/app/data
networks:
dockge_default:
external: true
EOF
# it-tools:
# needed: compose.yml
cat > /opt/stacks/it-tools/compose.yml <<EOF
services:
it-tools:
container_name: it-tools
restart: unless-stopped
networks:
- dockge_default
image: corentinth/it-tools:latest
networks:
dockge_default:
external: true
EOF
# bookstack:
# needed: compose.yml
# variables needed: admin email, admin pass
cat > /opt/stacks/bookstack/compose.yml <<EOF
services:
bookstack:
image: lscr.io/linuxserver/bookstack:latest
container_name: bookstack
environment:
TZ: $timezone
APP_URL: https://docs.$domain
APP_KEY: base64:$bookstackkey
DB_HOST: bookstack_db
DB_PORT: 3306
DB_DATABASE: bookstack
DB_USERNAME: bookstack
DB_PASSWORD: $bookstackdbpass
volumes:
- ./config:/config
networks:
- dockge_default
restart: unless-stopped
bookstack_db:
image: lscr.io/linuxserver/mariadb:latest
container_name: bookstack_db
networks:
- dockge_default
environment:
TZ: $timezone
MYSQL_ROOT_PASSWORD: $bookstackdbrootpass
MYSQL_DATABASE: bookstack
MYSQL_USER: bookstack
MYSQL_PASSWORD: $bookstackdbpass
restart: unless-stopped
networks:
dockge_default:
external: true
EOF
# jellyfin:
# needed: compose.yml
# variables needed: admin email, admin pass
cat > /opt/stacks/jellyfin/compose.yml <<EOF
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
user: root
networks:
- dockge_default
volumes:
- ./config:/config
- ./cache:/cache
- ./media:/media:ro
- ./fonts:/usr/local/share/fonts/custom:ro
restart: unless-stopped
environment:
JELLYFIN_PublishedServerUrl: https://video.$domain
TZ: $timezone
networks:
dockge_default:
external: true
EOF
# onlyoffice:
# needed: compose.yml
cat > /opt/stacks/onlyoffice/compose.yml <<EOF
services:
documentserver:
stdin_open: true
tty: true
restart: always
networks:
- dockge_default
image: onlyoffice/documentserver
dns:
- 1.1.1.1
- 8.8.8.8
environment:
JWT_SECRET: $onlyofficeJWT
JWT_IN_BODY: true
networks:
dockge_default:
external: true
EOF
# dashboard:
# needed: compose.yml
cat > /opt/stacks/dashboard/compose.yml <<EOF
services:
dashboard:
image: lscr.io/linuxserver/heimdall:latest
container_name: dashboard
environment:
- PUID=1000
- PGID=1000
- TZ=$timezone
- ALLOW_INTERNAL_REQUESTS=false #optional
- APP_NAME=Home
volumes:
- ./Heimdall:/config
networks:
- dockge_default
restart: unless-stopped
networks:
dockge_default:
external: true
EOF
# dozzle
cat >/opt/stacks/dozzle/compose.yml <<EOF
services:
dozzle:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- dockge_default
image: amir20/dozzle:latest
restart: always
networks:
dockge_default:
external: true
EOF
# pihole
cat >/opt/stacks/pihole/compose.yml <<EOF
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
dns:
- 1.1.1.1
ports:
- 53:53/tcp
- 53:53/udp
environment:
TZ: Europe/Amsterdam
FTLCONF_WEBSERVER_API_PASSWORD: z5fGWz2i0q
volumes:
- ./config:/etc/pihole
- ./dns:/etc/dnsmasq.d
cap_add:
- NET_ADMIN
restart: unless-stopped
networks:
- dockge_default
networks:
dockge_default:
external: true
EOF
# install mailcow to /opt/stacks/mailcow so it shows up in dockge
apt install -y git openssl curl gawk coreutils grep jq
umask 0022
#cd /opt/stacks
#git clone https://github.com/mailcow/mailcow-dockerized mailcow
#cd /opt/stacks/mailcow
#bash ./generate_config.sh < /dev/tty
# install youtube downloader to /opt/stacks/downloader so it shows up in dockge
cd /opt/stacks
git clone https://github.com/trantienloi2404/youtube-downloader.git downloader
cd /opt/dockge
docker compose up -d
#disable stub listener
echo "DNSStubListener=no" | tee -a /etc/systemd/resolved.conf
echo ""
echo ""
echo ""
echo "you can now access the dockge GUI interface at $localip:5001 and the proxy interface at $localip:81 once you start it from Dockge. be sure to forward ports 80, 443 and 51820 to $localip in your router settings"
echo "please reboot before further setup"
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File