initial commit
This commit is contained in:
572
deploy.sh
Normal file
572
deploy.sh
Normal 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"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user