Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
branches: [main]
workflow_dispatch:

# Images are pushed to Docker Hub (obchain219/volx-*). Requires repo secrets:
# DOCKER_USERNAME (obchain219) DOCKER_PASSWORD (Docker Hub access token)
# SERVER_SSH_KEY (+ optional SERVER_KNOWN_HOSTS)

# One deploy at a time; never cancel mid-flight (would risk a half-applied
# stack). Queued runs wait their turn.
concurrency:
Expand All @@ -22,10 +26,8 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
timeout-minutes: 30
# Only the build job pushes images; deploy needs nothing beyond read.
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
Expand All @@ -39,12 +41,11 @@ jobs:

- uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build & push ${{ matrix.svc }}
uses: docker/build-push-action@v6
Expand All @@ -53,8 +54,8 @@ jobs:
file: ${{ matrix.dockerfile }}
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/volx-${{ matrix.svc }}:latest
ghcr.io/${{ github.repository_owner }}/volx-${{ matrix.svc }}:${{ github.sha }}
${{ secrets.DOCKER_USERNAME }}/volx-${{ matrix.svc }}:latest
${{ secrets.DOCKER_USERNAME }}/volx-${{ matrix.svc }}:${{ github.sha }}
cache-from: type=gha,scope=${{ matrix.svc }}
cache-to: type=gha,mode=max,scope=${{ matrix.svc }}

Expand Down Expand Up @@ -100,14 +101,26 @@ jobs:
- name: Ship compose + deploy script, then pull & apply
env:
DEPLOY_DIR: /home/ancilar/volx-deploy
# Keeper runtime secrets — written into the server .env each deploy.
# GitHub masks these values in the logs.
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
# Pin the server's registry to whatever CI pushed to, so the compose
# default can never drift from the images that were just built.
VOLX_REGISTRY: ${{ secrets.DOCKER_USERNAME }}
run: |
ssh ssh.ancilar.com "mkdir -p $DEPLOY_DIR"
scp docker/docker-compose.prod.yml ssh.ancilar.com:"$DEPLOY_DIR/docker-compose.prod.yml"
scp docker/clickhouse-init.sql ssh.ancilar.com:"$DEPLOY_DIR/clickhouse-init.sql"
scp scripts/deploy.sh ssh.ancilar.com:"$DEPLOY_DIR/deploy.sh"
# The server already holds $DEPLOY_DIR/.env (keeper secrets), placed
# once by hand. deploy.sh pulls the freshly-pushed images and recreates
# only the services whose digest changed.
# Write the runtime .env on the server from the GitHub secrets (umask
# 077 -> 0600). docker compose auto-loads it; the keeper reads the keys.
# Docker Hub repos must be PUBLIC (no server-side login is configured).
ssh ssh.ancilar.com "umask 077; cat > $DEPLOY_DIR/.env" <<EOF
SEPOLIA_RPC_URL=$SEPOLIA_RPC_URL
PRIVATE_KEY=$PRIVATE_KEY
VOLX_REGISTRY=$VOLX_REGISTRY
EOF
ssh ssh.ancilar.com "cd $DEPLOY_DIR && chmod +x deploy.sh && VOLX_TAG=latest ./deploy.sh"

- name: Wipe SSH key
Expand Down
10 changes: 5 additions & 5 deletions docker/docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# Config — a `.env` beside this file (gitignored) or exported shell env:
# SEPOLIA_RPC_URL, PRIVATE_KEY keeper signer (required)
# TUNNEL_TOKEN only with --profile tunnel
# VOLX_REGISTRY (default ghcr.io/obchain), VOLX_TAG (default latest)
# VOLX_REGISTRY (default obchain219), VOLX_TAG (default latest)

name: volx-prod

