Fix letsencrypt auto-renew.
This commit is contained in:
1 parent
3406c622c5
commit
54b640aef0
7 files changed
+102
-18
No files matched your search
@@ -284,7 +284,8 @@ dokku google-auth:allow my-app alice@signal.org # …or just on one app
|
||||
dokku google-auth:deny --global former@signal.org # cut someone off
|
||||
dokku google-auth:disable my-app # turn SSO off for an app
|
||||
dokku google-auth:logs -t # follow auth service logs (sign-ins, denials)
|
||||
dokku google-auth:restart # restart the auth service
|
||||
dokku google-auth:restart # restart the auth service (rebuilds if the source moved)
|
||||
dokku google-auth:rebuild # force a rebuild when the source looks unchanged
|
||||
```
|
||||
|
||||
Users can check who they're signed in as at `https://<any-app>/_google-auth/`
|
||||
@@ -315,12 +316,18 @@ and sign out at `https://<any-app>/_google-auth/logout`.
|
||||
- **Plugin updates:** `sudo dokku plugin:update google-auth` rebuilds the
|
||||
service image and recreates the container with freshly written settings.
|
||||
Editing the plugin directory in place works too: the image is tagged with a
|
||||
fingerprint of its source, so `google-auth:restart` (and anything else that
|
||||
starts the service) rebuilds when the Go code has moved rather than reusing
|
||||
the binary that happens to be tagged. This matters because the shell half of
|
||||
the plugin takes effect the moment the files change while the binary does
|
||||
not, and a container running an older build accepts the mount, accepts
|
||||
`GOOGLE_AUTH_APP_CONFIG_DIR`, and ignores both.
|
||||
fingerprint of `Dockerfile`, `go.mod`, `cmd/`, and `internal/`, so
|
||||
`google-auth:restart` (and anything else that starts the service) rebuilds
|
||||
when the Go code has moved rather than reusing the binary that happens to be
|
||||
tagged. This matters because the shell half of the plugin takes effect the
|
||||
moment the files change while the binary does not, and a container running an
|
||||
older build accepts the mount, accepts `GOOGLE_AUTH_APP_CONFIG_DIR`, and
|
||||
ignores both.
|
||||
That fingerprint covers this plugin's own source and nothing else, so when
|
||||
the inputs it cannot see change — a patched `golang:1.24-alpine`, a build that
|
||||
died halfway — force the rebuild: `dokku google-auth:rebuild`, or
|
||||
`dokku google-auth:rebuild --no-cache` to also discard the layer cache and
|
||||
re-pull the base images.
|
||||
`dokku google-auth:report` names the running service's state — it asks the
|
||||
service itself rather than trusting Docker's metadata — and if it ever says
|
||||
it is ignoring per-app lists, `dokku google-auth:restart` recreates it.
|
||||
|
||||
@@ -18,7 +18,8 @@ case "$1" in
|
||||
google-auth:report [app], Show global and per-app google-auth status
|
||||
google-auth:start, Start the shared auth service container
|
||||
google-auth:stop, Stop the shared auth service container
|
||||
google-auth:restart, Restart the shared auth service container (picks up config changes)
|
||||
google-auth:restart, Restart the shared auth service container (rebuilds the image if the plugin source changed)
|
||||
google-auth:rebuild [--no-cache], Force a rebuild of the service image even if the source looks unchanged
|
||||
google-auth:logs [--tail|-t], Show logs from the shared auth service container
|
||||
help_content
|
||||
}
|
||||
|
||||
@@ -637,11 +637,19 @@ fn-ga-image-current() {
|
||||
}
|
||||
|
||||
fn-ga-build-image() {
|
||||
declare NO_CACHE="${1:-false}"
|
||||
command -v docker >/dev/null 2>&1 || dokku_log_fail "docker is required to build the google-auth service image"
|
||||
local args=(image build)
|
||||
if [[ "$NO_CACHE" == "true" ]]; then
|
||||
# --pull too: the source hash cannot see the base images, so a rebuild that
|
||||
# keeps a cached golang:1.24-alpine is not actually a fresh build.
|
||||
args+=(--no-cache --pull)
|
||||
dokku_log_info1 "Building $GOOGLE_AUTH_IMAGE from scratch (ignoring the layer cache, re-pulling base images)"
|
||||
else
|
||||
dokku_log_info1 "Building $GOOGLE_AUTH_IMAGE (first build downloads the Go toolchain image; this can take a few minutes)"
|
||||
docker image build \
|
||||
--label "google-auth.source-hash=$(fn-ga-source-hash)" \
|
||||
-t "$GOOGLE_AUTH_IMAGE" "$GOOGLE_AUTH_PLUGIN_DIR"
|
||||
fi
|
||||
args+=(--label "google-auth.source-hash=$(fn-ga-source-hash)" -t "$GOOGLE_AUTH_IMAGE" "$GOOGLE_AUTH_PLUGIN_DIR")
|
||||
docker "${args[@]}"
|
||||
}
|
||||
|
||||
fn-ga-service-running() {
|
||||
@@ -739,7 +747,7 @@ fn-ga-service-start() {
|
||||
# Starting the service is how an operator expects to pick up an upgraded
|
||||
# plugin, and reusing the old binary there is what makes a new feature look
|
||||
# broken rather than absent.
|
||||
fn-ga-image-current || fn-ga-build-image
|
||||
fn-ga-image-current || fn-ga-build-image false
|
||||
fn-ga-write-env-file
|
||||
local port
|
||||
port="$(fn-ga-global-get port "$GOOGLE_AUTH_DEFAULT_PORT")"
|
||||
|
||||
@@ -9,9 +9,15 @@ DATA_ROOT="$DOKKU_LIB_ROOT/data/google-auth"
|
||||
|
||||
mkdir -p "$DATA_ROOT/global" "$DATA_ROOT/apps"
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source "$PLUGIN_DIR/functions"
|
||||
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
echo "-----> Building dokku-google-auth service image (first build can take a few minutes)"
|
||||
docker image build -t dokku-google-auth:latest "$PLUGIN_DIR"
|
||||
# Build through fn-ga-build-image rather than calling docker directly, so the
|
||||
# image carries the source-hash label. An unlabelled image reads as stale
|
||||
# forever: every service start would rebuild it, and the report would claim
|
||||
# the binary is older than the plugin right after an upgrade installed it.
|
||||
fn-ga-build-image false
|
||||
# Pick up the new image if the service is already running. This goes through
|
||||
# fn-ga-service-start rather than its own `docker run` so an upgrade always
|
||||
# rewrites service.env first: recreating the container from the file an older
|
||||
@@ -20,8 +26,6 @@ if command -v docker >/dev/null 2>&1; then
|
||||
# access list and fall back to the global one.
|
||||
if [[ "$(docker container inspect -f '{{.State.Running}}' dokku-google-auth 2>/dev/null)" == "true" ]]; then
|
||||
echo "-----> Restarting google-auth service with the new image"
|
||||
# shellcheck disable=SC1091
|
||||
source "$PLUGIN_DIR/functions"
|
||||
if fn-ga-configured; then
|
||||
fn-ga-service-start
|
||||
else
|
||||
|
||||
@@ -39,8 +39,10 @@ description = "Check the help output shapes and that every subcommand is documen
|
||||
run = "test/help-test.sh"
|
||||
|
||||
[tasks.docker-build]
|
||||
description = "Build the auth service docker image"
|
||||
run = "docker build -t dokku-google-auth:latest ."
|
||||
description = "Build the auth service docker image, labelled the way the plugin does"
|
||||
# Via fn-ga-build-image so the image carries its source-hash label. A build
|
||||
# without it reads as permanently stale to the plugin.
|
||||
run = "bash -c 'source ./functions && fn-ga-build-image'"
|
||||
|
||||
[tasks.check]
|
||||
description = "Run everything CI would run"
|
||||
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$(dirname "$(dirname "${BASH_SOURCE[0]}")")/functions"
|
||||
|
||||
cmd-google-auth-rebuild() {
|
||||
declare desc="rebuild the auth service image from the plugin source and restart"
|
||||
local cmd="google-auth:rebuild"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
|
||||
# Starting the service already rebuilds when the Go source has moved, so this
|
||||
# exists for the case that check cannot see: the source is unchanged but the
|
||||
# build inputs are not — a patched base image, a half-written image, a build
|
||||
# that failed partway.
|
||||
local no_cache=false
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--no-cache) no_cache=true ;;
|
||||
*) dokku_log_fail "usage: dokku $cmd [--no-cache]" ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
fn-ga-build-image "$no_cache"
|
||||
if fn-ga-service-running; then
|
||||
# The image is current now, so this recreates the container without
|
||||
# building a second time.
|
||||
fn-ga-service-start
|
||||
else
|
||||
dokku_log_verbose "auth service is not running; the new image is used when it starts"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-google-auth-rebuild "$@"
|
||||
@@ -238,6 +238,7 @@ cat >"$WORK/bin-docker/docker" <<'EOF'
|
||||
case "$1 $2" in
|
||||
"container inspect") cat "$DOCKER_INSPECT_FIXTURE" ;;
|
||||
"image inspect") printf '%s\n' "$DOCKER_IMAGE_FIXTURE" ;;
|
||||
"image build") printf '%s\n' "$*" >"$DOCKER_ARGS_FIXTURE" ;;
|
||||
esac
|
||||
exit 0
|
||||
EOF
|
||||
@@ -308,6 +309,33 @@ image_current "$SOURCE_HASH" || fail "an image labelled with the current source
|
||||
image_current "0000000000000000" && fail "an image built from other source is not current"
|
||||
image_current "<no value>" && fail "an unlabelled image (built before this check) is not current"
|
||||
image_current "" && fail "an image with no label value is not current"
|
||||
|
||||
# Every build must apply the label, or the image it produces is stale on
|
||||
# arrival — the plugin would rebuild on every start and the report would call a
|
||||
# freshly installed binary out of date.
|
||||
# shellcheck disable=SC2030,SC2031 # the subshell is what keeps the stubs local
|
||||
build_args() (
|
||||
export DOCKER_ARGS_FIXTURE="$WORK/build-args"
|
||||
PATH="$WORK/bin-docker:$PATH"
|
||||
fn-ga-build-image "$1" >/dev/null
|
||||
cat "$DOCKER_ARGS_FIXTURE"
|
||||
)
|
||||
|
||||
DEFAULT_BUILD="$(build_args false)"
|
||||
grep -q -- "--label google-auth.source-hash=$SOURCE_HASH" <<<"$DEFAULT_BUILD" ||
|
||||
fail "a build must label the image with the source hash, got: $DEFAULT_BUILD"
|
||||
grep -q -- "-t dokku-google-auth:latest" <<<"$DEFAULT_BUILD" ||
|
||||
fail "a build must tag the service image, got: $DEFAULT_BUILD"
|
||||
grep -q -- "--no-cache" <<<"$DEFAULT_BUILD" &&
|
||||
fail "an ordinary build should use the layer cache"
|
||||
|
||||
FORCED_BUILD="$(build_args true)"
|
||||
grep -q -- "--no-cache" <<<"$FORCED_BUILD" || fail "a forced build should ignore the layer cache"
|
||||
# The source hash covers this plugin's files, not the images the Dockerfile
|
||||
# pulls, so a forced build that reuses a cached base image is not a fresh one.
|
||||
grep -q -- "--pull" <<<"$FORCED_BUILD" || fail "a forced build should re-pull the base images"
|
||||
grep -q -- "--label google-auth.source-hash=$SOURCE_HASH" <<<"$FORCED_BUILD" ||
|
||||
fail "a forced build must still label the image, got: $FORCED_BUILD"
|
||||
echo "ok: service image tracks the plugin source"
|
||||
|
||||
# --- lifecycle triggers carry per-app lists ---
|
||||
|
||||
Reference in new issue
Block a user