From 1c4e809012954c94221beefce3b581e57ec140aa Mon Sep 17 00:00:00 2001 From: pompydev Date: Wed, 21 May 2025 20:53:59 +0900 Subject: [PATCH] add dokploy install script --- homelab/dokploy/justfile | 211 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 homelab/dokploy/justfile diff --git a/homelab/dokploy/justfile b/homelab/dokploy/justfile new file mode 100644 index 0000000..ad317e3 --- /dev/null +++ b/homelab/dokploy/justfile @@ -0,0 +1,211 @@ +# See https://docs.dokploy.com/docs/core/manual-installation + +install POSTGRES_PASSWORD: + #!/usr/bin/env bash + + if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" >&2 + exit 1 + fi + + # check if something is running on port 80 + if ss -tulnp | grep ':80 ' >/dev/null; then + echo "Error: something is already running on port 80" >&2 + exit 1 + fi + + # check if something is running on port 443 + if ss -tulnp | grep ':443 ' >/dev/null; then + echo "Error: something is already running on port 443" >&2 + exit 1 + fi + + command_exists() { + command -v "$@" > /dev/null 2>&1 + } + + if ! command_exists docker; then + echo "Docker not installed" + exit + fi + + echo "Leaving existing docker swarm" + docker swarm leave --force 2>/dev/null + + get_ip() { + local ip="" + + ip=$(curl -4s --connect-timeout 5 https://ifconfig.io 2>/dev/null) + + if [ -z "$ip" ]; then + ip=$(curl -4s --connect-timeout 5 https://icanhazip.com 2>/dev/null) + fi + + if [ -z "$ip" ]; then + ip=$(curl -4s --connect-timeout 5 https://ipecho.net/plain 2>/dev/null) + fi + + if [ -z "$ip" ]; then + ip=$(curl -6s --connect-timeout 5 https://ifconfig.io 2>/dev/null) + + if [ -z "$ip" ]; then + ip=$(curl -6s --connect-timeout 5 https://icanhazip.com 2>/dev/null) + fi + + if [ -z "$ip" ]; then + ip=$(curl -6s --connect-timeout 5 https://ipecho.net/plain 2>/dev/null) + fi + fi + + if [ -z "$ip" ]; then + echo "Error: Could not determine server IP address automatically (neither IPv4 nor IPv6)." >&2 + echo "Please set the ADVERTISE_ADDR environment variable manually." >&2 + echo "Example: export ADVERTISE_ADDR=" >&2 + exit 1 + fi + + echo "$ip" + } + + get_private_ip() { + ip addr show | grep -E "inet (192\.168\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.)" | head -n1 | awk '{print $2}' | cut -d/ -f1 + } + + advertise_addr="${ADVERTISE_ADDR:-$(get_private_ip)}" + + if [ -z "$advertise_addr" ]; then + echo "ERROR: We couldn't find a private IP address." + echo "Please set the ADVERTISE_ADDR environment variable manually." + echo "Example: export ADVERTISE_ADDR=192.168.1.100" + exit 1 + fi + echo "Using advertise address: $advertise_addr" + + echo "Initializing swarm" + docker swarm init --advertise-addr $advertise_addr + if [ $? -ne 0 ]; then + echo "Error: Failed to initialize Docker Swarm" >&2 + exit 1 + fi + echo "Swarm initialized" + + echo "Initializing network" + docker network rm -f dokploy-network 2>/dev/null + docker network create --driver overlay --attachable dokploy-network + echo "Network created" + + mkdir -p /etc/dokploy + && chmod 777 /etc/dokploy + + docker service create \ + --name dokploy-postgres \ + --constraint 'node.role==manager' \ + --network dokploy-network \ + --env POSTGRES_USER=dokploy \ + --env POSTGRES_DB=dokploy \ + --env POSTGRES_PASSWORD={{ POSTGRES_PASSWORD }} \ + --mount type=volume,source=dokploy-postgres-database,target=/var/lib/postgresql/data \ + postgres:16 + + docker service create \ + --name dokploy-redis \ + --constraint 'node.role==manager' \ + --network dokploy-network \ + --mount type=volume,source=redis-data-volume,target=/data \ + redis:7 + + docker service create \ + --name dokploy \ + --replicas 1 \ + --network dokploy-network \ + --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \ + --mount type=bind,source=/etc/dokploy,target=/etc/dokploy \ + --mount type=volume,source=dokploy-docker-config,target=/root/.docker \ + --publish published=3000,target=3000,mode=host \ + --update-parallelism 1 \ + --update-order stop-first \ + --constraint 'node.role == manager' \ + -e ADVERTISE_ADDR=$advertise_addr \ + dokploy/dokploy:latest + + sleep 4 + + docker run -d \ + --name dokploy-traefik \ + --restart always \ + -v /etc/dokploy/traefik/traefik.yml:/etc/traefik/traefik.yml \ + -v /etc/dokploy/traefik/dynamic:/etc/dokploy/traefik/dynamic \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -p 80:80/tcp \ + -p 443:443/tcp \ + -p 443:443/udp \ + traefik:v3.1.2 + + docker network connect dokploy-network dokploy-traefik + + GREEN="\033[0;32m" + YELLOW="\033[1;33m" + BLUE="\033[0;34m" + NO_COLOR="\033[0m" + + format_ip_for_url() { + local ip="$1" + if echo "$ip" | grep -q ':'; then + # IPv6 + echo "[${ip}]" + else + # IPv4 + echo "${ip}" + fi + } + + public_ip="${ADVERTISE_ADDR:-$(get_ip)}" + formatted_addr=$(format_ip_for_url "$public_ip") + echo "" + printf "${GREEN}Congratulations, Dokploy is installed!${NO_COLOR}\n" + printf "${BLUE}Wait 15 seconds for the server to start${NO_COLOR}\n" + printf "${YELLOW}Please go to http://${formatted_addr}:3000${NO_COLOR}\n\n" + +update: + #!/usr/bin/env bash + echo "Updating Dokploy..." + + # Pull the latest image + docker pull dokploy/dokploy:latest + + # Update the service + docker service update --image dokploy/dokploy:latest dokploy + + echo "Dokploy has been updated to the latest version." + +uninstall: + #!/usr/bin/env bash + + if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" >&2 + exit 1 + fi + + echo "# Removing services" + docker service rm \ + dokploy \ + dokploy-traefik \ + dokploy-postgres \ + dokploy-redis + echo + + echo "# Removing volumes" + docker volume rm -f \ + dokploy-postgres-database \ + dokploy-docker-config \ + redis-data-volume + echo + + echo "# Removing networks" + docker network rm -f \ + dokploy-network + echo + + echo "# Removing /etc/dokploy" + rm -rf \ + /etc/dokploy