Expand Down Expand Up @@ -79,7 +79,7 @@ services:
ingestion:
# Pre-built image pulled from the registry on the server. `build:` is kept
# for local `up --build`; on the server we only `pull` so the image wins.
image: ${VOLX_REGISTRY:-ghcr.io/obchain}/volx-ingestion:${VOLX_TAG:-latest}
image: ${VOLX_REGISTRY:-obchain219}/volx-ingestion:${VOLX_TAG:-latest}
build:
context: ..
dockerfile: crates/ingestion/Dockerfile
Expand All @@ -100,7 +100,7 @@ services:
disable: true

engine:
image: ${VOLX_REGISTRY:-ghcr.io/obchain}/volx-engine:${VOLX_TAG:-latest}
image: ${VOLX_REGISTRY:-obchain219}/volx-engine:${VOLX_TAG:-latest}
build:
context: ..
dockerfile: crates/engine/Dockerfile
Expand All @@ -124,7 +124,7 @@ services:
disable: true

api:
image: ${VOLX_REGISTRY:-ghcr.io/obchain}/volx-api:${VOLX_TAG:-latest}
image: ${VOLX_REGISTRY:-obchain219}/volx-api:${VOLX_TAG:-latest}
build:
context: ..
dockerfile: api/Dockerfile
Expand All @@ -151,7 +151,7 @@ services:
disable: true

keeper:
image: ${VOLX_REGISTRY:-ghcr.io/obchain}/volx-keeper:${VOLX_TAG:-latest}
image: ${VOLX_REGISTRY:-obchain219}/volx-keeper:${VOLX_TAG:-latest}
build:
context: ..
dockerfile: keeper/Dockerfile
Expand Down
17 changes: 9 additions & 8 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@
#
# Env (from the `.env` beside the compose file, auto-loaded by compose):
# SEPOLIA_RPC_URL, PRIVATE_KEY keeper signer (required)
# VOLX_REGISTRY (default ghcr.io/obchain), VOLX_TAG (default latest)
# VOLX_REGISTRY (default obchain219), VOLX_TAG (default latest)
# DOCKER_USERNAME, DOCKER_PASSWORD only if the Docker Hub repos are private
# TUNNEL_TOKEN only with --tunnel

set -euo pipefail

cd "$(dirname "$0")"

# Load the local .env so its values are visible to THIS script (compose reads
# it on its own; we need GHCR_TOKEN/GHCR_USER here for the optional login).
# it on its own; we need DOCKER_USERNAME/DOCKER_PASSWORD here for the login).
if [ -f .env ]; then
set -a; . ./.env; set +a
fi
Expand All @@ -31,14 +32,14 @@ DC=(docker compose -f "$COMPOSE_FILE")
PROFILE_ARGS=()
[ "${1:-}" = "--tunnel" ] && PROFILE_ARGS=(--profile tunnel)

# GHCR auth only needed for PRIVATE packages. Public packages pull anonymously;
# set GHCR_TOKEN (a read:packages PAT) in .env if the images are private.
if [ -n "${GHCR_TOKEN:-}" ]; then
echo "==> docker login ghcr.io as ${GHCR_USER:-obchain}"
echo "$GHCR_TOKEN" | docker login ghcr.io -u "${GHCR_USER:-obchain}" --password-stdin
# Docker Hub auth only needed for PRIVATE repos. Public repos pull anonymously;
# set DOCKER_USERNAME + DOCKER_PASSWORD (access token) in .env if private.
if [ -n "${DOCKER_USERNAME:-}" ] && [ -n "${DOCKER_PASSWORD:-}" ]; then
echo "==> docker login as $DOCKER_USERNAME"
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
fi

echo "==> pulling images (${VOLX_REGISTRY:-ghcr.io/obchain}, tag ${VOLX_TAG:-latest})"
echo "==> pulling images (${VOLX_REGISTRY:-obchain219}, tag ${VOLX_TAG:-latest})"
"${DC[@]}" "${PROFILE_ARGS[@]}" pull

# `up -d` diffs each service's desired vs running state and recreates only the
Expand Down
Loading