fix: podman network with fixed IPs, remove host networking
This commit is contained in:
parent
55e1cbece2
commit
2ce600bb6d
7 changed files with 90 additions and 124 deletions
|
|
@ -3,9 +3,16 @@ services:
|
|||
image: git24hcom/authelia:latest
|
||||
container_name: authelia
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
expose:
|
||||
- "9091"
|
||||
- "8080"
|
||||
volumes:
|
||||
- /opt/nextworkspace/config/authelia/:/config/
|
||||
- /opt/nextworkspace/data/authelia/:/data/
|
||||
environment:
|
||||
- TZ=UTC
|
||||
networks:
|
||||
nextwks-net:
|
||||
ipv4_address: 172.16.0.11
|
||||
|
||||
networks:
|
||||
nextwks-net:
|
||||
external: true
|
||||
|
|
|
|||
|
|
@ -3,10 +3,18 @@ services:
|
|||
image: caddy:latest
|
||||
container_name: caddy
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /opt/nextworkspace/config/caddy/:/etc/caddy/
|
||||
- /opt/nextworkspace/data/caddy/:/data/
|
||||
- /opt/nextworkspace/logs/caddy/:/var/log/caddy/
|
||||
environment:
|
||||
- TZ=UTC
|
||||
- /opt/nextworkspace/www/:/opt/nextworkspace/www/
|
||||
networks:
|
||||
nextwks-net:
|
||||
ipv4_address: 172.16.0.10
|
||||
|
||||
networks:
|
||||
nextwks-net:
|
||||
external: true
|
||||
|
|
|
|||
23
compose/launcher.yaml
Normal file
23
compose/launcher.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
services:
|
||||
launcher:
|
||||
image: alpine:latest
|
||||
container_name: launcher
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- "9000"
|
||||
volumes:
|
||||
- /opt/nextworkspace/:/opt/nextworkspace/
|
||||
- /opt/nextworkspace/data/:/opt/nextworkspace/data/
|
||||
- /opt/nextworkspace/lng/:/opt/nextworkspace/lng/
|
||||
- /opt/nextworkspace/.env:/opt/nextworkspace/.env
|
||||
working_dir: /opt/nextworkspace
|
||||
command: /opt/nextworkspace/nextworkspace
|
||||
environment:
|
||||
- CONFIG_DIR=/opt/nextworkspace/config/nextworkspace
|
||||
networks:
|
||||
nextwks-net:
|
||||
ipv4_address: 172.16.0.12
|
||||
|
||||
networks:
|
||||
nextwks-net:
|
||||
external: true
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
###############################################################
|
||||
# Authelia configuration #
|
||||
###############################################################
|
||||
host: 127.0.0.1
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
|
||||
log:
|
||||
|
|
|
|||
|
|
@ -6,21 +6,16 @@
|
|||
|
||||
# Authelia OIDC provider
|
||||
auth.{DOMAIN} {
|
||||
reverse_proxy 127.0.0.1:9091
|
||||
reverse_proxy authelia:9091
|
||||
}
|
||||
|
||||
# Main workspace (forward auth with Authelia)
|
||||
app.{DOMAIN} {
|
||||
# Forward auth to Authelia verify endpoint
|
||||
forward_auth 127.0.0.1:9091 {
|
||||
forward_auth authelia:9091 {
|
||||
uri /api/verify?rd=https://auth.{DOMAIN}/
|
||||
|
||||
# Copy auth headers to upstream
|
||||
copy_headers Remote-User Remote-Name Remote-Email Remote-Groups
|
||||
}
|
||||
|
||||
# Serve launcher + proxy upstream apps
|
||||
reverse_proxy 127.0.0.1:9000
|
||||
reverse_proxy launcher:9000
|
||||
}
|
||||
|
||||
# Public landing page
|
||||
|
|
|
|||
139
deploy.sh
139
deploy.sh
|
|
@ -5,8 +5,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|||
REPO_DIR="/opt/NextWks"
|
||||
TARGET_DIR="/opt/nextworkspace"
|
||||
BACKUP_DIR="/opt/backup"
|
||||
SERVICE_NAME="nextworkspace"
|
||||
BINARY_NAME="nextworkspace"
|
||||
NETWORK_NAME="nextwks-net"
|
||||
HEALTH_CHECK_RETRIES=10
|
||||
HEALTH_CHECK_INTERVAL=2
|
||||
|
||||
|
|
@ -17,7 +16,6 @@ elif [ -f "$TARGET_DIR/.env" ]; then
|
|||
set -a; source "$TARGET_DIR/.env"; set +a
|
||||
fi
|
||||
DOMAIN="${DOMAIN:-nextwks.eu}"
|
||||
APP_SUB="${APP_SUB:-app}"
|
||||
|
||||
# --- Mode ---
|
||||
GREENFIELD=false
|
||||
|
|
@ -27,46 +25,32 @@ else echo "[MODE] Smart update (target exists)"; fi
|
|||
|
||||
# --- Pull + build ---
|
||||
cd "$REPO_DIR"
|
||||
echo "[1/5] Pulling latest code..."
|
||||
echo "[1/6] Pulling latest code..."
|
||||
git pull 2>/dev/null || true
|
||||
|
||||
echo "[2/5] Building binary..."
|
||||
echo "[2/6] Building binary..."
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
go build -o "$BINARY_NAME" .
|
||||
go build -o nextworkspace .
|
||||
|
||||
# --- Greenfield ---
|
||||
if [ "$GREENFIELD" = true ]; then
|
||||
echo "[3/5] Full teardown..."
|
||||
systemctl stop $SERVICE_NAME 2>/dev/null || true
|
||||
systemctl disable $SERVICE_NAME 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/$SERVICE_NAME.service
|
||||
systemctl daemon-reload
|
||||
|
||||
# Backup Caddy certs before destroying
|
||||
CADDY_CERTS="$TARGET_DIR/data/caddy/caddy/certificates"
|
||||
if [ -d "$CADDY_CERTS" ]; then
|
||||
mkdir -p "$BACKUP_DIR/certificates"
|
||||
cp -r "$CADDY_CERTS"/* "$BACKUP_DIR/certificates/" 2>/dev/null || true
|
||||
echo "[INFO] Caddy certificates backed up"
|
||||
fi
|
||||
|
||||
sudo -u master podman rm -f caddy authelia 2>/dev/null || true
|
||||
sudo -u master podman pod rm -f caddy authelia 2>/dev/null || true
|
||||
echo "[3/6] Full teardown..."
|
||||
podman rm -f caddy authelia launcher 2>/dev/null || true
|
||||
|
||||
if [ -d "$TARGET_DIR" ]; then
|
||||
chattr -R -i "$TARGET_DIR" 2>/dev/null || true
|
||||
rm -rf "$TARGET_DIR"
|
||||
fi
|
||||
|
||||
echo "[4/5] Building production directories..."
|
||||
echo "[4/6] Building directories..."
|
||||
mkdir -p "$TARGET_DIR/config/caddy"
|
||||
mkdir -p "$TARGET_DIR/config/authelia"
|
||||
mkdir -p "$TARGET_DIR/data/caddy"
|
||||
mkdir -p "$TARGET_DIR/data/authelia"
|
||||
mkdir -p "$TARGET_DIR/compose"
|
||||
mkdir -p "$TARGET_DIR/www"
|
||||
mkdir -p "$TARGET_DIR/config/nextworkspace"
|
||||
mkdir -p "$TARGET_DIR/logs/caddy"
|
||||
# Ensure data dirs are owned by the runtime user
|
||||
chown -R master:master "$TARGET_DIR/data/caddy" 2>/dev/null || true
|
||||
chown -R master:master "$TARGET_DIR/logs/caddy" 2>/dev/null || true
|
||||
|
||||
|
|
@ -76,75 +60,60 @@ if [ "$GREENFIELD" = true ]; then
|
|||
chmod 600 "$TARGET_DIR/.env"
|
||||
fi
|
||||
|
||||
# Generate secrets if missing
|
||||
JWT_SECRET="${JWT_SECRET:-$(openssl rand -hex 32)}"
|
||||
SESSION_SECRET="${SESSION_SECRET:-$(openssl rand -hex 32)}"
|
||||
ADMIN_PASSWORD_HASH="${ADMIN_PASSWORD_HASH:-}"
|
||||
|
||||
# Generate bcrypt password hash for Authelia
|
||||
HASH_TOOL="$(dirname "$0")/tools/hash-password/main.go"
|
||||
if [ -z "$ADMIN_PASSWORD_HASH" ] && [ -n "${ADMIN_PASSWORD:-}" ] && [ -f "$HASH_TOOL" ]; then
|
||||
ADMIN_PASSWORD_HASH=$(cd "$(dirname "$0")" && go run ./tools/hash-password/ "$ADMIN_PASSWORD" 2>/dev/null || echo "")
|
||||
if [ -n "$ADMIN_PASSWORD_HASH" ] && [ -f "$BACKUP_DIR/.env" ]; then
|
||||
echo "ADMIN_PASSWORD_HASH='$ADMIN_PASSWORD_HASH'" >> "$BACKUP_DIR/.env"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Generate Caddyfile (using | delimiter to avoid conflicts with / and @)
|
||||
# Generate Caddyfile
|
||||
sed -e "s|{DOMAIN}|$DOMAIN|g" -e "s|{TLS_EMAIL}|${TLS_EMAIL:-admin@$DOMAIN}|g" \
|
||||
"$SCRIPT_DIR/config/caddy/Caddyfile" > "$TARGET_DIR/config/caddy/Caddyfile"
|
||||
|
||||
# Generate Authelia config
|
||||
# Generate Authelia config (minimal — deploy.sh fills secrets)
|
||||
JWT_SECRET="${JWT_SECRET:-$(openssl rand -hex 32)}"
|
||||
SESSION_SECRET="${SESSION_SECRET:-$(openssl rand -hex 32)}"
|
||||
sed -e "s|{DOMAIN}|$DOMAIN|g" \
|
||||
-e "s|{JWT_SECRET}|$JWT_SECRET|g" \
|
||||
-e "s|{SESSION_SECRET}|$SESSION_SECRET|g" \
|
||||
-e "s|{SMTP_HOST}|${SMTP_HOST:-smtp.openxchange.eu}|g" \
|
||||
-e "s|{SMTP_PORT}|${SMTP_PORT:-587}|g" \
|
||||
-e "s|{SMTP_USER}|${SMTP_USER:-post@nextwks.eu}|g" \
|
||||
-e "s|{SMTP_PASS}|${SMTP_PASS}|g" \
|
||||
-e "s|{SMTP_PASS}|$SMTP_PASS|g" \
|
||||
"$SCRIPT_DIR/config/authelia/configuration.yml" > "$TARGET_DIR/config/authelia/configuration.yml"
|
||||
|
||||
# Generate users database
|
||||
ADMIN_PASSWORD_HASH="${ADMIN_PASSWORD_HASH:-}"
|
||||
if [ -z "$ADMIN_PASSWORD_HASH" ] && [ -n "${ADMIN_PASSWORD:-}" ] && [ -f "$SCRIPT_DIR/tools/hash-password/main.go" ]; then
|
||||
ADMIN_PASSWORD_HASH=$(cd "$SCRIPT_DIR" && go run ./tools/hash-password/ "$ADMIN_PASSWORD" 2>/dev/null || echo "")
|
||||
fi
|
||||
sed -e "s|{ADMIN_PASSWORD_HASH}|$ADMIN_PASSWORD_HASH|g" \
|
||||
-e "s|{TLS_EMAIL}|${TLS_EMAIL:-admin@$DOMAIN}|g" \
|
||||
"$SCRIPT_DIR/config/authelia/users_database.yml" > "$TARGET_DIR/config/authelia/users_database.yml"
|
||||
|
||||
# Copy compose files
|
||||
# Copy compose files + binary
|
||||
cp "$SCRIPT_DIR/compose/caddy.yaml" "$TARGET_DIR/compose/caddy.yaml"
|
||||
cp "$SCRIPT_DIR/compose/authelia.yaml" "$TARGET_DIR/compose/authelia.yaml"
|
||||
|
||||
# Copy binary
|
||||
cp "$SCRIPT_DIR/compose/launcher.yaml" "$TARGET_DIR/compose/launcher.yaml"
|
||||
cp "$BINARY_NAME" "$TARGET_DIR/$BINARY_NAME"
|
||||
if [ -f "$REPO_DIR/VERSION" ]; then
|
||||
cp "$REPO_DIR/VERSION" "$TARGET_DIR/VERSION"
|
||||
fi
|
||||
|
||||
# Copy www landing page
|
||||
# Copy landing page
|
||||
if [ -d "$SCRIPT_DIR/config/www" ]; then
|
||||
cp -r "$SCRIPT_DIR/config/www"/* "$TARGET_DIR/www/"
|
||||
fi
|
||||
|
||||
# Deploy Caddy + Authelia
|
||||
echo "[5/5] Deploying Caddy and Authelia..."
|
||||
mkdir -p "$TARGET_DIR/data/caddy"
|
||||
|
||||
# Restore Caddy certs from backup if available
|
||||
if [ -d "$BACKUP_DIR/certificates/acme-v02" ]; then
|
||||
mkdir -p "$CADDY_CERTS"
|
||||
cp -r "$BACKUP_DIR/certificates"/* "$CADDY_CERTS/" 2>/dev/null || true
|
||||
echo "[INFO] Restored Caddy certificates from backup"
|
||||
fi
|
||||
|
||||
sudo -u master podman-compose -f "$TARGET_DIR/compose/caddy.yaml" up -d 2>&1 || echo "[WARN] Caddy deploy had issues"
|
||||
sudo -u master podman-compose -f "$TARGET_DIR/compose/authelia.yaml" up -d 2>&1 || echo "[WARN] Authelia deploy had issues"
|
||||
|
||||
# Basic launcher config
|
||||
# Copy launcher config
|
||||
cp -r "$SCRIPT_DIR/config/nextworkspace"/* "$TARGET_DIR/config/nextworkspace/" 2>/dev/null || true
|
||||
|
||||
# Copy apps.yaml template
|
||||
cp "$SCRIPT_DIR/config/nextworkspace/apps.yaml" "$TARGET_DIR/config/nextworkspace/apps.yaml" 2>/dev/null || true
|
||||
# Create podman network
|
||||
echo "[5/6] Creating podman network..."
|
||||
podman network create --subnet 172.16.0.0/24 "$NETWORK_NAME" 2>/dev/null || true
|
||||
|
||||
# Extract Authelia secret for binary
|
||||
# Deploy all containers
|
||||
echo "[6/6] Deploying containers..."
|
||||
podman-compose -f "$TARGET_DIR/compose/launcher.yaml" up -d 2>&1 || echo "[WARN] Launcher deploy had issues"
|
||||
podman-compose -f "$TARGET_DIR/compose/authelia.yaml" up -d 2>&1 || echo "[WARN] Authelia deploy had issues"
|
||||
podman-compose -f "$TARGET_DIR/compose/caddy.yaml" up -d 2>&1 || echo "[WARN] Caddy deploy had issues"
|
||||
|
||||
# Extract Authelia secret
|
||||
sleep 3
|
||||
AUTHELIA_SECRET=$(grep -oP 'session_secret: \K.*' "$TARGET_DIR/config/authelia/configuration.yml" 2>/dev/null || echo "")
|
||||
if [ -n "$AUTHELIA_SECRET" ]; then
|
||||
if ! grep -q "AUTHELIA_SECRET" "$BACKUP_DIR/.env" 2>/dev/null; then
|
||||
|
|
@ -152,48 +121,12 @@ if [ "$GREENFIELD" = true ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Write systemd service
|
||||
cat > /etc/systemd/system/$SERVICE_NAME.service <<UNIT
|
||||
[Unit]
|
||||
Description=NextWorkspace Launcher
|
||||
After=network.target caddy.service authelia.service
|
||||
Wants=caddy.service authelia.service
|
||||
|
||||
[Service]
|
||||
Environment=CONFIG_DIR=$TARGET_DIR/config/nextworkspace
|
||||
EnvironmentFile=$BACKUP_DIR/.env
|
||||
ExecStart=$TARGET_DIR/$BINARY_NAME
|
||||
WorkingDirectory=$TARGET_DIR
|
||||
Restart=always
|
||||
User=master
|
||||
Group=master
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now $SERVICE_NAME
|
||||
|
||||
# --- Smart update ---
|
||||
else
|
||||
echo "[3/5] Stopping launcher..."
|
||||
systemctl stop $SERVICE_NAME 2>/dev/null || true
|
||||
echo "[4/5] Swapping binary..."
|
||||
cp "$BINARY_NAME" "$TARGET_DIR/$BINARY_NAME"
|
||||
|
||||
# Ensure AUTHELIA_SECRET is in .env
|
||||
AUTHELIA_SECRET=$(grep -oP 'session_secret: \K.*' "$TARGET_DIR/config/authelia/configuration.yml" 2>/dev/null || echo "")
|
||||
if [ -n "$AUTHELIA_SECRET" ]; then
|
||||
if ! grep -q "AUTHELIA_SECRET" "$BACKUP_DIR/.env" 2>/dev/null; then
|
||||
echo "AUTHELIA_SECRET=$AUTHELIA_SECRET" >> "$BACKUP_DIR/.env"
|
||||
echo "[INFO] AUTHELIA_SECRET added to .env"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "[5/5] Restarting services..."
|
||||
sudo -u master podman restart caddy authelia 2>/dev/null || true
|
||||
systemctl restart $SERVICE_NAME
|
||||
echo "[3/6] Redeploying containers..."
|
||||
podman-compose -f "$TARGET_DIR/compose/launcher.yaml" up -d 2>&1 || true
|
||||
podman-compose -f "$TARGET_DIR/compose/authelia.yaml" up -d 2>&1 || true
|
||||
podman-compose -f "$TARGET_DIR/compose/caddy.yaml" restart 2>&1 || true
|
||||
fi
|
||||
|
||||
# --- Health check ---
|
||||
|
|
|
|||
12
main.go
12
main.go
|
|
@ -303,7 +303,7 @@ func proxyToUpstream(upstream string) http.HandlerFunc {
|
|||
}
|
||||
|
||||
func adminHandler(w http.ResponseWriter, r *http.Request) {
|
||||
apiBase := "http://127.0.0.1:8080"
|
||||
apiBase := "http://172.16.0.11:8080"
|
||||
apiToken := os.Getenv("AUTHELIA_SECRET")
|
||||
configDir := os.Getenv("CONFIG_DIR")
|
||||
if configDir == "" {
|
||||
|
|
@ -348,13 +348,13 @@ func adminHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Check service statuses
|
||||
autheliaUp := false
|
||||
if resp, err := http.Get("http://127.0.0.1:9091/api/health"); err == nil {
|
||||
if resp, err := http.Get("http://172.16.0.11:9091/api/health"); err == nil {
|
||||
autheliaUp = resp.StatusCode == 200
|
||||
resp.Body.Close()
|
||||
}
|
||||
caddyUp := false
|
||||
// Check port 80 responds (don't follow HTTPS redirect)
|
||||
if conn, err := net.DialTimeout("tcp", "127.0.0.1:80", 3*time.Second); err == nil {
|
||||
if conn, err := net.DialTimeout("tcp", "172.16.0.10:80", 3*time.Second); err == nil {
|
||||
caddyUp = true
|
||||
conn.Close()
|
||||
}
|
||||
|
|
@ -511,7 +511,7 @@ type apiUser struct {
|
|||
|
||||
func fetchAllUsers() ([]apiUser, error) {
|
||||
apiToken := os.Getenv("AUTHELIA_SECRET")
|
||||
req, _ := http.NewRequest("GET", "http://127.0.0.1:8080/api/users", nil)
|
||||
req, _ := http.NewRequest("GET", "http://172.16.0.11:8080/api/users", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+apiToken)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
|
|
@ -608,7 +608,7 @@ func initials(s string) string {
|
|||
// --- API proxy for authelia-api ---
|
||||
|
||||
func apiProxyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
target, _ := url.Parse("http://127.0.0.1:8080")
|
||||
target, _ := url.Parse("http://172.16.0.11:8080")
|
||||
proxy := httputil.NewSingleHostReverseProxy(target)
|
||||
// Inject Bearer token for authelia-api auth
|
||||
token := os.Getenv("AUTHELIA_SECRET")
|
||||
|
|
@ -638,7 +638,7 @@ func globalSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Check Authelia health
|
||||
autheliaUp := false
|
||||
if resp, err := http.Get("http://127.0.0.1:9091/api/health"); err == nil {
|
||||
if resp, err := http.Get("http://172.16.0.11:9091/api/health"); err == nil {
|
||||
autheliaUp = resp.StatusCode == 200
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue