Installer: reliably add peardock user to docker group
Release rolling / release (push) Successful in 9m12s
Release rolling / release (push) Successful in 9m12s
Create the docker group when missing, usermod -aG with verification, align socket group/mode when needed, and set systemd Group and SupplementaryGroups so the service can access the Docker socket.
This commit is contained in:
+106
-10
@@ -260,6 +260,101 @@ asset_url() {
|
||||
echo "${GITEA_URL}/${OWNER}/${REPO}/releases/download/${TAG}/${name}"
|
||||
}
|
||||
|
||||
# ─── docker group / socket access ───────────────────────────────────────────
|
||||
# Engine socket is typically root:docker mode 660. peardock.service runs as
|
||||
# User=peardock and must be a docker group member (SupplementaryGroups=docker).
|
||||
ensure_peardock_docker_group() {
|
||||
local sock="${DOCKER_HOST:-}"
|
||||
local grp="docker"
|
||||
|
||||
# Normalize DOCKER_HOST=unix:///var/run/docker.sock → path
|
||||
if [[ -z "$sock" || "$sock" == unix://* || "$sock" == /* ]]; then
|
||||
sock="${sock#unix://}"
|
||||
sock="${sock:-/var/run/docker.sock}"
|
||||
else
|
||||
# tcp://… — group membership not required for local socket, but still useful
|
||||
sock="/var/run/docker.sock"
|
||||
fi
|
||||
|
||||
if [[ ! -S "$sock" ]]; then
|
||||
warn "Docker socket not found at ${sock}"
|
||||
warn "Install/start Docker, then re-run: sudo usermod -aG docker peardock && sudo systemctl restart peardock"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Prefer the socket's group when it is not root
|
||||
local sock_grp
|
||||
sock_grp="$(stat -c '%G' "$sock" 2>/dev/null || stat -f '%Sg' "$sock" 2>/dev/null || echo docker)"
|
||||
if [[ -n "$sock_grp" && "$sock_grp" != "root" ]]; then
|
||||
grp="$sock_grp"
|
||||
fi
|
||||
|
||||
if ! getent group "$grp" >/dev/null 2>&1; then
|
||||
log "Creating group '${grp}' for Docker socket access…"
|
||||
if command -v groupadd >/dev/null 2>&1; then
|
||||
run_root groupadd --system "$grp" 2>/dev/null || run_root groupadd "$grp"
|
||||
elif command -v addgroup >/dev/null 2>&1; then
|
||||
run_root addgroup --system "$grp" 2>/dev/null || run_root addgroup "$grp"
|
||||
else
|
||||
die "Cannot create group '${grp}' (need groupadd/addgroup)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ensure socket is group-accessible when possible
|
||||
local mode
|
||||
mode="$(stat -c '%a' "$sock" 2>/dev/null || echo "")"
|
||||
if [[ -n "$mode" && "$mode" != "666" && "$mode" != "660" && "$mode" != "620" ]]; then
|
||||
log "Setting ${sock} group to ${grp}, mode 660…"
|
||||
run_root chgrp "$grp" "$sock" 2>/dev/null || true
|
||||
run_root chmod 660 "$sock" 2>/dev/null || true
|
||||
else
|
||||
run_root chgrp "$grp" "$sock" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
log "Adding user peardock to group '${grp}'…"
|
||||
if command -v usermod >/dev/null 2>&1; then
|
||||
run_root usermod -aG "$grp" peardock
|
||||
elif command -v gpasswd >/dev/null 2>&1; then
|
||||
run_root gpasswd -a peardock "$grp"
|
||||
elif command -v adduser >/dev/null 2>&1; then
|
||||
run_root adduser peardock "$grp" 2>/dev/null || run_root adduser peardock "$grp"
|
||||
else
|
||||
die "Cannot add peardock to ${grp} (need usermod/gpasswd/adduser)"
|
||||
fi
|
||||
|
||||
# Verify membership (id may need a moment; read /etc/group directly)
|
||||
if getent group "$grp" | grep -qE '(^|,)peardock(,|$)'; then
|
||||
ok "peardock is a member of group '${grp}'"
|
||||
else
|
||||
# usermod sometimes succeeds but getent lag — check id -nG as root
|
||||
if run_root id -nG peardock 2>/dev/null | tr ' ' '\n' | grep -qx "$grp"; then
|
||||
ok "peardock is a member of group '${grp}'"
|
||||
else
|
||||
die "Failed to add peardock to group '${grp}'. Run: sudo usermod -aG ${grp} peardock"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prove socket is reachable as peardock (sg runs with supplementary group)
|
||||
if command -v sg >/dev/null 2>&1; then
|
||||
if run_root sg "$grp" -c "runuser -u peardock -- test -r '$sock' -a -w '$sock'" 2>/dev/null \
|
||||
|| run_root runuser -u peardock -- sg "$grp" -c "test -r '$sock' -a -w '$sock'" 2>/dev/null; then
|
||||
ok "Docker socket ${sock} is read/write for peardock (via ${grp})"
|
||||
else
|
||||
# fallback: test as peardock with full group list after usermod
|
||||
if run_root su -s /bin/sh peardock -c "test -r '$sock' -a -w '$sock'" 2>/dev/null; then
|
||||
ok "Docker socket ${sock} is accessible to peardock"
|
||||
else
|
||||
warn "Could not verify socket RW as peardock yet — restart Docker after group change if needed"
|
||||
warn " sudo systemctl restart docker && sudo systemctl restart peardock"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Export for unit file generation
|
||||
PEARDOCK_DOCKER_GROUP="$grp"
|
||||
export PEARDOCK_DOCKER_GROUP
|
||||
}
|
||||
|
||||
# ─── server install ─────────────────────────────────────────────────────────
|
||||
install_server() {
|
||||
local host="$1" version="$2"
|
||||
@@ -313,14 +408,15 @@ install_server() {
|
||||
|| run_root useradd --system --home "$SERVER_DIR" --shell /bin/false peardock
|
||||
elif command -v adduser >/dev/null 2>&1; then
|
||||
run_root adduser --system --home "$SERVER_DIR" --shell /usr/sbin/nologin --no-create-home peardock || true
|
||||
fi
|
||||
fi
|
||||
# docker group
|
||||
if getent group docker >/dev/null 2>&1; then
|
||||
run_root usermod -aG docker peardock 2>/dev/null || true
|
||||
else
|
||||
warn "docker group not found — ensure peardock can access the Docker socket"
|
||||
die "Cannot create peardock user (need useradd or adduser)"
|
||||
fi
|
||||
fi
|
||||
id peardock >/dev/null 2>&1 || die "peardock user was not created"
|
||||
|
||||
# Docker socket access: peardock must be in the docker group (mode 660 root:docker).
|
||||
ensure_peardock_docker_group
|
||||
|
||||
run_root chown -R peardock:peardock "$SERVER_DIR" 2>/dev/null || run_root chown -R peardock "$SERVER_DIR"
|
||||
|
||||
# systemd unit
|
||||
@@ -344,15 +440,15 @@ RestartSec=5
|
||||
TimeoutStartSec=30
|
||||
TimeoutStopSec=30
|
||||
User=peardock
|
||||
# Prefer docker group when present
|
||||
Group=docker
|
||||
SupplementaryGroups=docker
|
||||
# Primary + supplementary docker group so /var/run/docker.sock (root:docker 660) works
|
||||
Group=${PEARDOCK_DOCKER_GROUP:-docker}
|
||||
SupplementaryGroups=${PEARDOCK_DOCKER_GROUP:-docker}
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
Environment=NODE_ENV=production
|
||||
EnvironmentFile=-${SERVER_DIR}/.env
|
||||
# Docker socket + state
|
||||
ReadWritePaths=${SERVER_DIR}
|
||||
ReadWritePaths=${SERVER_DIR} /var/run/docker.sock /run/docker.sock
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Reference in New Issue
Block a user