#!/bin/sh set -eu # Usage: ./workspaces-linux-x64-install.sh # root-check (ohne EUID: bashism) if [ "$(id -u)" -ne 0 ]; then echo "please execute as root (sudo)." exit 1 fi WEBSERVER="${1:-}" DOMAIN="${2:-}" EMAIL="${3:-}" PORT="5000" if [ -z "$WEBSERVER" ]; then echo "error: missing parameters." echo "usage: $0 " exit 1 fi # check for update parameter if [ "$WEBSERVER" = "update" ]; then systemctl stop workspaces echo "downloading workspaces-linux-x64.tar.gz" wget -O /srv/workspaces-linux-x64.tar.gz \ "https://git.exystem.net/Exystem-Services-Dev/workspaces-public/raw/branch/main/Deployments/workspaces-linux-x64.tar.gz" echo "extracting to /srv/workspaces ..." tar -xvzf /srv/workspaces-linux-x64.tar.gz -C /srv/workspaces rm -f /srv/workspaces-linux-x64.tar.gz || true chown -R workspacesuser:workspacesuser /srv/workspaces chmod -R 700 /srv/workspaces systemctl start workspaces echo "finished (update)." exit 1 fi if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ]; then echo "error: missing parameters." echo "usage: $0 " exit 1 fi case "$WEBSERVER" in apache2) echo "installing Workspaces instance with apache2:" ;; nginx) echo "installing Workspaces instance with nginx:" ;; *) echo "error: invalid web server parameter"; exit 1 ;; esac echo "Workspace instance installation started..." # download & extract tar.gz echo "downloading workspaces-linux-x64.tar.gz" wget -O /srv/workspaces-linux-x64.tar.gz \ "https://git.exystem.net/Exystem-Services-Dev/workspaces-public/raw/branch/main/Deployments/workspaces-linux-x64.tar.gz" echo "preparing target dir /srv/workspaces ..." mkdir -p /srv/workspaces echo "extracting to /srv/workspaces ..." tar -xvzf /srv/workspaces-linux-x64.tar.gz -C /srv/workspaces rm -f /srv/workspaces-linux-x64.tar.gz || true echo "configuring user and rights..." # idempotent user creation (system user, no login) if id -u workspacesuser >/dev/null 2>&1; then echo "user 'workspacesuser' already exists." else # Fallback: create normal user if useradd not present if command -v useradd >/dev/null 2>&1; then useradd --system --create-home --home-dir /srv/workspaces --shell /usr/sbin/nologin workspacesuser else adduser --disabled-login --gecos "" workspacesuser || true fi fi chown -R workspacesuser:workspacesuser /srv/workspaces chmod -R 700 /srv/workspaces # make app executable if present if [ -f /srv/workspaces/workspaces/Xstm.Workspace ]; then chmod +x /srv/workspaces/workspaces/Xstm.Workspace fi echo "configuring service..." cat </etc/systemd/system/workspaces.service [Unit] Description=Xstm.Workspace After=network.target [Service] Type=simple User=workspacesuser WorkingDirectory=/srv/workspaces/workspaces Environment=ASPNETCORE_URLS=http://127.0.0.1:${PORT} ExecStart=/srv/workspaces/workspaces/Xstm.Workspace Restart=on-failure [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now workspaces echo "configuring web server..." # helper: backup file if exists backup_if_exists() { if [ -f "$1" ]; then cp -a "$1" "$1.bak.$(date +%s)" fi } if [ "$WEBSERVER" = "apache2" ]; then # ---------------- Apache start ---------------- echo "checking/installing apache2 & certbot..." apt-get update -y DEBIAN_FRONTEND=noninteractive apt-get install -y apache2 certbot python3-certbot-apache a2enmod proxy proxy_http headers rewrite ssl reqtimeout echo "creating apache vHost for ${DOMAIN}..." SITE_CONF="/etc/apache2/sites-available/${DOMAIN}.conf" mkdir -p /var/www/letsencrypt/.well-known/acme-challenge/ backup_if_exists "$SITE_CONF" cat >"$SITE_CONF" < ServerName ${DOMAIN} # Upload/Timeouts großzügig LimitRequestBody 0 ProxyTimeout 3600 Timeout 3600 RequestReadTimeout header=3600,MinRate=1 body=3600,MinRate=1 # ACME-Challenge (aus Proxy ausnehmen) Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/ Options None AllowOverride None Require all granted ProxyPass /.well-known/acme-challenge/ ! ProxyPreserveHost On ProxyPass / http://127.0.0.1:${PORT}/ retry=0 timeout=3600 connectiontimeout=3600 ProxyPassReverse / http://127.0.0.1:${PORT}/ Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined EOF a2ensite "${DOMAIN}.conf" a2dissite 000-default.conf || true apache2ctl configtest systemctl reload apache2 # UFW if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "Status: active"; then ufw allow "Apache Full" || true ufw delete allow "Apache" || true fi echo "configuring certbot..." certbot --apache -d "$DOMAIN" -m "$EMAIL" --agree-tos --redirect -n systemctl reload apache2 echo "finished (apache)." # ---------------- Apache end ---------------- elif [ "$WEBSERVER" = "nginx" ]; then # ---------------- Nginx start ---------------- echo "checking/installing nginx & certbot..." apt-get update -y DEBIAN_FRONTEND=noninteractive apt-get install -y nginx certbot python3-certbot-nginx # optional global baseline if ! grep -q "client_max_body_size" /etc/nginx/nginx.conf; then # GNU sed -i; ok auf Debian/Ubuntu sed -i 's/http {/http {\n client_max_body_size 50m;/' /etc/nginx/nginx.conf fi SITE_AVAIL="/etc/nginx/sites-available/${DOMAIN}" SITE_ENABLED="/etc/nginx/sites-enabled/${DOMAIN}" mkdir -p /var/www/letsencrypt backup_if_exists "$SITE_AVAIL" echo "creating server block for ${DOMAIN}..." cat >"$SITE_AVAIL" </dev/null 2>&1 && ufw status | grep -q "Status: active"; then ufw allow "Nginx Full" || true ufw delete allow "Nginx HTTP" || true fi echo "configuring certbot..." certbot --nginx -d "$DOMAIN" -m "$EMAIL" --agree-tos --redirect -n systemctl reload nginx echo "finished (nginx)." # ---------------- Nginx end ---------------- else echo "invalid web server parameter" exit 1 fi echo "All done. Domain: https://${DOMAIN} | Proxy → http://127.0.0.1:${PORT}"