From 7d5f0920b7c2144704082312cd4a5b5ad1f83bdb Mon Sep 17 00:00:00 2001 From: Timothy Kim Date: Fri, 13 Mar 2026 17:00:59 -0400 Subject: [PATCH] replace per-app deploy scripts with generic deploy.sh Dispatch now validates the command format and routes to a single deploy.sh that handles any app. This fixes first-deploy failures for new apps (dispatch no longer needs a static case list) and simplifies new-app.sh (no deploy script or dispatch update needed). Also adds input validation to new-app.sh, set -euo pipefail to deploy scripts, and dnf module reset before nodejs install. --- README.md | 18 +++++++----------- scripts/deploy-dispatch.sh | 15 ++++++--------- scripts/deploy-nginx.sh | 2 -- scripts/deploy-timothykim.sh | 2 -- scripts/deploy.sh | 8 ++++++++ scripts/new-app.sh | 19 ++++++------------- setup.sh | 12 ++++++++---- 7 files changed, 35 insertions(+), 41 deletions(-) delete mode 100755 scripts/deploy-nginx.sh delete mode 100755 scripts/deploy-timothykim.sh create mode 100755 scripts/deploy.sh diff --git a/README.md b/README.md index c9e9001..8aa873f 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,8 @@ docker/ # One directory per app, each with a compose.yml nginx/ # Nginx Proxy Manager (reverse proxy + TLS) timothykim.net/ # timothykim.net static site scripts/ - deploy-dispatch.sh # SSH command dispatcher (routes to per-app deploy scripts) - deploy-nginx.sh # Deploy script for nginx - deploy-timothykim.sh # Deploy script for timothykim.net + deploy-dispatch.sh # SSH command dispatcher (validates and routes deploy commands) + deploy.sh # Generic deploy script (git pull + docker compose up) new-app.sh # Scaffolding script to add a new app setup.sh # One-time server provisioning script .gitea/workflows/ # Per-app deploy workflows triggered by path changes @@ -43,16 +42,15 @@ base64 /path/to/git-crypt-key ## How deploys work -Each app has three components: +Each app has two components: -1. **Deploy script** (`scripts/deploy-.sh`) -- pulls the latest repo - changes, then runs `docker compose pull && up -d` for that app. -2. **Gitea Actions workflow** (`.gitea/workflows/deploy-.yml`) -- triggers +1. **Gitea Actions workflow** (`.gitea/workflows/deploy-.yml`) -- triggers on pushes to `main` when files under `docker//` change. SSHes into the server as the `deploy` user to trigger the deploy. -3. **SSH dispatcher** (`scripts/deploy-dispatch.sh`) -- the `deploy` user's +2. **SSH dispatcher** (`scripts/deploy-dispatch.sh`) -- the `deploy` user's `authorized_keys` is locked to this script via a `command=` directive. It - reads `SSH_ORIGINAL_COMMAND` to route to the correct per-app deploy script. + validates the command and runs `scripts/deploy.sh`, which pulls the latest + repo changes and runs `docker compose pull && up -d` for that app. This means: @@ -72,9 +70,7 @@ This creates: - `docker//compose.yml` -- a starter compose file on the `shared` network -- `scripts/deploy-.sh` -- the deploy script - `.gitea/workflows/deploy-.yml` -- the Gitea Actions workflow -- A new case in `scripts/deploy-dispatch.sh` After running the script: diff --git a/scripts/deploy-dispatch.sh b/scripts/deploy-dispatch.sh index 9d9dea6..7df1edc 100755 --- a/scripts/deploy-dispatch.sh +++ b/scripts/deploy-dispatch.sh @@ -1,12 +1,9 @@ #!/bin/bash set -euo pipefail -case "$SSH_ORIGINAL_COMMAND" in - deploy-nginx) sudo /opt/hantim/scripts/deploy-nginx.sh ;; - deploy-timothykim) sudo /opt/hantim/scripts/deploy-timothykim.sh ;; - *) - echo "Unknown command: $SSH_ORIGINAL_COMMAND" - echo "Available: deploy-nginx, deploy-timothykim" - exit 1 - ;; -esac +if [[ "$SSH_ORIGINAL_COMMAND" =~ ^deploy-[a-zA-Z0-9._-]+$ ]]; then + sudo /opt/hantim/scripts/deploy.sh "$SSH_ORIGINAL_COMMAND" +else + echo "Unknown command: $SSH_ORIGINAL_COMMAND" + exit 1 +fi diff --git a/scripts/deploy-nginx.sh b/scripts/deploy-nginx.sh deleted file mode 100755 index 30dd3a1..0000000 --- a/scripts/deploy-nginx.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -cd /opt/hantim && git pull && cd docker/nginx && docker compose pull && docker compose up -d diff --git a/scripts/deploy-timothykim.sh b/scripts/deploy-timothykim.sh deleted file mode 100755 index 799b7f5..0000000 --- a/scripts/deploy-timothykim.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -cd /opt/hantim && git pull && cd docker/timothykim.net && docker compose pull && docker compose up -d diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100755 index 0000000..d461155 --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail +APP="${1#deploy-}" +cd /opt/hantim +git pull +cd "docker/$APP" +docker compose pull +docker compose up -d diff --git a/scripts/new-app.sh b/scripts/new-app.sh index 3ee7939..8683cdf 100755 --- a/scripts/new-app.sh +++ b/scripts/new-app.sh @@ -8,6 +8,12 @@ if [ -z "${1:-}" ]; then fi APP="$1" + +if ! [[ "$APP" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then + echo "Error: app name must be alphanumeric (hyphens, dots, underscores allowed)." + exit 1 +fi + REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" if [ -d "$REPO_ROOT/docker/$APP" ]; then @@ -30,17 +36,6 @@ networks: external: true EOF -echo "Creating scripts/deploy-$APP.sh..." -cat > "$REPO_ROOT/scripts/deploy-$APP.sh" < "$REPO_ROOT/.gitea/workflows/deploy-$APP.yml" <<'OUTER' @@ -69,9 +64,7 @@ sed -i "s/APP_PLACEHOLDER/$APP/g" "$REPO_ROOT/.gitea/workflows/deploy-$APP.yml" echo "" echo "Done! Files created:" echo " - docker/$APP/compose.yml" -echo " - scripts/deploy-$APP.sh" echo " - .gitea/workflows/deploy-$APP.yml" -echo " - Updated scripts/deploy-dispatch.sh" echo "" echo "Next steps:" echo " 1. Edit docker/$APP/compose.yml to fit your app" diff --git a/setup.sh b/setup.sh index bc8229a..bb7e9d3 100755 --- a/setup.sh +++ b/setup.sh @@ -33,6 +33,7 @@ dnf upgrade -y echo "==> Installing dependencies..." dnf install -y git-crypt +dnf module reset -y nodejs dnf module install -y nodejs:20/common BW_CLI="$(npm config get prefix)/bin/bw" @@ -44,7 +45,8 @@ fi # --- Unlock git-crypt via Bitwarden --- echo "==> Restoring git-tracked files..." -cd "$REPO_DIR" && git checkout -- . +cd "$REPO_DIR" +git checkout -- . echo "==> Unlocking git-crypt via Bitwarden..." echo " Log in to Bitwarden when prompted." @@ -89,7 +91,7 @@ chown -R deploy:deploy /home/deploy/.ssh echo "==> Configuring sudo for deploy user..." cat > /etc/sudoers.d/deploy < Logging into Gitea registry..." echo "Run manually: docker login git.timothykim.net" echo "==> Starting services..." -cd "$REPO_DIR/docker/nginx" && docker compose up -d -cd "$REPO_DIR/docker/timothykim.net" && docker compose up -d +cd "$REPO_DIR/docker/nginx" +docker compose up -d +cd "$REPO_DIR/docker/timothykim.net" +docker compose up -d echo "==> Done. Don't forget to:" echo " 1. Add the deploy SSH public key to /home/deploy/.ssh/authorized_keys"