Add org-agenda-api container builds and fly.io deployment

Consolidates container builds from colonelpanic-org-agenda-api repo:
- Add org-agenda-api input to nixos flake
- Add container-colonelpanic and container-kat package outputs
- Add org-agenda-api cachix as substituter
- Add org-agenda-api devShell for deployment work

New org-agenda-api directory contains:
- container.nix: Container build logic using mkContainer
- configs/: Instance configs (custom-config.el, fly.toml, secrets)
- deploy.sh: Fly.io deployment script
- secrets.nix: agenix secret declarations

Build with: nix build .#container-colonelpanic
Deploy with: cd org-agenda-api && ./deploy.sh colonelpanic

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-28 14:24:41 -08:00
parent ccd63ba066
commit 504ec1a105
19 changed files with 1187 additions and 50 deletions

140
org-agenda-api/deploy.sh Executable file
View File

@@ -0,0 +1,140 @@
#!/usr/bin/env bash
set -euo pipefail
# Deploy customized org-agenda-api container to Fly.io
# Usage: ./deploy.sh <instance> [flyctl deploy args...]
# Example: ./deploy.sh colonelpanic
# ./deploy.sh kat
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
NIXOS_DIR="$SCRIPT_DIR/../nixos"
cd "$SCRIPT_DIR"
# Parse instance argument
INSTANCE="${1:-}"
if [[ -z "$INSTANCE" ]]; then
echo "Usage: $0 <instance> [flyctl deploy args...]"
echo "Available instances:"
for dir in configs/*/; do
echo " - $(basename "$dir")"
done
exit 1
fi
shift
CONFIG_DIR="$SCRIPT_DIR/configs/$INSTANCE"
if [[ ! -d "$CONFIG_DIR" ]]; then
echo "Error: Instance '$INSTANCE' not found in configs/"
exit 1
fi
# Source instance configuration
if [[ -f "$CONFIG_DIR/config.env" ]]; then
source "$CONFIG_DIR/config.env"
else
echo "Error: $CONFIG_DIR/config.env not found"
exit 1
fi
echo "Deploying instance: $INSTANCE"
echo " Fly app: $FLY_APP"
# Check for uncommitted changes
if [[ -n "$(git status --porcelain)" ]]; then
echo ""
echo "WARNING: Working directory has uncommitted changes!"
echo "For reproducibility, consider committing before deploying."
echo ""
read -p "Continue anyway? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# Get input revisions for reproducibility from the nixos flake
ORG_API_NODE=$(jq -r '.nodes.root.inputs."org-agenda-api"' "$NIXOS_DIR/flake.lock")
ORG_API_REV=$(jq -r ".nodes.\"$ORG_API_NODE\".locked.rev" "$NIXOS_DIR/flake.lock")
# For dotfiles rev, use the current git commit since we're building from local
DOTFILES_REV=$(git -C "$NIXOS_DIR/.." rev-parse HEAD)
SHORT_DOTFILES="${DOTFILES_REV:0:7}"
SHORT_ORG_API="${ORG_API_REV:0:7}"
echo "Versions:"
echo " org-agenda-api: $ORG_API_REV"
echo " dotfiles: $DOTFILES_REV"
# Build container from nixos flake for this instance
# Use --refresh to ensure we're not using stale cached builds
echo "Building container from flake..."
nix build "$NIXOS_DIR#container-$INSTANCE" -o "result-container-$INSTANCE" --refresh
# Load into Docker
echo "Loading container into Docker..."
LOADED_IMAGE=$(docker load < "result-container-$INSTANCE" 2>&1 | grep -oP 'Loaded image: \K.*')
echo "Loaded: $LOADED_IMAGE"
# Tag with both versions for full reproducibility
# Format: api-<org-api-rev>-cfg-<dotfiles-rev>
IMAGE_TAG="api-${SHORT_ORG_API}-cfg-${SHORT_DOTFILES}"
IMAGE_NAME="registry.fly.io/$FLY_APP:$IMAGE_TAG"
echo "Tagging as $IMAGE_NAME..."
docker tag "$LOADED_IMAGE" "$IMAGE_NAME"
echo "Pushing to Fly.io registry..."
flyctl auth docker
docker push "$IMAGE_NAME"
# Decrypt secrets
echo "Decrypting secrets..."
IDENTITY=""
for key_type in ed25519 rsa; do
if [[ -f "$HOME/.ssh/id_${key_type}" ]]; then
IDENTITY="$HOME/.ssh/id_${key_type}"
break
fi
done
if [[ -z "$IDENTITY" ]]; then
echo "Error: No SSH identity found" >&2
exit 1
fi
GIT_SSH_KEY=$(age -d -i "$IDENTITY" "$CONFIG_DIR/secrets/git-ssh-key.age")
AUTH_PASSWORD=$(age -d -i "$IDENTITY" "$CONFIG_DIR/secrets/auth-password.age")
echo "Setting Fly.io secrets..."
SECRET_ARGS=(
"GIT_SSH_PRIVATE_KEY=$GIT_SSH_KEY"
"AUTH_USER=$AUTH_USER"
"AUTH_PASSWORD=$AUTH_PASSWORD"
"GIT_USER_EMAIL=$GIT_USER_EMAIL"
"GIT_USER_NAME=$GIT_USER_NAME"
)
# Use GIT_SYNC_REPOSITORIES (multi-repo) or GIT_SYNC_REPOSITORY (single repo)
if [[ -n "${GIT_SYNC_REPOSITORIES:-}" ]]; then
SECRET_ARGS+=("GIT_SYNC_REPOSITORIES=$GIT_SYNC_REPOSITORIES")
elif [[ -n "${GIT_SYNC_REPOSITORY:-}" ]]; then
SECRET_ARGS+=("GIT_SYNC_REPOSITORY=$GIT_SYNC_REPOSITORY")
else
echo "Error: Neither GIT_SYNC_REPOSITORIES nor GIT_SYNC_REPOSITORY set in config.env"
exit 1
fi
flyctl secrets set "${SECRET_ARGS[@]}" --stage -a "$FLY_APP"
echo "Deploying $IMAGE_NAME..."
flyctl deploy --image "$IMAGE_NAME" -c "$CONFIG_DIR/fly.toml" "$@"
# Cleanup
rm -f "result-container-$INSTANCE"
echo ""
echo "Done! Deployed to $FLY_APP"
echo " Image: $IMAGE_NAME"
echo " org-agenda-api: $ORG_API_REV"
echo " dotfiles: $DOTFILES_REV"