From 5b25211618cddf6a36b9142b9597a9bba7f79939 Mon Sep 17 00:00:00 2001 From: Matthew Binning Date: Thu, 1 Jan 2026 16:44:54 -0800 Subject: [PATCH] feat: Add deployment to a staging environment Added staging.nginx.nix modeled on prod.nginx.nix, configuring nginx as a local staging server. Updated deploy.sh to target either staging or prod over SSH. Consolidated shared configuration between the two nginx nix files and between the staging and prod deploy paths in deploy.sh. --- deploy.sh | 99 ++++++++++++++++++++++++++++++++----- nginx.nix => prod.nginx.nix | 11 +++++ staging.nginx.nix | 56 +++++++++++++++++++++ 3 files changed, 155 insertions(+), 11 deletions(-) rename nginx.nix => prod.nginx.nix (92%) create mode 100644 staging.nginx.nix diff --git a/deploy.sh b/deploy.sh index daf400e..a6b2f21 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,15 +1,92 @@ #!/usr/bin/env sh -sudo cp -rt /srv/www/binning.net \ - blog \ - includes \ - index.html \ - blog.html \ - resume.html \ - style.css \ - 404.html +set -e -sudo chown -R nginx:nginx /srv/www/binning.net/ +# Usage information +usage() { + printf "Usage: %s [staging|prod]\n\n staging - Deploy to local staging environment (/srv/www/stage.binning.net)\n prod - Deploy to production server via SSH (www.binning.net)\n\nExample:\n %s staging\n %s prod\n" "$0" "$0" "$0" + exit 1 +} -sudo cp -t /etc/nixos/ \ - nginx.nix \ No newline at end of file +# Check if argument provided +if [ $# -eq 0 ]; then + printf "Error: No environment specified\n" + usage +fi + +ENV=$1 + +case $ENV in + staging) + printf "Deploying to STAGING environment...\n" + + STAGING_PATH="/srv/www/stage.binning.net" + + # Create staging directory if it doesn't exist + sudo mkdir -p ${STAGING_PATH} + + # Deploy website files via rsync + printf "Deploying website files...\n" + sudo rsync -av --delete \ + blog \ + includes \ + index.html \ + blog.html \ + resume.html \ + style.css \ + 404.html \ + ${STAGING_PATH}/ + + # Set proper ownership + sudo chown -R nginx:nginx ${STAGING_PATH}/ + + # Copy nginx config + sudo cp -t /etc/nixos/ staging.nginx.nix + + printf "✓ Staging deployment complete!\n Files deployed to: %s\n Nginx config: /etc/nixos/staging.nginx.nix\n\nTo activate, update your NixOS configuration to import staging.nginx.nix\nand run: sudo nixos-rebuild switch\n" "${STAGING_PATH}" + ;; + + prod) + printf "Deploying to PRODUCTION environment...\n" + + # SSH details + REMOTE_HOST="binning.net" + REMOTE_USER="matthew.binning" + REMOTE_PATH="/srv/www/binning.net" + REMOTE_NIXOS="/etc/nixos/" + + # Check if SSH key is set up + if ! ssh -o BatchMode=yes -o ConnectTimeout=5 ${REMOTE_USER}@${REMOTE_HOST} exit 2>/dev/null; then + printf "Warning: SSH connection test failed. Ensure SSH keys are configured.\nYou may be prompted for a password.\n" + fi + + # Deploy website files via rsync over SSH + printf "Deploying website files...\n" + rsync -avz --delete \ + -e ssh \ + blog \ + includes \ + index.html \ + blog.html \ + resume.html \ + style.css \ + 404.html \ + ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/ + + # Deploy nginx configuration + printf "Deploying nginx configuration...\n" + scp prod.nginx.nix ${REMOTE_USER}@${REMOTE_HOST}:/tmp/nginx.nix + + # Set proper permissions and move config on remote server + ssh ${REMOTE_USER}@${REMOTE_HOST} "sudo mv /tmp/nginx.nix ${REMOTE_NIXOS}nginx.nix && \ + sudo chown -R nginx:nginx ${REMOTE_PATH}/ && \ + printf 'Configuration deployed. Run sudo nixos-rebuild switch to activate.\n'" + + printf "✓ Production deployment complete!\n\nSSH into %s and run: sudo nixos-rebuild switch\n" "${REMOTE_HOST}" + ;; + + *) + printf "Error: Invalid environment '%s'\n" "$ENV" + usage + ;; +esac diff --git a/nginx.nix b/prod.nginx.nix similarity index 92% rename from nginx.nix rename to prod.nginx.nix index a2f5b7d..d3f84ff 100644 --- a/nginx.nix +++ b/prod.nginx.nix @@ -59,6 +59,17 @@ in ''; }; + # Private blog articles with HTTP basic authentication + locations."/blog/private/" = { + extraConfig = '' + auth_basic "Private Articles"; + auth_basic_user_file /srv/nginx/.htpasswd; + + # Enable Server Side Includes + ssi on; + ''; + }; + # Optional: Custom 404 page extraConfig = '' error_page 404 /404.html; diff --git a/staging.nginx.nix b/staging.nginx.nix new file mode 100644 index 0000000..174a7f4 --- /dev/null +++ b/staging.nginx.nix @@ -0,0 +1,56 @@ +{ config, pkgs, lib, ... }: + +{ + services.nginx = { + enable = true; + + # Recommended settings + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + + # Virtual hosts configuration for local staging + virtualHosts = { + + # Main website - Static HTML/CSS + # Access via http://localhost or http://localhost:80 + "localhost" = { + # No SSL for local development + listen = [ + { addr = "127.0.0.1"; port = 80; } + { addr = "0.0.0.0"; port = 80; } + ]; + + root = "/srv/www/stage.binning.net"; + + locations."/" = { + index = "index.html"; + tryFiles = "$uri $uri/ =404"; + extraConfig = '' + # Enable Server Side Includes for navbar/footer includes + ssi on; + ''; + }; + + # Private blog articles with HTTP basic authentication + locations."/blog/private/" = { + extraConfig = '' + auth_basic "Private Articles"; + auth_basic_user_file /srv/nginx/.htpasswd; + + # Enable Server Side Includes + ssi on; + ''; + }; + + # Custom 404 page + extraConfig = '' + error_page 404 /404.html; + ''; + }; + }; + }; + + # Firewall - allow local HTTP access + networking.firewall.allowedTCPPorts = [ 80 ]; +}