Merge pull request #9 from madhura68/feat/deploy-script
feat(deploy): bin/deploy-to-nas.sh — één-commando Mac→NAS redeploy
This commit is contained in:
commit
3e3d0e5b10
4 changed files with 157 additions and 0 deletions
16
.env.deploy.example
Normal file
16
.env.deploy.example
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# .env.deploy — config voor bin/deploy-to-nas.sh
|
||||
# Kopieer naar .env.deploy en pas aan; staat in .gitignore.
|
||||
|
||||
# SSH-target voor de NAS. Moet werkend zijn met SSH-key (geen password).
|
||||
NAS_HOST=admin@nas.local
|
||||
|
||||
# Pad op de NAS waar tarball + compose + .env terechtkomen.
|
||||
# Default: /share/Agent/scrum4me-agent-runner
|
||||
# NAS_REMOTE_DIR=/share/Agent/scrum4me-agent-runner
|
||||
|
||||
# Build-args (overrides). Standaard:
|
||||
# MCP_GIT_REF=main — pin een commit in productie indien gewenst
|
||||
# CLAUDE_CODE_VERSION=latest — pin een claude-code release indien gewenst
|
||||
# AGENT_UID=1000, AGENT_GID=1000
|
||||
# MCP_GIT_REF=main
|
||||
# CLAUDE_CODE_VERSION=latest
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,5 +1,6 @@
|
|||
# Secrets
|
||||
.env
|
||||
.env.deploy
|
||||
*.env.local
|
||||
|
||||
# Local dev overrides (niet committen, per ontwikkelaar)
|
||||
|
|
|
|||
28
README.md
28
README.md
|
|
@ -117,6 +117,34 @@ docker compose logs -f
|
|||
> mapt deze stack standaard `18080:8080`. Override via
|
||||
> `AGENT_HEALTH_PORT_HOST` in `.env` als je een andere host-poort wilt.
|
||||
|
||||
## Snelle redeploy — `bin/deploy-to-nas.sh`
|
||||
|
||||
Voor een **bestaande deploy** die je opnieuw wil bouwen + deployen
|
||||
(bijvoorbeeld na een merge in `scrum4me-mcp` of een aanpassing aan
|
||||
`CLAUDE.md`):
|
||||
|
||||
```bash
|
||||
# Eenmalig: NAS-target instellen
|
||||
cp .env.deploy.example .env.deploy
|
||||
vi .env.deploy # zet NAS_HOST=admin@<nas>
|
||||
|
||||
# Daarna: één commando voor de hele cyclus
|
||||
bin/deploy-to-nas.sh
|
||||
```
|
||||
|
||||
Het script doet:
|
||||
|
||||
1. `docker buildx build --platform linux/amd64 --load`
|
||||
2. `docker save | gzip → scrum4me-agent-runner-amd64.tar.gz`
|
||||
3. `scp` van tarball + `docker-compose.yml` + (eerste keer) `.env` naar NAS
|
||||
4. `ssh` op NAS: `docker load` + sanity-check op `.env` + `docker compose up -d --force-recreate`
|
||||
5. `docker compose logs -f` — lokaal-volgbaar terwijl pre-flight + eerste batch starten
|
||||
|
||||
`.env` op de NAS wordt **niet** overschreven als 'ie er al staat. Bij een
|
||||
verse NAS-installatie wordt 'ie wél geüpload + ge-sed't (NAS_BASE,
|
||||
AGENT_UID, etc.). Voor de **eerste deploy** of een schoon volume zie de
|
||||
volledige procedure hieronder.
|
||||
|
||||
## Deploy — cross-build vanaf Mac (Apple Silicon → amd64-NAS)
|
||||
|
||||
Alternatief voor de in-place build hierboven. Bouw de image op je Mac voor
|
||||
|
|
|
|||
112
bin/deploy-to-nas.sh
Executable file
112
bin/deploy-to-nas.sh
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/env bash
|
||||
# deploy-to-nas.sh — Mac → NAS cross-build deploy in één commando.
|
||||
#
|
||||
# Voert in volgorde uit:
|
||||
# 1. docker buildx build (linux/amd64, --load)
|
||||
# 2. docker save | gzip → scrum4me-agent-runner-amd64.tar.gz
|
||||
# 3. scp tarball + docker-compose.yml + (eerste keer) .env naar NAS
|
||||
# 4. ssh: docker load + sed-patch .env paths (eerste keer) + compose up --force-recreate
|
||||
# 5. ssh: docker compose logs -f voor verificatie
|
||||
#
|
||||
# Gebruik:
|
||||
# bin/deploy-to-nas.sh # gebruikt env vars uit .env.deploy
|
||||
# NAS_HOST=admin@nas bin/deploy-to-nas.sh
|
||||
#
|
||||
# Vereisten:
|
||||
# - docker buildx geïnstalleerd
|
||||
# - .env aanwezig in repo-root (deze wordt naar NAS gestuurd op eerste run)
|
||||
# - .env.deploy met NAS_HOST + NAS_REMOTE_DIR (optioneel — anders prompted)
|
||||
# - SSH-key access naar de NAS (geen password-prompts)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
# ----- config -----------------------------------------------------------
|
||||
if [[ -f .env.deploy ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source .env.deploy
|
||||
fi
|
||||
|
||||
: "${NAS_HOST:?NAS_HOST not set — bv. admin@nas.local. Zet 'm in .env.deploy of als env-var.}"
|
||||
: "${NAS_REMOTE_DIR:=/share/Agent/scrum4me-agent-runner}"
|
||||
: "${IMAGE_TAG:=scrum4me-agent-runner:local}"
|
||||
: "${TARBALL:=scrum4me-agent-runner-amd64.tar.gz}"
|
||||
: "${MCP_GIT_REF:=main}"
|
||||
: "${CLAUDE_CODE_VERSION:=latest}"
|
||||
: "${AGENT_UID:=1000}"
|
||||
: "${AGENT_GID:=1000}"
|
||||
|
||||
log() { echo "[deploy-to-nas] $*"; }
|
||||
|
||||
# ----- pre-flight -------------------------------------------------------
|
||||
if [[ ! -f .env ]]; then
|
||||
log "FAIL: .env ontbreekt in repo-root. Maak 'm aan via: cp .env.example .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ----- 1. buildx --------------------------------------------------------
|
||||
log "1/5 docker buildx build (linux/amd64, MCP_GIT_REF=$MCP_GIT_REF)"
|
||||
docker buildx build \
|
||||
--platform linux/amd64 \
|
||||
--build-arg "MCP_GIT_REF=${MCP_GIT_REF}" \
|
||||
--build-arg "CLAUDE_CODE_VERSION=${CLAUDE_CODE_VERSION}" \
|
||||
--build-arg "AGENT_UID=${AGENT_UID}" \
|
||||
--build-arg "AGENT_GID=${AGENT_GID}" \
|
||||
-t "$IMAGE_TAG" \
|
||||
--load \
|
||||
.
|
||||
|
||||
# ----- 2. tarball -------------------------------------------------------
|
||||
log "2/5 docker save | gzip → $TARBALL"
|
||||
docker save "$IMAGE_TAG" | gzip > "$TARBALL"
|
||||
ls -lh "$TARBALL"
|
||||
|
||||
# ----- 3. scp -----------------------------------------------------------
|
||||
log "3/5 scp tarball + compose naar $NAS_HOST:$NAS_REMOTE_DIR"
|
||||
ssh "$NAS_HOST" "mkdir -p '$NAS_REMOTE_DIR'"
|
||||
|
||||
# Check of er al een .env op de NAS staat. Zo niet: stuur de Mac-versie en
|
||||
# patch hem. Zo wel: laat 'm met rust (kan NAS-specifiek aangepast zijn).
|
||||
if ssh "$NAS_HOST" "test -f '$NAS_REMOTE_DIR/.env'" 2>/dev/null; then
|
||||
log " (.env bestaat al op NAS — niet overschreven)"
|
||||
else
|
||||
log " geen .env op NAS, kopiëren + patchen"
|
||||
scp .env "$NAS_HOST:$NAS_REMOTE_DIR/.env"
|
||||
ssh "$NAS_HOST" "
|
||||
cd '$NAS_REMOTE_DIR'
|
||||
chmod 600 .env
|
||||
sed -i \\
|
||||
-e 's|^NAS_BASE=.*|NAS_BASE=/share/Agent|' \\
|
||||
-e 's|^AGENT_BASE=.*|AGENT_BASE=/share/Agent|' \\
|
||||
-e 's|^AGENT_PLATFORM=.*|AGENT_PLATFORM=linux/amd64|' \\
|
||||
-e 's|^AGENT_UID=.*|AGENT_UID=${AGENT_UID}|' \\
|
||||
-e 's|^AGENT_GID=.*|AGENT_GID=${AGENT_GID}|' \\
|
||||
-e 's|^AGENT_HEALTH_PORT_HOST=.*|AGENT_HEALTH_PORT_HOST=18080|' \\
|
||||
.env
|
||||
"
|
||||
fi
|
||||
|
||||
scp "$TARBALL" docker-compose.yml package.json README.md \
|
||||
"$NAS_HOST:$NAS_REMOTE_DIR/"
|
||||
|
||||
# ----- 4. load + restart ------------------------------------------------
|
||||
log "4/5 docker load + compose up --force-recreate op NAS"
|
||||
ssh "$NAS_HOST" "
|
||||
set -eu
|
||||
source /etc/profile
|
||||
cd '$NAS_REMOTE_DIR'
|
||||
|
||||
# Sanity: env-vars die check-tokens.sh nodig heeft
|
||||
grep -qE '^(CLAUDE_CODE_OAUTH_TOKEN|ANTHROPIC_API_KEY)=' .env || { echo 'FAIL: anthropic credential ontbreekt in .env'; exit 1; }
|
||||
grep -qE '^SCRUM4ME_TOKEN=' .env || { echo 'FAIL: SCRUM4ME_TOKEN ontbreekt in .env'; exit 1; }
|
||||
grep -qE '^DATABASE_URL=' .env || { echo 'FAIL: DATABASE_URL ontbreekt in .env'; exit 1; }
|
||||
|
||||
gunzip -c '$TARBALL' | docker load
|
||||
docker compose up -d --force-recreate
|
||||
"
|
||||
|
||||
# ----- 5. tail logs ------------------------------------------------------
|
||||
log "5/5 docker compose logs (Ctrl-C om te stoppen)"
|
||||
ssh "$NAS_HOST" "cd '$NAS_REMOTE_DIR' && docker compose logs -f --tail=50"
|
||||
Loading…
Add table
Add a link
Reference in a new issue