forked from Nixius/authelia
151 lines
3.8 KiB
Bash
Executable File
151 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build the production images on the target Docker context and deploy app.a250.ca.
|
|
|
|
set -Eeuo pipefail
|
|
|
|
DOMAIN="${DOMAIN:-app.a250.ca}"
|
|
STACK_NAME="${STACK_NAME:-atlas}"
|
|
DEPLOY_CONTEXT="${DOCKER_DEPLOY_CONTEXT:-${DEPLOY_CONTEXT:-}}"
|
|
DEPLOY_HOST="${DEPLOY_HOST:-app.a250.ca}"
|
|
STACK_FILE="${STACK_FILE:-stack.production.yml}"
|
|
SKIP_TESTS="${SKIP_TESTS:-1}"
|
|
SKIP_HEALTHCHECK="${SKIP_HEALTHCHECK:-1}"
|
|
PUSH_IMAGES="${PUSH_IMAGES:-1}"
|
|
REGISTRY_IMAGE="${REGISTRY_IMAGE:-git.nixc.us/a250/ss-atlas}"
|
|
SS_ATLAS_LOCAL_IMAGE="${SS_ATLAS_LOCAL_IMAGE:-atlas-ss-atlas:production}"
|
|
SS_ATLAS_PUSH_IMAGE="${SS_ATLAS_PUSH_IMAGE:-$REGISTRY_IMAGE:production}"
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
log() {
|
|
printf '[ship] %s\n' "$*"
|
|
}
|
|
|
|
fail() {
|
|
printf '[ship] ERROR: %s\n' "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
run() {
|
|
log "+ $*"
|
|
"$@"
|
|
}
|
|
|
|
run_docker() {
|
|
log "+ docker ${DOCKER_LABEL} $*"
|
|
docker "${DOCKER_ARGS[@]}" "$@"
|
|
}
|
|
|
|
require_command() {
|
|
command -v "$1" >/dev/null 2>&1 || fail "Missing required command: $1"
|
|
}
|
|
|
|
docker_target() {
|
|
docker "${DOCKER_ARGS[@]}" "$@"
|
|
}
|
|
|
|
service_exists() {
|
|
docker_target service inspect "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
force_service_image() {
|
|
local service="$1"
|
|
local image="$2"
|
|
|
|
if service_exists "$service"; then
|
|
run_docker service update --force --image "$image" "$service"
|
|
else
|
|
log "Service $service is not present yet; stack deploy will create it."
|
|
fi
|
|
}
|
|
|
|
cd "$ROOT_DIR"
|
|
|
|
require_command git
|
|
require_command docker
|
|
|
|
if [ -z "$DEPLOY_CONTEXT" ]; then
|
|
if docker context inspect macmini7 >/dev/null 2>&1; then
|
|
DEPLOY_CONTEXT="macmini7"
|
|
else
|
|
DEPLOY_CONTEXT=""
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$DEPLOY_CONTEXT" ]; then
|
|
DOCKER_ARGS=(--context "$DEPLOY_CONTEXT")
|
|
DOCKER_LABEL="--context $DEPLOY_CONTEXT"
|
|
else
|
|
DOCKER_ARGS=(-H "ssh://$DEPLOY_HOST")
|
|
DOCKER_LABEL="-H ssh://$DEPLOY_HOST"
|
|
fi
|
|
|
|
[ -f "$STACK_FILE" ] || fail "Missing $STACK_FILE"
|
|
grep -q "$DOMAIN" "$STACK_FILE" || fail "$STACK_FILE does not reference $DOMAIN"
|
|
|
|
if ! docker_target info >/dev/null 2>&1; then
|
|
fail "Docker target '${DOCKER_LABEL}' is not reachable"
|
|
fi
|
|
|
|
if [ "$(docker_target info --format '{{.Swarm.LocalNodeState}}')" != "active" ]; then
|
|
fail "Docker target '${DOCKER_LABEL}' is not an active swarm manager"
|
|
fi
|
|
|
|
BUILD_COMMIT="$(git rev-parse --short HEAD)"
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
BUILD_COMMIT="${BUILD_COMMIT}-dirty"
|
|
log "Working tree has uncommitted changes; shipping current checkout as $BUILD_COMMIT."
|
|
fi
|
|
BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
|
|
log "Shipping $BUILD_COMMIT to https://$DOMAIN via docker ${DOCKER_LABEL}."
|
|
|
|
if [ "$SKIP_TESTS" != "1" ]; then
|
|
require_command go
|
|
log "+ (cd docker/ss-atlas && go test ./...)"
|
|
(cd docker/ss-atlas && go test ./...)
|
|
else
|
|
log "Skipping tests because SKIP_TESTS=1."
|
|
fi
|
|
|
|
run_docker build \
|
|
--pull \
|
|
--no-cache \
|
|
--build-arg "BUILD_COMMIT=$BUILD_COMMIT" \
|
|
--build-arg "BUILD_TIME=$BUILD_TIME" \
|
|
--label "org.opencontainers.image.revision=$BUILD_COMMIT" \
|
|
--label "org.opencontainers.image.created=$BUILD_TIME" \
|
|
-t "$SS_ATLAS_LOCAL_IMAGE" \
|
|
-t "$SS_ATLAS_PUSH_IMAGE" \
|
|
-f docker/ss-atlas/Dockerfile \
|
|
docker/ss-atlas
|
|
|
|
if [ "$PUSH_IMAGES" = "1" ]; then
|
|
run_docker push "$SS_ATLAS_PUSH_IMAGE"
|
|
else
|
|
log "Skipping image pushes because PUSH_IMAGES=0."
|
|
fi
|
|
|
|
run_docker stack deploy \
|
|
--with-registry-auth \
|
|
--resolve-image never \
|
|
-c "$STACK_FILE" \
|
|
"$STACK_NAME"
|
|
|
|
force_service_image "${STACK_NAME}_ss-atlas" "$SS_ATLAS_PUSH_IMAGE"
|
|
|
|
log "Current stack tasks:"
|
|
run_docker stack ps "$STACK_NAME" --no-trunc
|
|
|
|
if [ "$SKIP_HEALTHCHECK" != "1" ]; then
|
|
require_command curl
|
|
run curl -fsS "https://$DOMAIN/health"
|
|
printf '\n'
|
|
run curl -fsS "https://$DOMAIN/version"
|
|
printf '\n'
|
|
else
|
|
log "Skipping health checks because SKIP_HEALTHCHECK=1."
|
|
fi
|
|
|
|
log "Done. Requested $BUILD_COMMIT on https://$DOMAIN."
|