feat(deploy): publish-images.sh one-command ghcr upload
GHCR_TOKEN=ghp_xxx scripts/publish-images.sh 0.1.0 — logs into ghcr.io as alezmad and pushes all 3 claudemesh-* images (broker + web + migrate, multi-arch) via the existing build-multiarch.sh. Supports --dry-run that prints what would publish without logging in or pushing. When user drops their GHCR PAT, shipping the 0.1.0 image tag is one command. Also documents post-trim image sizes in DEPLOY.md Step 2 (broker 341MB, migrate 653MB, web 250MB). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
20
DEPLOY.md
20
DEPLOY.md
@@ -49,6 +49,18 @@ Three images ship: `broker`, `web`, `migrate`. Use the multi-arch build script
|
|||||||
it produces both `linux/amd64` (VPS) and `linux/arm64` (Apple Silicon devs)
|
it produces both `linux/amd64` (VPS) and `linux/arm64` (Apple Silicon devs)
|
||||||
manifests so nobody hits QEMU emulation at runtime.
|
manifests so nobody hits QEMU emulation at runtime.
|
||||||
|
|
||||||
|
### Fast path (ghcr.io/alezmad)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
GHCR_TOKEN=ghp_xxx ./scripts/publish-images.sh 0.1.0
|
||||||
|
./scripts/publish-images.sh 0.1.0 --dry-run # preview without pushing
|
||||||
|
```
|
||||||
|
|
||||||
|
One command logs in + builds + pushes all 3 images to
|
||||||
|
`ghcr.io/alezmad/claudemesh-{broker,web,migrate}` for both archs.
|
||||||
|
|
||||||
|
### Manual path (any registry)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Login to your registry
|
# Login to your registry
|
||||||
docker login <REGISTRY_HOST> -u <USERNAME>
|
docker login <REGISTRY_HOST> -u <USERNAME>
|
||||||
@@ -65,6 +77,14 @@ scripts/build-multiarch.sh ghcr.io/myorg latest # → ghcr.io/myorg/clau
|
|||||||
The script tags each image with both `<TAG>` and `:latest`. Builds in ~5-8 min
|
The script tags each image with both `<TAG>` and `:latest`. Builds in ~5-8 min
|
||||||
on Mac M-series (arm64 native is fast, amd64 via emulation is the slow leg).
|
on Mac M-series (arm64 native is fast, amd64 via emulation is the slow leg).
|
||||||
|
|
||||||
|
Image sizes (arm64, after the `pnpm deploy` trim — amd64 is similar):
|
||||||
|
|
||||||
|
| image | size | contains |
|
||||||
|
| ------------------- | ------- | -------------------------------------- |
|
||||||
|
| claudemesh-broker | ~341 MB | bun runtime, prod deps only |
|
||||||
|
| claudemesh-migrate | ~653 MB | bun runtime + drizzle-kit (devDep) |
|
||||||
|
| claudemesh-web | ~250 MB | node + next.js standalone output |
|
||||||
|
|
||||||
> **Mac Docker Desktop note**: if amd64 builds fail with `Input/output error`
|
> **Mac Docker Desktop note**: if amd64 builds fail with `Input/output error`
|
||||||
> during `apt-get install`, enable **Settings → General → Use Rosetta for x86/amd64
|
> during `apt-get install`, enable **Settings → General → Use Rosetta for x86/amd64
|
||||||
> emulation** (not QEMU). QEMU has known I/O stability issues on macOS; Rosetta
|
> emulation** (not QEMU). QEMU has known I/O stability issues on macOS; Rosetta
|
||||||
|
|||||||
69
scripts/publish-images.sh
Executable file
69
scripts/publish-images.sh
Executable file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# One-command publish of all 3 claudemesh images to ghcr.io/alezmad.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# GHCR_TOKEN=ghp_xxx ./scripts/publish-images.sh [TAG]
|
||||||
|
# GHCR_TOKEN=ghp_xxx ./scripts/publish-images.sh 0.1.0
|
||||||
|
# ./scripts/publish-images.sh 0.1.0 --dry-run # no login, no push
|
||||||
|
#
|
||||||
|
# Produces (all multi-arch: linux/amd64 + linux/arm64):
|
||||||
|
# ghcr.io/alezmad/claudemesh-broker:<TAG> + :latest
|
||||||
|
# ghcr.io/alezmad/claudemesh-web:<TAG> + :latest
|
||||||
|
# ghcr.io/alezmad/claudemesh-migrate:<TAG> + :latest
|
||||||
|
#
|
||||||
|
# Prereqs:
|
||||||
|
# - docker buildx (Docker Desktop on Mac ships with it)
|
||||||
|
# - GHCR_TOKEN env var: a GitHub personal access token with `write:packages`
|
||||||
|
# scope. Create at https://github.com/settings/tokens
|
||||||
|
#
|
||||||
|
# Image sizes after the pnpm deploy trim (arm64):
|
||||||
|
# claudemesh-broker ~341 MB
|
||||||
|
# claudemesh-migrate ~653 MB
|
||||||
|
# claudemesh-web (next.js standalone, ~250 MB)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TAG="${1:-latest}"
|
||||||
|
DRY_RUN=false
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--dry-run) DRY_RUN=true ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
REGISTRY="ghcr.io/alezmad"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
if $DRY_RUN; then
|
||||||
|
echo "=== DRY RUN — no login, no push ==="
|
||||||
|
echo ""
|
||||||
|
echo "Would run:"
|
||||||
|
echo " echo \$GHCR_TOKEN | docker login ghcr.io -u alezmad --password-stdin"
|
||||||
|
echo " ${SCRIPT_DIR}/build-multiarch.sh ${REGISTRY} ${TAG}"
|
||||||
|
echo ""
|
||||||
|
echo "Images that would be published:"
|
||||||
|
echo " ${REGISTRY}/claudemesh-broker:${TAG} + :latest"
|
||||||
|
echo " ${REGISTRY}/claudemesh-web:${TAG} + :latest"
|
||||||
|
echo " ${REGISTRY}/claudemesh-migrate:${TAG} + :latest"
|
||||||
|
echo " (platforms: linux/amd64, linux/arm64)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${GHCR_TOKEN:-}" ]]; then
|
||||||
|
echo "error: GHCR_TOKEN env var is required." >&2
|
||||||
|
echo "Create a GitHub PAT with 'write:packages' scope at" >&2
|
||||||
|
echo " https://github.com/settings/tokens" >&2
|
||||||
|
echo "Then re-run: GHCR_TOKEN=ghp_xxx $0 ${TAG}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "→ logging in to ghcr.io as alezmad"
|
||||||
|
echo "$GHCR_TOKEN" | docker login ghcr.io -u alezmad --password-stdin
|
||||||
|
|
||||||
|
echo "→ building + pushing ${REGISTRY}/claudemesh-{broker,web,migrate}:${TAG}"
|
||||||
|
"${SCRIPT_DIR}/build-multiarch.sh" "${REGISTRY}" "${TAG}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✓ published. pull with:"
|
||||||
|
echo " docker pull ${REGISTRY}/claudemesh-broker:${TAG}"
|
||||||
Reference in New Issue
Block a user