Files
server-scripts/install_nextcloud.sh
2026-01-05 22:18:06 +01:00

282 lines
8.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
USERNAME="$1"
DOMAIN="$2"
APACHE_PORT="$3"
PUBLIC_PORT="$4"
TALK_PORT="$5"
if [ -z "$TALK_PORT" ]; then
echo "Usage: $0 <username> <domain> <apache_port> <public_port> <talk_port>"
exit 1
fi
FULL_DOMAIN="${USERNAME}.${DOMAIN}"
VHOST_FILE="/etc/apache2/sites-available/${FULL_DOMAIN}.conf"
USER_HOME="/home/${USERNAME}"
USER_SCRIPT="${USER_HOME}/install_nc.sh"
need_cmd() { command -v "$1" >/dev/null 2>&1; }
port_free() {
local p="$1"
if ss -ltnp 2>/dev/null | grep -qE ":(^|.*:)$p\s"; then
return 1
fi
return 0
}
############################################################
# 0 - PACKAGES + APACHE + CERTBOT
############################################################
echo "[0/8] Ensuring required packages..."
need_cmd curl || (apt-get update -y && apt-get install -y curl)
need_cmd dig || (apt-get update -y && apt-get install -y dnsutils)
echo "[0.1/8] Ensuring Apache + modules..."
need_cmd apache2 || (apt-get update -y && apt-get install -y apache2)
mkdir -p /etc/apache2/sites-available /etc/apache2/sites-enabled
a2enmod proxy proxy_http proxy_wstunnel rewrite headers ssl http2 >/dev/null || true
systemctl enable --now apache2 >/dev/null
echo "[0.2/8] Ensuring certbot..."
need_cmd certbot || (apt-get update -y && apt-get install -y certbot python3-certbot-apache)
############################################################
# 0.3 - DNS CHECK
############################################################
echo "[0.3/8] Checking DNS for $FULL_DOMAIN ..."
SERVER_IP=$(curl -s https://api.ipify.org)
DOMAIN_IP=$(dig +short "$FULL_DOMAIN" | head -n1)
if [ -z "$DOMAIN_IP" ]; then
echo "❌ ERROR: Domain does not resolve."
exit 1
fi
if [ "$DOMAIN_IP" != "$SERVER_IP" ]; then
echo "❌ ERROR: DNS does not point to this server."
echo "Domain IP: $DOMAIN_IP"
echo "Server IP: $SERVER_IP"
exit 1
fi
echo "✅ DNS OK."
############################################################
# 0.4 - PORT CHECKS (host ports are global even across rootless users)
############################################################
echo "[0.4/8] Checking host ports are free..."
for p in "$PUBLIC_PORT" "$APACHE_PORT" "$TALK_PORT"; do
if ! port_free "$p"; then
echo "❌ ERROR: Port $p is already in use on the host."
ss -ltnp | grep -E ":$p\s" || true
exit 1
fi
done
echo "✅ Ports look free."
############################################################
# 1 - CREATE USER
############################################################
echo "[1/8] Creating user $USERNAME with password 12345..."
if id "$USERNAME" >/dev/null 2>&1; then
echo "User already exists. Skipping adduser."
else
adduser --gecos "" "$USERNAME" --disabled-password
echo "${USERNAME}:12345" | chpasswd
fi
############################################################
# 2 - ADD USER TO SUDO + LINGER
############################################################
echo "[2/8] Adding $USERNAME to sudo..."
usermod -aG sudo "$USERNAME" || true
echo "[2.1/8] Enabling linger for $USERNAME..."
loginctl enable-linger "$USERNAME" || true
############################################################
# 3 - CREATE VHOST
############################################################
echo "[3/8] Creating vhost $VHOST_FILE ..."
tee "$VHOST_FILE" >/dev/null <<EOF
<VirtualHost *:80>
ServerName ${FULL_DOMAIN}
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
<VirtualHost *:443>
ServerName ${FULL_DOMAIN}
RewriteEngine On
ProxyPreserveHost On
RequestHeader set X-Real-IP %{REMOTE_ADDR}s
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:${APACHE_PORT}/ nocanon
ProxyPassReverse / http://localhost:${APACHE_PORT}/
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteCond %{THE_REQUEST} "^[a-zA-Z]+ /(.*) HTTP/\\d+(\\.\\d+)?$"
RewriteRule .? "ws://localhost:${APACHE_PORT}/%1" [P,L,UnsafeAllow3F]
Protocols h2 h2c http/1.1
H2WindowSize 5242880
TraceEnable off
<Files ".ht*">
Require all denied
</Files>
LimitRequestBody 0
Timeout 86400
ProxyTimeout 86400
</VirtualHost>
EOF
############################################################
# 4 - ENABLE SITE + CERT
############################################################
echo "[4/8] Enabling site..."
a2ensite "${FULL_DOMAIN}" >/dev/null || true
systemctl reload apache2
echo "[5/8] Running certbot..."
if [ ! -d "/etc/letsencrypt/live/${FULL_DOMAIN}" ]; then
certbot certonly --apache -d "${FULL_DOMAIN}"
else
echo "Certificate already exists. Skipping certbot."
fi
SSL_CERT="/etc/letsencrypt/live/${FULL_DOMAIN}/fullchain.pem"
SSL_KEY="/etc/letsencrypt/live/${FULL_DOMAIN}/privkey.pem"
if ! grep -q "SSLCertificateFile ${SSL_CERT}" "$VHOST_FILE"; then
sed -i "/Protocols h2 h2c http\\/1.1/a \
# TLS\n\
SSLEngine on\n\
SSLProtocol -all +TLSv1.2 +TLSv1.3\n\
SSLSessionTickets off\n\
SSLCertificateFile ${SSL_CERT}\n\
SSLCertificateKeyFile ${SSL_KEY}\n\
" "$VHOST_FILE"
fi
systemctl reload apache2
############################################################
# 6 - CREATE install_nc.sh IN USER HOME
############################################################
echo "[6/8] Creating ${USER_SCRIPT} ..."
tee "$USER_SCRIPT" >/dev/null <<'EOF'
#!/usr/bin/env bash
set -e
# Always have docker available in new SSH sessions
mkdir -p "$HOME/bin"
touch "$HOME/.profile" "$HOME/.bashrc"
grep -q 'export PATH="$HOME/bin:$PATH"' "$HOME/.profile" || echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.profile"
grep -q 'export PATH="$HOME/bin:$PATH"' "$HOME/.bashrc" || echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.bashrc"
# Rootless docker env for new shells
grep -q 'export XDG_RUNTIME_DIR="/run/user/$(id -u)"' "$HOME/.bashrc" || echo 'export XDG_RUNTIME_DIR="/run/user/$(id -u)"' >> "$HOME/.bashrc"
grep -q 'export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"' "$HOME/.bashrc" || echo 'export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"' >> "$HOME/.bashrc"
# Apply now
export PATH="$HOME/bin:$PATH"
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"
echo "[1/3] Installing rootless Docker prerequisites..."
sudo apt-get update -y
sudo apt-get install -y uidmap dbus-user-session slirp4netns fuse-overlayfs curl
echo "[2/3] Installing rootless Docker..."
if ! curl -fsSL https://get.docker.com/rootless | sh; then
echo "⚠️ Rootless installer failed. Retrying with --skip-iptables..."
"$HOME/bin/dockerd-rootless-setuptool.sh" install --skip-iptables
fi
export PATH="$HOME/bin:$PATH"
if ! command -v docker >/dev/null 2>&1; then
echo "❌ docker client not found after install."
ls -la "$HOME/bin" || true
exit 1
fi
echo "Enabling linger..."
sudo loginctl enable-linger "$USER" || true
echo "Starting rootless Docker..."
systemctl --user daemon-reload || true
systemctl --user enable --now docker || true
# Fallback if service isn't active
if ! systemctl --user is-active --quiet docker 2>/dev/null; then
nohup dockerd-rootless.sh >/tmp/dockerd-rootless.log 2>&1 &
fi
# Wait for socket
for i in {1..30}; do
if [ -S "$XDG_RUNTIME_DIR/docker.sock" ]; then
break
fi
sleep 1
done
if [ ! -S "$XDG_RUNTIME_DIR/docker.sock" ]; then
echo "❌ docker.sock not found at $XDG_RUNTIME_DIR/docker.sock"
exit 1
fi
echo "✅ Rootless docker.sock exists: $XDG_RUNTIME_DIR/docker.sock"
ls -la "$XDG_RUNTIME_DIR/docker.sock" || true
echo "[3/3] Starting Nextcloud AIO mastercontainer..."
docker rm -f nextcloud-aio-mastercontainer >/dev/null 2>&1 || true
docker run -d \
--init \
--sig-proxy=false \
--name nextcloud-aio-mastercontainer \
--restart always \
--publish __PUBLIC_PORT__:8080 \
--env APACHE_PORT=__APACHE_PORT__ \
--env TALK_PORT=__TALK_PORT__ \
--env APACHE_IP_BINDING=0.0.0.0 \
--env APACHE_ADDITIONAL_NETWORK="" \
--env SKIP_DOMAIN_VALIDATION=false \
--env AIO_DISABLE_SECURITY_CHECKS=true \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume "$XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock" \
ghcr.io/nextcloud-releases/all-in-one:latest
echo "✅ AIO mastercontainer started."
echo "Open: https://<SERVER-IP>:__PUBLIC_PORT__/ (IP only) and click 'Download and start containers'"
EOF
# Patch placeholders with actual ports
sed -i "s/__PUBLIC_PORT__/${PUBLIC_PORT}/g" "$USER_SCRIPT"
sed -i "s/__APACHE_PORT__/${APACHE_PORT}/g" "$USER_SCRIPT"
sed -i "s/__TALK_PORT__/${TALK_PORT}/g" "$USER_SCRIPT"
chown "$USERNAME:$USERNAME" "$USER_SCRIPT"
chmod +x "$USER_SCRIPT"
############################################################
# 7 - DONE
############################################################
echo "------------------------------------------------------------"
echo " PHASE 1 COMPLETE"
echo " Login as: $USERNAME"
echo " Run: ./install_nc.sh"
echo "------------------------------------------------------------"