mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-28 08:49:42 +02:00
feat(scripts): free trusted HTTPS via sslip.io for public-IP remote i… (#460)
* feat(scripts): free trusted HTTPS via sslip.io for public-IP remote installs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: refactor setup scripts * chore: generate sdk * chore: fix messaging for setup_remote script * fix: fix ffmpeg download url * feat: centralise and simplify the url configuration * fix: force script run as sudo * fix: fix documentation --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3309face2c
commit
78427817a6
30 changed files with 838 additions and 392 deletions
|
|
@ -29,12 +29,15 @@ This directory now has a shared deployment model for OSS Docker installs. If you
|
|||
- `scripts/lib/setup_common.sh` is the shared deployment helper library. It is sourced by `setup_local.sh`, `setup_remote.sh`, `update_remote.sh`, `setup_custom_domain.sh`, `run_dograh_init.sh`, and repo-root `remote_up.sh`.
|
||||
- `setup_common.sh` must stay safe to source. It should not set shell options like `set -u` for callers.
|
||||
- `.env` is the single operator-owned source of truth for remote deployment settings. Remote/runtime config should derive from it, not the other way around.
|
||||
- Canonical remote keys in `.env`: `ENVIRONMENT`, `SERVER_IP`, `PUBLIC_HOST`, `PUBLIC_BASE_URL`, `BACKEND_API_ENDPOINT`, `MINIO_PUBLIC_ENDPOINT`, `TURN_HOST`, `TURN_SECRET`, `FASTAPI_WORKERS`, `OSS_JWT_SECRET`.
|
||||
- Canonical remote keys in `.env`: `ENVIRONMENT`, `SERVER_IP`, `PUBLIC_HOST`, `PUBLIC_BASE_URL`, `TURN_SECRET`, `FASTAPI_WORKERS`, `OSS_JWT_SECRET`. `PUBLIC_BASE_URL` (+ `PUBLIC_HOST`, and `SERVER_IP` for coturn's literal `external-ip`) is the single endpoint source of truth.
|
||||
- `BACKEND_API_ENDPOINT`, `MINIO_PUBLIC_ENDPOINT`, `TURN_HOST` are **derived in-app** from `PUBLIC_BASE_URL` / `PUBLIC_HOST` (`api/constants.py`) and are no longer written to a remote `.env`. `dograh_sync_remote_env_file` neither writes nor deletes them — new installs omit them, and a value an operator sets by hand is left untouched as an explicit override for a split deployment (separate object store / TURN host). `dograh_validate_remote_runtime_env` therefore no longer requires them or asserts they equal `PUBLIC_BASE_URL`.
|
||||
- `remote_up.sh` is the supported remote startup entrypoint. It runs preflight via `dograh_prepare_remote_install`, runs `docker compose config -q`, then starts the stack.
|
||||
- `docker-compose.yaml` uses a one-shot `dograh-init` service for profiles `remote` and `local-turn`.
|
||||
- `cloudflared` is gated behind a `tunnel` profile (no longer always-on; `api` no longer `depends_on` it). `remote_up.sh` adds `--profile tunnel` when `SERVER_IP` is a private/reserved address (`dograh_is_local_ipv4`) — i.e. the host has no public IP; public-IP installs run `--profile remote` only and start no tunnel. Local installs opt in with `--profile tunnel`. The backend mirrors this exactly: `api/utils/common.py:is_local_or_private_url` decides when `get_backend_endpoints()` resolves the tunnel URL at runtime, so deploy-side and runtime stay in sync (keep the two IP classifiers aligned, incl. CGNAT 100.64.0.0/10).
|
||||
- `cloudflared` picks a mode by token: with `CLOUDFLARE_TUNNEL_TOKEN` it runs a named tunnel (stable hostname — set `BACKEND_API_ENDPOINT` to it and point its Cloudflare-dashboard ingress at `http://api:8000`); without a token it runs a quick tunnel (ephemeral `*.trycloudflare.com`, discovered via the `:2000` metrics endpoint by `api/utils/tunnel.py`).
|
||||
- `dograh-init` executes `scripts/run_dograh_init.sh`, which renders nginx/coturn runtime config into named volumes consumed by `nginx` and `coturn`.
|
||||
- Remote nginx/coturn config is runtime-generated. Host-managed `nginx.conf` / `turnserver.conf` are legacy only; update flow may back them up and delete them, but current installs should not depend on them.
|
||||
- `setup_remote.sh` writes `.env`, downloads the deployment helper bundle, generates self-signed certs, validates the init-based config, and tells operators to start via `./remote_up.sh` or `./remote_up.sh --build`.
|
||||
- `setup_remote.sh` writes `.env`, downloads the deployment helper bundle, generates self-signed certs, validates the init-based config, and tells operators to start via `./remote_up.sh` or `./remote_up.sh --build`. It hard-requires root (a guard near the top exits non-root with a "re-run with sudo" message) because it provisions Docker, binds :80/:443, and installs a Let's Encrypt cert + system renewal hook. Cloud-init/user-data callers (e.g. `infrastructure/`) already run as root, so they pass; interactive callers must use `sudo`. Docs that invoke it (`docs/deployment/docker.mdx`, `docs/deployment/scaling.mdx`) and the hint printed by `setup_custom_domain.sh` all use `sudo`.
|
||||
- `update_remote.sh` is the migration/upgrade path for prebuilt remote installs. It refreshes `docker-compose.yaml`, `remote_up.sh`, `scripts/run_dograh_init.sh`, `scripts/lib/setup_common.sh`, and `deploy/templates/*`, backs up touched files, removes legacy host `nginx.conf` / `turnserver.conf`, and revalidates the init-based path.
|
||||
- `setup_custom_domain.sh` is certificate/domain glue only. It must not own nginx config. It updates canonical public URL keys in `.env`, copies Let's Encrypt certs into `certs/`, installs renewal hook, and restarts through `./remote_up.sh`.
|
||||
- `setup_local.{sh,ps1}` has an interactive `Enable coturn? [y/N]` prompt unless `ENABLE_COTURN` is preset. If coturn is enabled, it downloads the minimal helper bundle needed for `local-turn` (`setup_common.sh`, `run_dograh_init.sh`, templates) and relies on `dograh-init` to render coturn config.
|
||||
|
|
|
|||
|
|
@ -252,9 +252,11 @@ dograh_sync_remote_env_file() {
|
|||
dograh_set_env_key "$env_file" SERVER_IP "$server_ip"
|
||||
dograh_set_env_key "$env_file" PUBLIC_HOST "$public_host"
|
||||
dograh_set_env_key "$env_file" PUBLIC_BASE_URL "$public_base_url"
|
||||
dograh_set_env_key "$env_file" BACKEND_API_ENDPOINT "$public_base_url"
|
||||
dograh_set_env_key "$env_file" MINIO_PUBLIC_ENDPOINT "$public_base_url"
|
||||
dograh_set_env_key "$env_file" TURN_HOST "$public_host"
|
||||
|
||||
# BACKEND_API_ENDPOINT / MINIO_PUBLIC_ENDPOINT / TURN_HOST are derived in-app
|
||||
# from PUBLIC_BASE_URL / PUBLIC_HOST (see api/constants.py), so sync neither
|
||||
# writes nor removes them: new installs simply omit them, and any value an
|
||||
# operator set by hand is left untouched as an explicit override.
|
||||
}
|
||||
|
||||
dograh_validate_remote_runtime_env() {
|
||||
|
|
@ -262,14 +264,12 @@ dograh_validate_remote_runtime_env() {
|
|||
[[ -n "${TURN_SECRET:-}" ]] || dograh_fail "TURN_SECRET is missing"
|
||||
[[ -n "${PUBLIC_HOST:-}" ]] || dograh_fail "PUBLIC_HOST is missing"
|
||||
[[ -n "${PUBLIC_BASE_URL:-}" ]] || dograh_fail "PUBLIC_BASE_URL is missing"
|
||||
[[ -n "${BACKEND_API_ENDPOINT:-}" ]] || dograh_fail "BACKEND_API_ENDPOINT is missing"
|
||||
[[ -n "${MINIO_PUBLIC_ENDPOINT:-}" ]] || dograh_fail "MINIO_PUBLIC_ENDPOINT is missing"
|
||||
[[ -n "${TURN_HOST:-}" ]] || dograh_fail "TURN_HOST is missing"
|
||||
dograh_is_ipv4 "${SERVER_IP:-}" || dograh_fail "SERVER_IP must be a valid IPv4 address"
|
||||
[[ "${PUBLIC_BASE_URL}" =~ ^https?:// ]] || dograh_fail "PUBLIC_BASE_URL must include http:// or https://"
|
||||
[[ "${BACKEND_API_ENDPOINT}" == "${PUBLIC_BASE_URL}" ]] || dograh_fail "BACKEND_API_ENDPOINT must match PUBLIC_BASE_URL"
|
||||
[[ "${MINIO_PUBLIC_ENDPOINT}" == "${PUBLIC_BASE_URL}" ]] || dograh_fail "MINIO_PUBLIC_ENDPOINT must match PUBLIC_BASE_URL"
|
||||
[[ "${TURN_HOST}" == "${PUBLIC_HOST}" ]] || dograh_fail "TURN_HOST must match PUBLIC_HOST"
|
||||
# BACKEND_API_ENDPOINT / MINIO_PUBLIC_ENDPOINT / TURN_HOST are derived in-app
|
||||
# from PUBLIC_BASE_URL / PUBLIC_HOST (see api/constants.py), so they are not
|
||||
# required here. When an operator sets them explicitly (split deployment),
|
||||
# their value is honored as-is — no equality check.
|
||||
}
|
||||
|
||||
dograh_uses_init_compose_layout() {
|
||||
|
|
@ -401,6 +401,59 @@ dograh_preflight_remote_init_render() {
|
|||
rm -rf "$tmp_root"
|
||||
}
|
||||
|
||||
# Reconcile the running Postgres role password with POSTGRES_PASSWORD in .env.
|
||||
#
|
||||
# POSTGRES_PASSWORD only takes effect when the postgres data volume is first
|
||||
# initialized. If the volume was created before .env had a generated password
|
||||
# (e.g. an early start used the compose fallback `:-postgres`), or the password
|
||||
# was later rotated, the role keeps its old password while the API connects with
|
||||
# the .env value over TCP (pg_hba `scram-sha-256`) and dies with "password
|
||||
# authentication failed for user postgres". start_docker.sh handles this for the
|
||||
# OSS quickstart; the remote path (remote_up.sh) needs the same reconciliation.
|
||||
#
|
||||
# Bring postgres up on its own, then ALTER the role over the trusted local
|
||||
# socket (pg_hba trusts `local`, so this works even when the password is
|
||||
# currently mismatched). Idempotent: on a fresh volume it just re-sets the same
|
||||
# value. Survives the later `--force-recreate` because the password lives in the
|
||||
# data volume, not the container.
|
||||
dograh_sync_postgres_password() {
|
||||
local project_dir=$1
|
||||
shift
|
||||
local compose=("$@")
|
||||
local env_file="$project_dir/.env"
|
||||
local password=""
|
||||
local ready=""
|
||||
local i
|
||||
|
||||
[[ ${#compose[@]} -gt 0 ]] || compose=(docker compose)
|
||||
|
||||
if [[ -f "$env_file" ]]; then
|
||||
password="$(awk -F= '/^POSTGRES_PASSWORD=/{sub(/^POSTGRES_PASSWORD=/, ""); print; exit}' "$env_file")"
|
||||
fi
|
||||
|
||||
# No explicit password: the compose fallback (`:-postgres`) governs both the
|
||||
# DB init and the API's DATABASE_URL, so the two already agree — nothing to do.
|
||||
[[ -n "$password" ]] || return 0
|
||||
|
||||
dograh_info "Syncing Postgres password from .env..."
|
||||
( cd "$project_dir" && "${compose[@]}" up -d postgres ) >/dev/null
|
||||
|
||||
for ((i = 0; i < 30; i++)); do
|
||||
if ( cd "$project_dir" && "${compose[@]}" exec -T postgres pg_isready -U postgres ) >/dev/null 2>&1; then
|
||||
ready=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
[[ -n "$ready" ]] || dograh_fail "Postgres did not become ready while syncing POSTGRES_PASSWORD."
|
||||
|
||||
printf '%s\n' "ALTER USER postgres WITH PASSWORD :'pw';" \
|
||||
| ( cd "$project_dir" && "${compose[@]}" exec -T postgres \
|
||||
psql -U postgres -d postgres -v ON_ERROR_STOP=1 -v "pw=$password" ) >/dev/null \
|
||||
|| dograh_fail "Failed to sync Postgres password from .env."
|
||||
dograh_success "✓ Postgres password synced with .env"
|
||||
}
|
||||
|
||||
dograh_prepare_remote_install() {
|
||||
local project_dir=${1:-$(dograh_project_dir)}
|
||||
local env_file="$project_dir/.env"
|
||||
|
|
@ -410,6 +463,101 @@ dograh_prepare_remote_install() {
|
|||
dograh_preflight_remote_init_render "$project_dir"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# TLS certificate helpers (self-signed bootstrap + Let's Encrypt via webroot)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Map an IPv4 address to a public sslip.io / nip.io hostname, e.g.
|
||||
# 203.0.113.10 -> 203-0-113-10.sslip.io. The hostname resolves back to the
|
||||
# embedded IP from any public resolver, so Let's Encrypt can validate it over
|
||||
# the HTTP-01 challenge without the operator owning a domain. Public IPs only:
|
||||
# Let's Encrypt refuses to validate private/reserved addresses.
|
||||
dograh_sslip_host_from_ip() {
|
||||
local ip=$1
|
||||
local suffix=${2:-sslip.io}
|
||||
|
||||
dograh_is_ipv4 "$ip" || dograh_fail "dograh_sslip_host_from_ip: '$ip' is not an IPv4 address"
|
||||
printf '%s.%s\n' "${ip//./-}" "$suffix"
|
||||
}
|
||||
|
||||
# Install certbot via the host package manager if it is not already present.
|
||||
# Returns non-zero (instead of exiting) when no supported package manager is
|
||||
# found or the install fails, so callers can fall back to a self-signed cert.
|
||||
dograh_install_certbot() {
|
||||
if command -v certbot >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
dograh_info "Installing Certbot..."
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get update -qq && apt-get install -y -qq certbot
|
||||
elif command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y -q certbot
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
yum install -y -q certbot
|
||||
else
|
||||
dograh_warn "Could not detect a package manager (apt/dnf/yum) to install certbot."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Obtain (or renew) a Let's Encrypt certificate for $host using the webroot
|
||||
# challenge served by the running nginx container out of <project>/certs, then
|
||||
# copy the issued cert to certs/local.{crt,key} (the files nginx reads). This
|
||||
# needs nginx already running and serving /.well-known/acme-challenge/ on :80.
|
||||
# Returns non-zero on failure so callers can keep the self-signed cert.
|
||||
dograh_issue_letsencrypt_webroot() {
|
||||
local project_dir=$1
|
||||
local host=$2
|
||||
local email=${3:-}
|
||||
local webroot="$project_dir/certs"
|
||||
local live_dir="/etc/letsencrypt/live/$host"
|
||||
local -a email_args
|
||||
|
||||
if [[ -n "$email" ]]; then
|
||||
email_args=(--email "$email")
|
||||
else
|
||||
email_args=(--register-unsafely-without-email)
|
||||
fi
|
||||
|
||||
mkdir -p "$webroot/.well-known/acme-challenge"
|
||||
|
||||
certbot certonly --webroot -w "$webroot" \
|
||||
--non-interactive --agree-tos --keep-until-expiring \
|
||||
"${email_args[@]}" \
|
||||
-d "$host" || return 1
|
||||
|
||||
[[ -f "$live_dir/fullchain.pem" && -f "$live_dir/privkey.pem" ]] || return 1
|
||||
|
||||
cp "$live_dir/fullchain.pem" "$webroot/local.crt"
|
||||
cp "$live_dir/privkey.pem" "$webroot/local.key"
|
||||
chmod 644 "$webroot/local.crt" "$webroot/local.key"
|
||||
}
|
||||
|
||||
# Install a certbot deploy hook so renewed certificates are copied into
|
||||
# <project>/certs and nginx is restarted to load them. Renewal itself is driven
|
||||
# by certbot's packaged systemd timer / cron; webroot renewals need no downtime
|
||||
# because the running nginx serves the challenge.
|
||||
dograh_install_cert_renewal_hook() {
|
||||
local project_dir=$1
|
||||
local host=$2
|
||||
local hook_dir="/etc/letsencrypt/renewal-hooks/deploy"
|
||||
local hook_path="$hook_dir/dograh-reload.sh"
|
||||
|
||||
mkdir -p "$hook_dir"
|
||||
|
||||
cat > "$hook_path" << HOOK_EOF
|
||||
#!/bin/bash
|
||||
cp /etc/letsencrypt/live/$host/fullchain.pem $project_dir/certs/local.crt
|
||||
cp /etc/letsencrypt/live/$host/privkey.pem $project_dir/certs/local.key
|
||||
chmod 644 $project_dir/certs/local.crt $project_dir/certs/local.key
|
||||
|
||||
cd $project_dir
|
||||
docker compose --profile remote restart nginx 2>/dev/null || true
|
||||
HOOK_EOF
|
||||
chmod +x "$hook_path"
|
||||
}
|
||||
|
||||
dograh_download_bundle_file_for_ref() {
|
||||
local destination=$1
|
||||
local remote_path=$2
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ if [[ ! -d "dograh" ]]; then
|
|||
echo -e "${RED}Error: 'dograh' directory not found.${NC}"
|
||||
echo -e "${YELLOW}Please run this script from the directory containing your Dograh installation.${NC}"
|
||||
echo -e "${YELLOW}If you haven't set up Dograh yet, run the remote setup first:${NC}"
|
||||
echo -e "${BLUE} curl -o setup_remote.sh https://raw.githubusercontent.com/dograh-hq/dograh/main/scripts/setup_remote.sh && chmod +x setup_remote.sh && ./setup_remote.sh${NC}"
|
||||
echo -e "${BLUE} curl -o setup_remote.sh https://raw.githubusercontent.com/dograh-hq/dograh/main/scripts/setup_remote.sh && chmod +x setup_remote.sh && sudo ./setup_remote.sh${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ echo -e " Domain: ${BLUE}$DOMAIN_NAME${NC}"
|
|||
echo -e " Email: ${BLUE}$EMAIL_ADDRESS${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e "${BLUE}[1/7] Verifying DNS configuration...${NC}"
|
||||
echo -e "${BLUE}[1/6] Verifying DNS configuration...${NC}"
|
||||
SERVER_IP="$(curl -s ifconfig.me || curl -s icanhazip.com || echo "")"
|
||||
RESOLVED_IP="$(dig +short "$DOMAIN_NAME" | tail -1)"
|
||||
|
||||
|
|
@ -84,22 +84,14 @@ else
|
|||
echo -e "${GREEN}✓ DNS is correctly configured (${RESOLVED_IP})${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[2/7] Installing Certbot...${NC}"
|
||||
if command -v apt-get &> /dev/null; then
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq certbot
|
||||
elif command -v yum &> /dev/null; then
|
||||
yum install -y -q certbot
|
||||
elif command -v dnf &> /dev/null; then
|
||||
dnf install -y -q certbot
|
||||
else
|
||||
dograh_fail "Could not detect package manager. Please install certbot manually."
|
||||
fi
|
||||
echo -e "${BLUE}[2/6] Installing Certbot...${NC}"
|
||||
dograh_install_certbot || dograh_fail "Could not install certbot. Please install it manually and re-run."
|
||||
echo -e "${GREEN}✓ Certbot installed${NC}"
|
||||
|
||||
echo -e "${BLUE}[3/7] Stopping Dograh services...${NC}"
|
||||
echo -e "${BLUE}[3/6] Pointing .env at $DOMAIN_NAME and starting services...${NC}"
|
||||
cd dograh
|
||||
DOGRAH_DEPLOY_PROJECT_DIR="$(pwd)"
|
||||
DOGRAH_PATH="$(pwd)"
|
||||
|
||||
if [[ ! -f remote_up.sh || ! -f scripts/lib/setup_common.sh ]]; then
|
||||
dograh_download_remote_support_bundle "$(pwd)" "main"
|
||||
|
|
@ -107,113 +99,74 @@ fi
|
|||
|
||||
dograh_require_init_compose_layout "$(pwd)"
|
||||
|
||||
if docker compose --profile remote ps --quiet 2>/dev/null | grep -q .; then
|
||||
docker compose --profile remote down
|
||||
echo -e "${GREEN}✓ Dograh services stopped${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No running services found${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[4/7] Generating Let's Encrypt SSL certificate...${NC}"
|
||||
CERTBOT_OUTPUT=$(certbot certonly --standalone \
|
||||
--non-interactive \
|
||||
--agree-tos \
|
||||
--email "$EMAIL_ADDRESS" \
|
||||
-d "$DOMAIN_NAME" 2>&1) || {
|
||||
echo -e "${RED}✗ Certificate generation failed${NC}"
|
||||
echo ""
|
||||
|
||||
if echo "$CERTBOT_OUTPUT" | grep -qi "timeout\|firewall\|connection"; then
|
||||
echo -e "${YELLOW}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${YELLOW} Port 80 appears to be blocked by a firewall.${NC}"
|
||||
echo -e "${YELLOW}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e "Let's Encrypt needs to connect to port 80 to verify domain ownership."
|
||||
echo ""
|
||||
elif echo "$CERTBOT_OUTPUT" | grep -qi "too many\|rate.limit"; then
|
||||
echo -e "${YELLOW}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${YELLOW} Let's Encrypt rate limit reached.${NC}"
|
||||
echo -e "${YELLOW}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo "You've requested too many certificates recently."
|
||||
echo "Please wait before trying again (usually 1 hour)."
|
||||
echo ""
|
||||
elif echo "$CERTBOT_OUTPUT" | grep -qi "dns\|resolve\|NXDOMAIN"; then
|
||||
echo -e "${YELLOW}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${YELLOW} DNS resolution failed.${NC}"
|
||||
echo -e "${YELLOW}═══════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo "The domain '$DOMAIN_NAME' does not resolve to this server."
|
||||
echo "Please verify your DNS A record is correctly configured."
|
||||
echo ""
|
||||
else
|
||||
echo -e "${YELLOW}Certbot output:${NC}"
|
||||
echo "$CERTBOT_OUTPUT"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo -e "After fixing the issue, re-run this script:"
|
||||
echo -e " ${BLUE}sudo ./setup_custom_domain.sh${NC}"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
echo -e "${GREEN}✓ SSL certificate generated${NC}"
|
||||
|
||||
CERT_PATH="/etc/letsencrypt/live/$DOMAIN_NAME"
|
||||
echo ""
|
||||
echo -e "${BLUE}Certificate location:${NC}"
|
||||
echo -e " ${CERT_PATH}/"
|
||||
[[ -f "$CERT_PATH/fullchain.pem" ]] && echo -e " ${GREEN}✓${NC} fullchain.pem exists" || echo -e " ${RED}✗${NC} fullchain.pem NOT FOUND"
|
||||
[[ -f "$CERT_PATH/privkey.pem" ]] && echo -e " ${GREEN}✓${NC} privkey.pem exists" || echo -e " ${RED}✗${NC} privkey.pem NOT FOUND"
|
||||
echo ""
|
||||
|
||||
mkdir -p certs
|
||||
cp "$CERT_PATH/fullchain.pem" certs/local.crt
|
||||
cp "$CERT_PATH/privkey.pem" certs/local.key
|
||||
chmod 644 certs/local.crt certs/local.key
|
||||
echo -e "${GREEN}✓${NC} Certificates copied to certs/ directory"
|
||||
echo ""
|
||||
|
||||
echo -e "${BLUE}[5/7] Updating canonical remote settings and validating init-based config...${NC}"
|
||||
dograh_load_env_file .env
|
||||
|
||||
if [[ -z "${SERVER_IP:-}" ]]; then
|
||||
SERVER_IP="$(dograh_infer_server_ip "$(pwd)" || true)"
|
||||
fi
|
||||
|
||||
[[ -n "${SERVER_IP:-}" ]] || dograh_fail "Could not determine SERVER_IP from the existing install"
|
||||
|
||||
dograh_set_env_key .env SERVER_IP "$SERVER_IP"
|
||||
dograh_set_env_key .env PUBLIC_HOST "$DOMAIN_NAME"
|
||||
dograh_set_env_key .env PUBLIC_BASE_URL "https://$DOMAIN_NAME"
|
||||
dograh_delete_env_key .env BACKEND_URL
|
||||
# Switching domains is an explicit repoint of the whole deployment. Drop any
|
||||
# legacy per-subsystem endpoint keys an older install pinned to the previous host
|
||||
# so they re-derive from the new PUBLIC_BASE_URL / PUBLIC_HOST (see api/constants.py).
|
||||
# No-op on current installs, which don't write these keys.
|
||||
dograh_delete_env_key .env BACKEND_API_ENDPOINT
|
||||
dograh_delete_env_key .env MINIO_PUBLIC_ENDPOINT
|
||||
dograh_delete_env_key .env TURN_HOST
|
||||
dograh_prepare_remote_install "$(pwd)"
|
||||
echo -e "${GREEN}✓ .env synchronized and init-based config validated${NC}"
|
||||
|
||||
echo -e "${BLUE}[6/7] Setting up automatic certificate renewal...${NC}"
|
||||
DOGRAH_PATH="$(pwd)"
|
||||
# Bring the stack up (recreating it) so dograh-init re-renders nginx with the
|
||||
# domain server_name and the ACME challenge location, served with the existing
|
||||
# certificate. certbot --webroot then validates against the running nginx:
|
||||
# no downtime, and (unlike --standalone) renewal keeps working later while
|
||||
# nginx holds port 80.
|
||||
./remote_up.sh
|
||||
|
||||
cat > /etc/letsencrypt/renewal-hooks/deploy/dograh-reload.sh << HOOK_EOF
|
||||
#!/bin/bash
|
||||
cp /etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem $DOGRAH_PATH/certs/local.crt
|
||||
cp /etc/letsencrypt/live/$DOMAIN_NAME/privkey.pem $DOGRAH_PATH/certs/local.key
|
||||
chmod 644 $DOGRAH_PATH/certs/local.crt $DOGRAH_PATH/certs/local.key
|
||||
echo -e "${BLUE}Waiting for nginx to answer on port 80...${NC}"
|
||||
nginx_ready=0
|
||||
for ((i=1; i<=60; i++)); do
|
||||
if curl -s -o /dev/null --max-time 3 "http://127.0.0.1/"; then
|
||||
nginx_ready=1
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
[[ "$nginx_ready" == "1" ]] || dograh_fail "nginx did not come up on port 80; cannot run the ACME challenge."
|
||||
echo -e "${GREEN}✓ Services running and serving the ACME challenge${NC}"
|
||||
|
||||
cd $DOGRAH_PATH
|
||||
docker compose --profile remote restart nginx 2>/dev/null || true
|
||||
HOOK_EOF
|
||||
chmod +x /etc/letsencrypt/renewal-hooks/deploy/dograh-reload.sh
|
||||
echo -e "${BLUE}[4/6] Obtaining Let's Encrypt certificate for $DOMAIN_NAME...${NC}"
|
||||
if ! dograh_issue_letsencrypt_webroot "$(pwd)" "$DOMAIN_NAME" "$EMAIL_ADDRESS"; then
|
||||
echo -e "${RED}✗ Certificate issuance failed${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Common causes:${NC}"
|
||||
echo " - Port 80 not reachable from the internet (open it in your firewall)"
|
||||
echo " - DNS A record for $DOMAIN_NAME does not point to this server yet"
|
||||
echo " - Let's Encrypt rate limit reached (wait, then retry)"
|
||||
echo " - Upgrading an older install: run ./update_remote.sh first to refresh the"
|
||||
echo " nginx template so it serves the ACME challenge, then re-run this script"
|
||||
echo ""
|
||||
echo -e "The stack is still running with the previous certificate."
|
||||
echo -e "After fixing the issue, re-run: ${BLUE}sudo ./setup_custom_domain.sh${NC}"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Certificate issued and copied to certs/${NC}"
|
||||
|
||||
echo -e "${BLUE}[5/6] Loading the new certificate (restarting nginx)...${NC}"
|
||||
docker compose --profile remote restart nginx >/dev/null 2>&1 || true
|
||||
echo -e "${GREEN}✓ nginx restarted${NC}"
|
||||
|
||||
echo -e "${BLUE}[6/6] Configuring automatic certificate renewal...${NC}"
|
||||
dograh_install_cert_renewal_hook "$(pwd)" "$DOMAIN_NAME"
|
||||
if certbot renew --dry-run --quiet; then
|
||||
echo -e "${GREEN}✓ Auto-renewal configured and tested${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Auto-renewal test had issues, but certificates are installed${NC}"
|
||||
echo -e "${YELLOW}⚠ Auto-renewal dry-run had issues, but the certificate is installed${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}[7/7] Starting Dograh services through validated startup wrapper...${NC}"
|
||||
./remote_up.sh
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Custom Domain Setup Complete! ║${NC}"
|
||||
|
|
|
|||
|
|
@ -307,13 +307,16 @@ Write-Host ''
|
|||
if ($UseCoturn) {
|
||||
Write-Warn 'To start Dograh with TURN, run:'
|
||||
Write-Host ''
|
||||
Write-Host ' docker compose --profile local-turn up --pull always' -ForegroundColor Blue
|
||||
Write-Host ' docker compose --profile local-turn --profile tunnel up --pull always' -ForegroundColor Blue
|
||||
} else {
|
||||
Write-Warn 'To start Dograh, run:'
|
||||
Write-Host ''
|
||||
Write-Host ' docker compose up --pull always' -ForegroundColor Blue
|
||||
Write-Host ' docker compose --profile tunnel up --pull always' -ForegroundColor Blue
|
||||
}
|
||||
Write-Host ''
|
||||
Write-Host 'This starts a Cloudflare quick tunnel so inbound telephony webhooks can' -ForegroundColor Yellow
|
||||
Write-Host 'reach your local API over a temporary public URL.' -ForegroundColor Yellow
|
||||
Write-Host ''
|
||||
Write-Warn 'Your application will be available at:'
|
||||
Write-Host ''
|
||||
Write-Host ' http://localhost:3010' -ForegroundColor Blue
|
||||
|
|
|
|||
|
|
@ -211,13 +211,16 @@ echo ""
|
|||
if [[ "${ENABLE_COTURN:-false}" == "true" ]]; then
|
||||
echo -e "${YELLOW}To start Dograh with TURN, run:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}docker compose --profile local-turn up --pull always${NC}"
|
||||
echo -e " ${BLUE}docker compose --profile local-turn --profile tunnel up --pull always${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}To start Dograh, run:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}docker compose up --pull always${NC}"
|
||||
echo -e " ${BLUE}docker compose --profile tunnel up --pull always${NC}"
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${YELLOW}This starts a Cloudflare quick tunnel so inbound telephony webhooks can${NC}"
|
||||
echo -e "${YELLOW}reach your local API over a temporary public URL.${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Your application will be available at:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}http://localhost:3010${NC}"
|
||||
|
|
|
|||
|
|
@ -35,9 +35,17 @@ echo "║ Automated HTTPS deployment with TURN server ║"
|
|||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
|
||||
# Get the public IP address (skip prompt if SERVER_IP is already set)
|
||||
# This setup must run as root: it provisions Docker, binds privileged ports
|
||||
# 80/443, and (for public IPs) installs a Let's Encrypt certificate plus a
|
||||
# system renewal hook under /etc/letsencrypt — all of which require root. Stop
|
||||
# early with clear guidance rather than getting halfway and degrading the install.
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
dograh_fail "setup_remote.sh must be run as root.\nRe-run with sudo:\n sudo ./setup_remote.sh"
|
||||
fi
|
||||
|
||||
# Get the server IP address (skip prompt if SERVER_IP is already set)
|
||||
if [[ -z "${SERVER_IP:-}" ]]; then
|
||||
echo -e "${YELLOW}Enter your server's public IP address:${NC}"
|
||||
echo -e "${YELLOW}Enter your server's IP address:${NC}"
|
||||
read -p "> " SERVER_IP
|
||||
fi
|
||||
|
||||
|
|
@ -49,6 +57,61 @@ if ! dograh_is_ipv4 "$SERVER_IP"; then
|
|||
dograh_fail "Invalid IP address format"
|
||||
fi
|
||||
|
||||
# Certificate strategy. CERT_MODE selects how HTTPS is secured:
|
||||
# auto - public IP + root + docker -> sslip (trusted); otherwise self-signed
|
||||
# sslip - free trusted Let's Encrypt cert via <ip>.sslip.io (public IP only)
|
||||
# self-signed - generate a self-signed cert (browser shows a warning)
|
||||
# Reserved for future private-network paths (not implemented yet):
|
||||
# letsencrypt-dns, cloudflare-tunnel, external
|
||||
CERT_MODE="${CERT_MODE:-auto}"
|
||||
ACME_DOMAIN_SUFFIX="${ACME_DOMAIN_SUFFIX:-sslip.io}"
|
||||
LETSENCRYPT_EMAIL="${LETSENCRYPT_EMAIL:-}"
|
||||
|
||||
if [[ "$CERT_MODE" == "auto" ]]; then
|
||||
if dograh_is_local_ipv4 "$SERVER_IP"; then
|
||||
CERT_MODE="self-signed"
|
||||
dograh_warn "$SERVER_IP is a private IP — using a self-signed certificate."
|
||||
dograh_warn "For a trusted cert, deploy on a public IP or a domain you own"
|
||||
dograh_warn "(https://docs.dograh.com/deployment/custom-domain)."
|
||||
elif ! command -v docker >/dev/null 2>&1; then
|
||||
CERT_MODE="self-signed"
|
||||
dograh_warn "Docker not found — skipping automatic Let's Encrypt setup and using a self-signed cert."
|
||||
else
|
||||
CERT_MODE="sslip"
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$CERT_MODE" in
|
||||
self-signed) ;;
|
||||
sslip)
|
||||
if dograh_is_local_ipv4 "$SERVER_IP"; then
|
||||
dograh_fail "CERT_MODE=sslip needs a public IP; $SERVER_IP is private/reserved."
|
||||
fi
|
||||
command -v docker >/dev/null 2>&1 || dograh_fail "CERT_MODE=sslip needs Docker to serve the ACME challenge."
|
||||
;;
|
||||
letsencrypt-dns|cloudflare-tunnel|external)
|
||||
dograh_fail "CERT_MODE=$CERT_MODE is reserved but not implemented yet. Use 'sslip' (public IP) or 'self-signed'."
|
||||
;;
|
||||
*)
|
||||
dograh_fail "Unknown CERT_MODE '$CERT_MODE' (expected: auto, sslip, self-signed)."
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$CERT_MODE" == "sslip" ]]; then
|
||||
PUBLIC_HOST_VALUE="$(dograh_sslip_host_from_ip "$SERVER_IP" "$ACME_DOMAIN_SUFFIX")"
|
||||
CERT_DESC="Let's Encrypt via $ACME_DOMAIN_SUFFIX (trusted)"
|
||||
else
|
||||
PUBLIC_HOST_VALUE="$SERVER_IP"
|
||||
CERT_DESC="self-signed (browser warning)"
|
||||
fi
|
||||
CERT_RESULT="$CERT_MODE"
|
||||
|
||||
if [[ "$CERT_MODE" == "sslip" && -z "$LETSENCRYPT_EMAIL" && -t 0 ]]; then
|
||||
echo ""
|
||||
echo -e "${YELLOW}Email for Let's Encrypt expiry notices (optional, press Enter to skip):${NC}"
|
||||
read -p "> " LETSENCRYPT_EMAIL
|
||||
fi
|
||||
|
||||
FORCE_TURN_RELAY="${FORCE_TURN_RELAY:-false}"
|
||||
|
||||
# Get the TURN secret (skip prompt if TURN_SECRET is already set)
|
||||
|
|
@ -185,6 +248,8 @@ fi
|
|||
echo ""
|
||||
echo -e "${GREEN}Configuration:${NC}"
|
||||
echo -e " Server IP: ${BLUE}$SERVER_IP${NC}"
|
||||
echo -e " Public host: ${BLUE}$PUBLIC_HOST_VALUE${NC}"
|
||||
echo -e " Certificate: ${BLUE}$CERT_DESC${NC}"
|
||||
echo -e " TURN Secret: ${BLUE}********${NC}"
|
||||
echo -e " Deploy mode: ${BLUE}$DEPLOY_MODE${NC}"
|
||||
echo -e " Force TURN relay: ${BLUE}$FORCE_TURN_RELAY${NC}"
|
||||
|
|
@ -240,7 +305,7 @@ openssl req -x509 -nodes -newkey rsa:2048 \\
|
|||
-keyout certs/local.key \\
|
||||
-out certs/local.crt \\
|
||||
-days 365 \\
|
||||
-subj "/CN=$SERVER_IP"
|
||||
-subj "/CN=$PUBLIC_HOST_VALUE"
|
||||
CERT_EOF
|
||||
chmod +x generate_certificate.sh
|
||||
echo -e "${GREEN}✓ generate_certificate.sh created${NC}"
|
||||
|
|
@ -260,19 +325,16 @@ cat > .env << ENV_EOF
|
|||
# Remote deployments run with production signaling and HTTPS defaults
|
||||
ENVIRONMENT=production
|
||||
|
||||
# Canonical public host/base URL for this install.
|
||||
# Canonical public host/base URL for this install. SERVER_IP stays the raw IP
|
||||
# (coturn external-ip and validation need it); PUBLIC_HOST is the sslip.io
|
||||
# hostname when using a trusted cert, otherwise the IP. BACKEND_API_ENDPOINT,
|
||||
# MINIO_PUBLIC_ENDPOINT and TURN_HOST are derived from these by the API
|
||||
# (see api/constants.py) — set them here only to override for a split deployment.
|
||||
SERVER_IP=$SERVER_IP
|
||||
PUBLIC_HOST=$SERVER_IP
|
||||
PUBLIC_BASE_URL=https://$SERVER_IP
|
||||
|
||||
# Backend API endpoint (public URL the backend uses to build webhook/embed links)
|
||||
BACKEND_API_ENDPOINT=https://$SERVER_IP
|
||||
|
||||
# Public URL browsers use to fetch objects from MinIO (proxied by nginx)
|
||||
MINIO_PUBLIC_ENDPOINT=https://$SERVER_IP
|
||||
PUBLIC_HOST=$PUBLIC_HOST_VALUE
|
||||
PUBLIC_BASE_URL=https://$PUBLIC_HOST_VALUE
|
||||
|
||||
# TURN Server Configuration (time-limited credentials via TURN REST API)
|
||||
TURN_HOST=$SERVER_IP
|
||||
TURN_SECRET=$TURN_SECRET
|
||||
# Relay-only ICE candidates for explicit TURN diagnostics
|
||||
FORCE_TURN_RELAY=$FORCE_TURN_RELAY
|
||||
|
|
@ -332,6 +394,46 @@ OVERRIDE_EOF
|
|||
echo -e "${GREEN}✓ docker-compose.override.yaml created${NC}"
|
||||
fi
|
||||
|
||||
if [[ "$CERT_MODE" == "sslip" ]]; then
|
||||
echo ""
|
||||
echo -e "${BLUE}Starting Dograh and requesting a trusted certificate for ${PUBLIC_HOST_VALUE}...${NC}"
|
||||
|
||||
if [[ "$DEPLOY_MODE" == "build" ]]; then
|
||||
./remote_up.sh --build
|
||||
else
|
||||
./remote_up.sh
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Waiting for nginx to answer on port 80...${NC}"
|
||||
nginx_ready=0
|
||||
for ((i=1; i<=60; i++)); do
|
||||
if curl -s -o /dev/null --max-time 3 "http://127.0.0.1/"; then
|
||||
nginx_ready=1
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [[ "$nginx_ready" != "1" ]]; then
|
||||
CERT_RESULT="self-signed"
|
||||
dograh_warn "nginx did not become reachable on port 80 — skipping Let's Encrypt for now."
|
||||
dograh_warn "The stack is running with the bootstrap self-signed certificate."
|
||||
elif dograh_install_certbot && dograh_issue_letsencrypt_webroot "$(pwd)" "$PUBLIC_HOST_VALUE" "$LETSENCRYPT_EMAIL"; then
|
||||
docker compose --profile remote restart nginx >/dev/null 2>&1 || true
|
||||
dograh_install_cert_renewal_hook "$(pwd)" "$PUBLIC_HOST_VALUE"
|
||||
CERT_RESULT="sslip"
|
||||
dograh_success "✓ Trusted Let's Encrypt certificate installed; auto-renewal configured"
|
||||
else
|
||||
CERT_RESULT="self-signed"
|
||||
echo ""
|
||||
dograh_warn "Let's Encrypt issuance failed — the stack is running with the self-signed certificate."
|
||||
dograh_warn "Common causes and fixes:"
|
||||
dograh_warn " - Port 80 not reachable from the internet: open it in your firewall/security group"
|
||||
dograh_warn " - Rate limited on ${ACME_DOMAIN_SUFFIX}: re-run with ACME_DOMAIN_SUFFIX=nip.io"
|
||||
dograh_warn " - Then retry: sudo certbot certonly --webroot -w \"$(pwd)/certs\" -d ${PUBLIC_HOST_VALUE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║ Setup Complete! ║${NC}"
|
||||
|
|
@ -350,25 +452,42 @@ echo " - certs/local.crt"
|
|||
echo " - certs/local.key"
|
||||
echo " - .env"
|
||||
echo ""
|
||||
echo -e "${YELLOW}To start Dograh, run:${NC}"
|
||||
echo ""
|
||||
if [[ "$DEPLOY_MODE" != "build" || "${REPO_SOURCE:-}" != "existing" ]]; then
|
||||
echo -e " ${BLUE}cd $(pwd)${NC}"
|
||||
fi
|
||||
if [[ "$DEPLOY_MODE" == "build" ]]; then
|
||||
echo -e " ${BLUE}./remote_up.sh --build${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}A docker-compose.override.yaml has been created alongside${NC}"
|
||||
echo -e "${YELLOW}docker-compose.yaml. Compose auto-loads it, so no -f flag is${NC}"
|
||||
echo -e "${YELLOW}needed — it swaps the prebuilt images for local builds.${NC}"
|
||||
if [[ "$CERT_MODE" == "sslip" ]]; then
|
||||
if [[ "$CERT_RESULT" == "sslip" ]]; then
|
||||
echo -e "${GREEN}Dograh is running with a trusted certificate at:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}https://$PUBLIC_HOST_VALUE${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}No browser warning — the certificate renews automatically before expiry.${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}Dograh is running (with a temporary self-signed certificate) at:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}https://$PUBLIC_HOST_VALUE${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Let's Encrypt issuance did not complete (see the message above). Your${NC}"
|
||||
echo -e "${YELLOW}browser will warn until a trusted certificate is issued.${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e " ${BLUE}./remote_up.sh${NC}"
|
||||
echo -e "${YELLOW}To start Dograh, run:${NC}"
|
||||
echo ""
|
||||
if [[ "$DEPLOY_MODE" != "build" || "${REPO_SOURCE:-}" != "existing" ]]; then
|
||||
echo -e " ${BLUE}cd $(pwd)${NC}"
|
||||
fi
|
||||
if [[ "$DEPLOY_MODE" == "build" ]]; then
|
||||
echo -e " ${BLUE}./remote_up.sh --build${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}A docker-compose.override.yaml has been created alongside${NC}"
|
||||
echo -e "${YELLOW}docker-compose.yaml. Compose auto-loads it, so no -f flag is${NC}"
|
||||
echo -e "${YELLOW}needed — it swaps the prebuilt images for local builds.${NC}"
|
||||
else
|
||||
echo -e " ${BLUE}./remote_up.sh${NC}"
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${YELLOW}Your application will be available at:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}https://$PUBLIC_HOST_VALUE${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Note:${NC} Your browser will show a security warning for the self-signed"
|
||||
echo "certificate. You can safely accept it to proceed."
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${YELLOW}Your application will be available at:${NC}"
|
||||
echo ""
|
||||
echo -e " ${BLUE}https://$SERVER_IP${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Note:${NC} Your browser will show a security warning for the self-signed"
|
||||
echo "certificate. You can safely accept it to proceed."
|
||||
echo ""
|
||||
|
|
|
|||
|
|
@ -207,10 +207,9 @@ if ([string]::IsNullOrEmpty($existingMinioRootPassword)) {
|
|||
|
||||
Write-Host ''
|
||||
Write-Host "Docker registry: $Registry"
|
||||
Write-Host "Telemetry enabled: $EnableTelemetry"
|
||||
Write-Host ''
|
||||
Write-Host 'This will run:'
|
||||
Write-Host " `$env:REGISTRY = '$Registry'; `$env:ENABLE_TELEMETRY = '$EnableTelemetry'; docker compose up --pull always"
|
||||
Write-Host " `$env:REGISTRY = '$Registry'; `$env:ENABLE_TELEMETRY = '$EnableTelemetry'; docker compose --profile tunnel up --pull always"
|
||||
Write-Host ''
|
||||
|
||||
$answer = Read-Host 'Start Dograh now? [Y/n]'
|
||||
|
|
@ -222,7 +221,7 @@ if ($answer -match '^[Nn]') {
|
|||
$env:REGISTRY = $Registry
|
||||
$env:ENABLE_TELEMETRY = $EnableTelemetry
|
||||
Sync-PostgresPassword -Password (Get-DotEnvValue -Path $EnvFile -Key 'POSTGRES_PASSWORD')
|
||||
docker compose up --pull always
|
||||
docker compose --profile tunnel up --pull always
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,10 +200,9 @@ fi
|
|||
|
||||
echo ""
|
||||
echo "Docker registry: $REGISTRY"
|
||||
echo "Telemetry enabled: $ENABLE_TELEMETRY"
|
||||
echo ""
|
||||
echo "This will run:"
|
||||
echo " REGISTRY=$REGISTRY ENABLE_TELEMETRY=$ENABLE_TELEMETRY docker compose up --pull always"
|
||||
echo " REGISTRY=$REGISTRY ENABLE_TELEMETRY=$ENABLE_TELEMETRY docker compose --profile tunnel up --pull always"
|
||||
echo ""
|
||||
|
||||
if [[ ! -t 0 ]]; then
|
||||
|
|
@ -222,4 +221,4 @@ esac
|
|||
postgres_password="$(dotenv_value POSTGRES_PASSWORD || true)"
|
||||
sync_postgres_password "$postgres_password"
|
||||
|
||||
REGISTRY="$REGISTRY" ENABLE_TELEMETRY="$ENABLE_TELEMETRY" docker compose up --pull always
|
||||
REGISTRY="$REGISTRY" ENABLE_TELEMETRY="$ENABLE_TELEMETRY" docker compose --profile tunnel up --pull always
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue