Fix letsencrypt auto-renew.
This commit is contained in:
1 parent
3406c622c5
commit
54b640aef0
7 files changed
+103
-19
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:deny --global former@signal.org # cut someone off
|
||||||
dokku google-auth:disable my-app # turn SSO off for an app
|
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: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/`
|
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
|
- **Plugin updates:** `sudo dokku plugin:update google-auth` rebuilds the
|
||||||
service image and recreates the container with freshly written settings.
|
service image and recreates the container with freshly written settings.
|
||||||
Editing the plugin directory in place works too: the image is tagged with a
|
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
|
fingerprint of `Dockerfile`, `go.mod`, `cmd/`, and `internal/`, so
|
||||||
starts the service) rebuilds when the Go code has moved rather than reusing
|
`google-auth:restart` (and anything else that starts the service) rebuilds
|
||||||
the binary that happens to be tagged. This matters because the shell half of
|
when the Go code has moved rather than reusing the binary that happens to be
|
||||||
the plugin takes effect the moment the files change while the binary does
|
tagged. This matters because the shell half of the plugin takes effect the
|
||||||
not, and a container running an older build accepts the mount, accepts
|
moment the files change while the binary does not, and a container running an
|
||||||
`GOOGLE_AUTH_APP_CONFIG_DIR`, and ignores both.
|
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
|
`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
|
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.
|
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:report [app], Show global and per-app google-auth status
|
||||||
google-auth:start, Start the shared auth service container
|
google-auth:start, Start the shared auth service container
|
||||||
google-auth:stop, Stop 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
|
google-auth:logs [--tail|-t], Show logs from the shared auth service container
|
||||||
help_content
|
help_content
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -637,11 +637,19 @@ fn-ga-image-current() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn-ga-build-image() {
|
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"
|
command -v docker >/dev/null 2>&1 || dokku_log_fail "docker is required to build the google-auth service image"
|
||||||
dokku_log_info1 "Building $GOOGLE_AUTH_IMAGE (first build downloads the Go toolchain image; this can take a few minutes)"
|
local args=(image build)
|
||||||
docker image build \
|
if [[ "$NO_CACHE" == "true" ]]; then
|
||||||
--label "google-auth.source-hash=$(fn-ga-source-hash)" \
|
# --pull too: the source hash cannot see the base images, so a rebuild that
|
||||||
-t "$GOOGLE_AUTH_IMAGE" "$GOOGLE_AUTH_PLUGIN_DIR"
|
# 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)"
|
||||||
|
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() {
|
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
|
# 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
|
# plugin, and reusing the old binary there is what makes a new feature look
|
||||||
# broken rather than absent.
|
# 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
|
fn-ga-write-env-file
|
||||||
local port
|
local port
|
||||||
port="$(fn-ga-global-get port "$GOOGLE_AUTH_DEFAULT_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"
|
mkdir -p "$DATA_ROOT/global" "$DATA_ROOT/apps"
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$PLUGIN_DIR/functions"
|
||||||
|
|
||||||
if command -v docker >/dev/null 2>&1; then
|
if command -v docker >/dev/null 2>&1; then
|
||||||
echo "-----> Building dokku-google-auth service image (first build can take a few minutes)"
|
# Build through fn-ga-build-image rather than calling docker directly, so the
|
||||||
docker image build -t dokku-google-auth:latest "$PLUGIN_DIR"
|
# 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
|
# 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
|
# 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
|
# 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.
|
# access list and fall back to the global one.
|
||||||
if [[ "$(docker container inspect -f '{{.State.Running}}' dokku-google-auth 2>/dev/null)" == "true" ]]; then
|
if [[ "$(docker container inspect -f '{{.State.Running}}' dokku-google-auth 2>/dev/null)" == "true" ]]; then
|
||||||
echo "-----> Restarting google-auth service with the new image"
|
echo "-----> Restarting google-auth service with the new image"
|
||||||
# shellcheck disable=SC1091
|
|
||||||
source "$PLUGIN_DIR/functions"
|
|
||||||
if fn-ga-configured; then
|
if fn-ga-configured; then
|
||||||
fn-ga-service-start
|
fn-ga-service-start
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ description = "Check the help output shapes and that every subcommand is documen
|
|||||||
run = "test/help-test.sh"
|
run = "test/help-test.sh"
|
||||||
|
|
||||||
[tasks.docker-build]
|
[tasks.docker-build]
|
||||||
description = "Build the auth service docker image"
|
description = "Build the auth service docker image, labelled the way the plugin does"
|
||||||
run = "docker build -t dokku-google-auth:latest ."
|
# 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]
|
[tasks.check]
|
||||||
description = "Run everything CI would run"
|
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
|
case "$1 $2" in
|
||||||
"container inspect") cat "$DOCKER_INSPECT_FIXTURE" ;;
|
"container inspect") cat "$DOCKER_INSPECT_FIXTURE" ;;
|
||||||
"image inspect") printf '%s\n' "$DOCKER_IMAGE_FIXTURE" ;;
|
"image inspect") printf '%s\n' "$DOCKER_IMAGE_FIXTURE" ;;
|
||||||
|
"image build") printf '%s\n' "$*" >"$DOCKER_ARGS_FIXTURE" ;;
|
||||||
esac
|
esac
|
||||||
exit 0
|
exit 0
|
||||||
EOF
|
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 "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 "<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"
|
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"
|
echo "ok: service image tracks the plugin source"
|
||||||
|
|
||||||
# --- lifecycle triggers carry per-app lists ---
|
# --- lifecycle triggers carry per-app lists ---
|
||||||
|
|||||||
Reference in new issue
Block a user