#!/bin/bash set -euxo pipefail ############################################################################### # Cloud-Init for KrustyPlanet VPS ############################################################################### # Update system apt-get update -y apt-get upgrade -y # Install required packages apt-get install -y nginx certbot python3-certbot-nginx curl git # Install Node.js curl -fsSL https://deb.nodesource.com/setup_${node_version}.x | bash - apt-get install -y nodejs # Create directories mkdir -p /opt/contact-api mkdir -p /var/www/${project_name} mkdir -p /var/www/${project_name}/css mkdir -p /var/www/${project_name}/js # Set domain variable DOMAIN=${domain} # Set up nginx configuration cat << 'EOF' > /etc/nginx/sites-available/${project_name} server { root /var/www/${project_name}; index index.html; server_name ${DOMAIN} www.${DOMAIN}; location ~* \.(js|css)$ { add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; try_files $uri $uri/ =404; } location / { try_files $uri $uri/ =404; } add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; listen [::]:443 ssl ipv6only=on; listen 443 ssl; ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { listen 80; listen [::]:80; server_name ${DOMAIN} www.${DOMAIN}; return 301 https://$host$request_uri; } EOF # Symlink nginx config ln -sf /etc/nginx/sites-available/${project_name} /etc/nginx/sites-enabled/${project_name} # Remove default nginx site rm -f /etc/nginx/sites-enabled/default # Set up contact-api service cat << 'EOF' > /etc/systemd/system/contact-api.service [Unit] Description=Contact Form API - Email Backend After=network.target [Service] Type=simple User=www-data Group=www-data WorkingDirectory=/opt/contact-api ExecStart=/usr/bin/node src/index.js Restart=on-failure RestartSec=10 # Environment EnvironmentFile=/opt/contact-api/.env # Security NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/opt/contact-api # Logging StandardOutput=journal StandardError=journal SyslogIdentifier=contact-api [Install] WantedBy=multi-user.target EOF # Start nginx systemctl restart nginx # Enable contact-api service systemctl daemon-reload systemctl enable contact-api.service # Create .env file for contact-api cat << 'EOF' > /opt/contact-api/.env PORT=3001 SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USER=your-email@example.com SMTP_PASS=your-password FROM_EMAIL=noreply@krustyplanet.org FROM_NAME=KrustyPlanet EOF # Download contact-api source cd /opt/contact-api git clone https://codeberg.org/jez/contact-api.git . # Or download from URL if git repo doesn't exist # curl -L https://example.com/contact-api.tar.gz | tar -xzf - # Install dependencies npm install # Set permissions chown -R www-data:www-data /opt/contact-api chown -R www-data:www-data /var/www/${project_name} # Start contact-api systemctl start contact-api.service # Get SSL certificate certbot --nginx --non-interactive --agree-tos --email noreply@krustyplanet.org -d ${DOMAIN} -d www.${DOMAIN} # Enable certbot auto-renewal systemctl enable certbot.timer # Clean up apt-get autoremove -y apt-get clean echo "KrustyPlanet VPS setup complete!"