Add nginx config and deploy script
Changes
nnew file mode 100755@@@ -0,0 +1,72 @@++#!/usr/bin/env bash++# deploy.sh — Build & deploy alexfrison.net to Nginx static hosting++# Usage: ./deploy/deploy.sh [--skip-build]++# Requirements on server: git, node >=18, npm, nginx++++set -euo pipefail++++REPO_URL="[email protected]:HoboStreamer/AFResume.git"++SITE_DIR="/var/www/alexfrison.net"++NGINX_CONF="/etc/nginx/sites-available/alexfrison.net"++NGINX_ENABLED="/etc/nginx/sites-enabled/alexfrison.net"++DOMAIN="alexfrison.net"++++# ── Helper ────────────────────────────────────────────────────────────────────++info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }++ok() { echo -e "\033[1;32m[OK]\033[0m $*"; }++error() { echo -e "\033[1;31m[ERROR]\033[0m $*" >&2; exit 1; }++++# ── 1. Clone or pull ──────────────────────────────────────────────────────────++if [[ -d "$SITE_DIR/.git" ]]; then++ info "Pulling latest from origin/main..."++ git -C "$SITE_DIR" pull origin main++else++ info "Cloning $REPO_URL → $SITE_DIR..."++ sudo mkdir -p "$SITE_DIR"++ sudo chown "$USER":"$USER" "$SITE_DIR"++ git clone "$REPO_URL" "$SITE_DIR"++fi++++# ── 2. Install deps & build ───────────────────────────────────────────────────++if [[ "${1:-}" != "--skip-build" ]]; then++ info "Installing npm dependencies..."++ npm --prefix "$SITE_DIR" ci --prefer-offline++++ info "Building Astro site..."++ npm --prefix "$SITE_DIR" run build++++ ok "Build complete → $SITE_DIR/dist"++fi++++# ── 3. Install nginx config ───────────────────────────────────────────────────++if [[ ! -f "$NGINX_CONF" ]]; then++ info "Installing nginx config..."++ sudo cp "$SITE_DIR/deploy/nginx.conf" "$NGINX_CONF"++ sudo ln -sf "$NGINX_CONF" "$NGINX_ENABLED"++ ok "Nginx config installed."++else++ info "Nginx config already present at $NGINX_CONF — skipping copy."++ info "To update it manually: sudo cp $SITE_DIR/deploy/nginx.conf $NGINX_CONF"++fi++++# ── 4. Test & reload nginx ────────────────────────────────────────────────────++info "Testing nginx config..."++sudo nginx -t++++info "Reloading nginx..."++sudo systemctl reload nginx++ok "Nginx reloaded."++++# ── 5. SSL reminder ───────────────────────────────────────────────────────────++if [[ ! -d "/etc/letsencrypt/live/$DOMAIN" ]]; then++ echo ""++ echo " ┌─────────────────────────────────────────────────────────┐"++ echo " │ SSL cert not found. Run certbot to finish setup: │"++ echo " │ │"++ echo " │ sudo apt install certbot python3-certbot-nginx │"++ echo " │ sudo certbot --nginx -d $DOMAIN -d www.$DOMAIN │"++ echo " └─────────────────────────────────────────────────────────┘"++ echo ""++fi++++ok "Deploy complete. Visit https://$DOMAIN"nnew file mode 100644@@@ -0,0 +1,55 @@++server {++ listen 80;++ listen [::]:80;++ server_name alexfrison.net www.alexfrison.net;++++ # Redirect HTTP → HTTPS (remove this block if not using SSL)++ return 301 https://$host$request_uri;++}++++server {++ listen 443 ssl http2;++ listen [::]:443 ssl http2;++ server_name alexfrison.net www.alexfrison.net;++++ # --- SSL (certbot will fill these in) ---++ ssl_certificate /etc/letsencrypt/live/alexfrison.net/fullchain.pem;++ ssl_certificate_key /etc/letsencrypt/live/alexfrison.net/privkey.pem;++ include /etc/letsencrypt/options-ssl-nginx.conf;++ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;++++ # --- Root ---++ root /var/www/alexfrison.net/dist;++ index index.html;++++ # --- Gzip ---++ gzip on;++ gzip_vary on;++ gzip_proxied any;++ gzip_comp_level 6;++ gzip_types text/plain text/css text/xml application/json application/javascript++ application/xml+rss application/atom+xml image/svg+xml;++++ # --- Astro static output: try file, then .html, then 404 ---++ location / {++ try_files $uri $uri/ $uri.html =404;++ }++++ # --- Long-lived cache for hashed assets ---++ location ~* \.(js|css|woff2?|ttf|eot|otf|svg|png|jpg|jpeg|webp|gif|ico|avif)$ {++ expires 1y;++ add_header Cache-Control "public, immutable";++ access_log off;++ }++++ # --- Custom 404 ---++ error_page 404 /404.html;++ location = /404.html {++ internal;++ }++++ # --- Security headers ---++ add_header X-Frame-Options "SAMEORIGIN" always;++ add_header X-Content-Type-Options "nosniff" always;++ add_header Referrer-Policy "strict-origin-when-cross-origin" always;++}
new file mode 100755
new file mode 100755
@@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+# deploy.sh — Build & deploy alexfrison.net to Nginx static hosting
+# Usage: ./deploy/deploy.sh [--skip-build]
+# Requirements on server: git, node >=18, npm, nginx
+
+set -euo pipefail
+
+REPO_URL="[email protected]:HoboStreamer/AFResume.git"
+SITE_DIR="/var/www/alexfrison.net"
+NGINX_CONF="/etc/nginx/sites-available/alexfrison.net"
+NGINX_ENABLED="/etc/nginx/sites-enabled/alexfrison.net"
+DOMAIN="alexfrison.net"
+
+# ── Helper ────────────────────────────────────────────────────────────────────
+info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
+ok() { echo -e "\033[1;32m[OK]\033[0m $*"; }
+error() { echo -e "\033[1;31m[ERROR]\033[0m $*" >&2; exit 1; }
+
+# ── 1. Clone or pull ──────────────────────────────────────────────────────────
+if [[ -d "$SITE_DIR/.git" ]]; then
+ info "Pulling latest from origin/main..."
+ git -C "$SITE_DIR" pull origin main
+else
+ info "Cloning $REPO_URL → $SITE_DIR..."
+ sudo mkdir -p "$SITE_DIR"
+ sudo chown "$USER":"$USER" "$SITE_DIR"
+ git clone "$REPO_URL" "$SITE_DIR"
+fi
+
+# ── 2. Install deps & build ───────────────────────────────────────────────────
+if [[ "${1:-}" != "--skip-build" ]]; then
+ info "Installing npm dependencies..."
+ npm --prefix "$SITE_DIR" ci --prefer-offline
+
+ info "Building Astro site..."
+ npm --prefix "$SITE_DIR" run build
+
+ ok "Build complete → $SITE_DIR/dist"
+fi
+
+# ── 3. Install nginx config ───────────────────────────────────────────────────
+if [[ ! -f "$NGINX_CONF" ]]; then
+ info "Installing nginx config..."
+ sudo cp "$SITE_DIR/deploy/nginx.conf" "$NGINX_CONF"
+ sudo ln -sf "$NGINX_CONF" "$NGINX_ENABLED"
+ ok "Nginx config installed."
+else
+ info "Nginx config already present at $NGINX_CONF — skipping copy."
+ info "To update it manually: sudo cp $SITE_DIR/deploy/nginx.conf $NGINX_CONF"
+fi
+
+# ── 4. Test & reload nginx ────────────────────────────────────────────────────
+info "Testing nginx config..."
+sudo nginx -t
+
+info "Reloading nginx..."
+sudo systemctl reload nginx
+ok "Nginx reloaded."
+
+# ── 5. SSL reminder ───────────────────────────────────────────────────────────
+if [[ ! -d "/etc/letsencrypt/live/$DOMAIN" ]]; then
+ echo ""
+ echo " ┌─────────────────────────────────────────────────────────┐"
+ echo " │ SSL cert not found. Run certbot to finish setup: │"
+ echo " │ │"
+ echo " │ sudo apt install certbot python3-certbot-nginx │"
+ echo " │ sudo certbot --nginx -d $DOMAIN -d www.$DOMAIN │"
+ echo " └─────────────────────────────────────────────────────────┘"
+ echo ""
+fi
+
+ok "Deploy complete. Visit https://$DOMAIN"
new file mode 100644
new file mode 100644
@@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name alexfrison.net www.alexfrison.net;
+
+ # Redirect HTTP → HTTPS (remove this block if not using SSL)
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name alexfrison.net www.alexfrison.net;
+
+ # --- SSL (certbot will fill these in) ---
+ ssl_certificate /etc/letsencrypt/live/alexfrison.net/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/alexfrison.net/privkey.pem;
+ include /etc/letsencrypt/options-ssl-nginx.conf;
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
+
+ # --- Root ---
+ root /var/www/alexfrison.net/dist;
+ index index.html;
+
+ # --- Gzip ---
+ gzip on;
+ gzip_vary on;
+ gzip_proxied any;
+ gzip_comp_level 6;
+ gzip_types text/plain text/css text/xml application/json application/javascript
+ application/xml+rss application/atom+xml image/svg+xml;
+
+ # --- Astro static output: try file, then .html, then 404 ---
+ location / {
+ try_files $uri $uri/ $uri.html =404;
+ }
+
+ # --- Long-lived cache for hashed assets ---
+ location ~* \.(js|css|woff2?|ttf|eot|otf|svg|png|jpg|jpeg|webp|gif|ico|avif)$ {
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ access_log off;
+ }
+
+ # --- Custom 404 ---
+ error_page 404 /404.html;
+ location = /404.html {
+ internal;
+ }
+
+ # --- Security headers ---
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+}