refactor(self-hosting): forward every setting, drop dead config (#3047)

This commit is contained in:
Hampus
2026-09-30 00:58:43 +02:00
committed by GitHub
parent 39f9beda5a
commit 2b8a743dc5
96 changed files with 1743 additions and 2391 deletions
File diff suppressed because it is too large Load Diff
@@ -238,12 +238,12 @@ The desktop client opens the hosted web app for its release channel, so reach yo
Recovery requires `.env`, a database dump and a backup of `seaweedfs-data`, which holds uploads, avatars, reports and harvests. See [Volumes and buckets](/operator/configuration/#volumes-and-buckets) for everything that needs backing up.
The dump costs no downtime, so run it on a schedule while the stack serves:
The dump costs no downtime, so run it on a schedule while the stack serves. It runs inside the `postgres` container and takes the role and database from that container's environment, which follows `FLUXER_POSTGRES_USERNAME` and `FLUXER_POSTGRES_DATABASE`. It is for the bundled database. A database outside the stack is backed up with its own tools:
```bash
cd ~/fluxer
mkdir -p backups
docker compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom \
docker compose exec -T postgres sh -c 'pg_dump -U $POSTGRES_USER -d $POSTGRES_DB --format=custom' \
> "backups/fluxer-$(date -u +%Y%m%dT%H%M%SZ).dump"
```
@@ -251,7 +251,7 @@ PowerShell writes UTF-16 through `>`, which corrupts a binary dump. On Windows,
```powershell
mkdir -Force backups
docker compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom -f /tmp/fluxer.dump
docker compose exec -T postgres sh -c 'pg_dump -U $POSTGRES_USER -d $POSTGRES_DB --format=custom -f /tmp/fluxer.dump'
docker compose cp postgres:/tmp/fluxer.dump backups/fluxer.dump
docker compose exec -T postgres rm /tmp/fluxer.dump
```
@@ -396,7 +396,7 @@ Forward every path and query string unchanged. The edge handles routing:
| `/.well-known/assetlinks.json` | Android app association |
| `/version.json` | Client version metadata |
All other paths serve the web app.
All other paths serve the web app. The admin path follows `FLUXER_ADMIN_BASE_PATH`, `/admin` by default.
Pass the query string on `/gateway` through untouched. Clients always send `?v=`, `?encoding=`, `?compress=` and `?stream=`, and `1` is the only version the Gateway accepts.
@@ -25,6 +25,8 @@ The images come from `FLUXER_IMAGE_TAG` in `.env`. The stack files come from a g
The repository holds no ref by the name of a pinned image tag. A release tags each image on its own, as `[email protected]`, so pass `--ref` with that tag or with the commit it points at. Without that override the download fails with exit 4.
The stack files on `main` can run ahead of the `v1` images. The current `docker-compose.yml` passes an optional setting with no Compose default through empty when `.env` leaves it out, and only images built from the same change or later read an empty value as unset. Older images reject some of those empty values and `api`, `worker` and `media-proxy` fail to start. Refresh the stack files only once the images the tag names are at least as new, or pin both with `--ref`.
## What the script does
`--update` runs these steps in this order, and stops on the first one that fails:
@@ -195,6 +197,10 @@ Within minutes of the upgrade, `worker` starts deleting existing data that is pa
Instances on Cassandra already behave this way.
## Check the svc request ceiling
`docker-compose.yml` used to pass `FLUXER_SVC_MAX_CONCURRENT_REQUESTS` only to the `users` and `messages` routers and shards. It now reaches every svc container, so a value set in `.env` also caps `snowflakes`, `gifs` and `unfurl`. Unset, `snowflakes` allows `320` requests in flight, `messages` `192` and the rest `64`. An instance that sets the name either raises it to at least `320` or removes it from `.env`, then runs `docker compose up -d`.
## Add the passkey columns on Cassandra
An instance on the Postgres backend needs nothing here. An instance on Cassandra or Scylla adds two columns to `webauthn_credentials` before it starts the new `api` and `worker` images. Replace `fluxer` with the value of `FLUXER_CASSANDRA_KEYSPACE`.
@@ -229,7 +235,7 @@ Nothing else is copied. The dump covers `postgres-data`. The other volumes eithe
Put a dump on a timer as well. On Linux and macOS, this crontab line writes one a night and keeps two weeks of them:
```cron
15 3 * * * cd /srv/fluxer && docker compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom > "backups/fluxer-$(date -u +\%Y\%m\%dT\%H\%M\%SZ).dump" && find backups -name 'fluxer-*.dump' -mtime +14 -delete
15 3 * * * cd /srv/fluxer && docker compose exec -T postgres sh -c 'pg_dump -U $POSTGRES_USER -d $POSTGRES_DB --format=custom' > "backups/fluxer-$(date -u +\%Y\%m\%dT\%H\%M\%SZ).dump" && find backups -name 'fluxer-*.dump' -mtime +14 -delete
```
`/srv/fluxer` stands for the directory holding `.env`. Write it as an absolute path, because cron does not expand `~`. An unescaped `%` in a crontab is a newline, which is why every one above has a backslash.
@@ -269,7 +275,7 @@ The `seaweedfs-data` volume stays until you delete it. Copy its objects to the n
The other bundled services have no shipped overlay. Take one out with an override file listed in `COMPOSE_FILE`, which [Keep a local compose change](#keep-a-local-compose-change) describes, rather than by editing `docker-compose.yml`, which the Place step replaces on every upgrade.
The installer backs up only the bundled database and object store. Arrange separate backups for external stores before upgrading, and keep them with the release's backup record.
The installer backs up only the bundled database and object store. It skips the database dump when the stack defines no `postgres` service, and when `FLUXER_POSTGRES_HOST` or the host in `FLUXER_POSTGRES_URL` names anything other than `postgres`. The bundled service is idle in that shape, and its data directory still holds the role and database it was first started with, so the by-hand dump and restore commands on this page do not work against it either. Arrange separate backups for external stores before upgrading, and keep them with the release's backup record.
## Roll back
@@ -295,12 +301,12 @@ The database restores from the custom-format dump:
```bash
docker compose stop
docker compose up -d --wait postgres
docker compose exec -T postgres pg_restore -U fluxer -d fluxer --clean --if-exists \
docker compose exec -T postgres sh -c 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB --clean --if-exists' \
< backups/record-20260831T120000Z/fluxer.dump
docker compose up -d
```
`--clean` prints notices about objects that do not exist yet, which is expected against a fresh directory.
`--clean` prints notices about objects that do not exist yet, which is expected against a fresh directory. The role and database come from the `postgres` container's environment, which follows `FLUXER_POSTGRES_USERNAME` and `FLUXER_POSTGRES_DATABASE`, the same way the installer's dump reads them. These commands are for the bundled database. A database outside the stack restores with its own tools.
PowerShell has no `<` redirection. On Windows, copy the dump into the container and name it as a file:
@@ -308,7 +314,7 @@ PowerShell has no `<` redirection. On Windows, copy the dump into the container
docker compose stop
docker compose up -d --wait postgres
docker compose cp backups\record-20260831T120000Z\fluxer.dump postgres:/tmp/fluxer.dump
docker compose exec -T postgres pg_restore -U fluxer -d fluxer --clean --if-exists /tmp/fluxer.dump
docker compose exec -T postgres sh -c 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB --clean --if-exists /tmp/fluxer.dump'
docker compose exec -T postgres rm /tmp/fluxer.dump
docker compose up -d
```
@@ -327,12 +333,12 @@ For a `seaweedfs-data.tar`, write `tar xf` in place of `tar xzf`. `tar` extracts
## Move to a new Postgres major version
`docker-compose.yml` pins `postgres:16-alpine`. A newer major does not read the data directory an older major wrote, so the data moves across through a dump. The upgrade refuses when the refreshed compose file changes that pin, because the move destroys the volume holding the database.
`docker-compose.yml` runs `postgres:16-alpine` unless `FLUXER_POSTGRES_IMAGE` in `.env` names another image. A newer major does not read the data directory an older major wrote, so the data moves across through a dump. The upgrade refuses when the refreshed compose file would run a different major from the current one, because the move destroys the volume holding the database. It reads the current major from the image the old file names, and takes `FLUXER_POSTGRES_IMAGE` into account only for a file that reads it.
Take the dump while the old major is still serving, then stop everything and drop the volume:
```bash
docker compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom \
docker compose exec -T postgres sh -c 'pg_dump -U $POSTGRES_USER -d $POSTGRES_DB --format=custom' \
> backups/pre-major.dump
docker compose down
docker volume rm fluxer_postgres-data
@@ -342,16 +348,18 @@ On Windows, run `pg_dump` inside the container with `-f /tmp/pre-major.dump` and
Once that volume is removed, the dump is the only copy of the database.
Put the new `postgres` tag in `docker-compose.yml`, start the database on its own, and restore into the empty directory:
`FLUXER_POSTGRES_IMAGE` takes effect only once `docker-compose.yml` reads it. An instance on older stack files runs `sh install.sh --update` first, or edits the tag in its `docker-compose.yml` as before.
Set `FLUXER_POSTGRES_IMAGE` in `.env` to the new tag, such as `postgres:17-alpine`, start the database on its own, and restore into the empty directory:
```bash
docker compose up -d --wait postgres
docker compose exec -T postgres pg_restore -U fluxer -d fluxer --clean --if-exists \
docker compose exec -T postgres sh -c 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB --clean --if-exists' \
< backups/pre-major.dump
docker compose up -d
```
Run `sh install.sh --update` afterwards to finish the move on the refreshed files.
Run `sh install.sh --update` afterwards to finish the move on the refreshed files. Remove the `FLUXER_POSTGRES_IMAGE` line once the refreshed `docker-compose.yml` runs the same major by default.
## Pin a release
@@ -359,11 +367,11 @@ Run `sh install.sh --update` afterwards to finish the move on the refreshed file
A pinned instance also pins its stack files. [Match the images to the stack files](#match-the-images-to-the-stack-files) has the `--ref` a pinned tag needs.
The tag applies only to the Fluxer images. `caddy`, `postgres`, `valkey`, `nats`, `meilisearch`, `seaweedfs` and `livekit` are pinned in `docker-compose.yml`, and they move only when an upgrade refreshes that file.
The tag applies only to the Fluxer images. `caddy`, `postgres`, `valkey`, `nats`, `meilisearch`, `seaweedfs` and `livekit` take their tags from `docker-compose.yml`, and move when an upgrade refreshes that file. An image name in `.env`, such as `FLUXER_POSTGRES_IMAGE`, holds one of them in place instead. [Images](/operator/configuration/#images) lists the names.
## Change the domain or the passkey relying party
`FLUXER_DOMAIN` supplies the default `FLUXER_PASSKEY_RP_ID`, which is the domain a passkey is tied to. A passkey works only under the identifier it was created with.
`FLUXER_DOMAIN` supplies the default `FLUXER_PASSKEY_RP_ID`, which is the domain a passkey is tied to. `FLUXER_PUBLIC_ORIGIN` does not move it. A passkey works only under the identifier it was created with.
:::danger[Changing either value invalidates every passkey]
Passkeys registered under the old `FLUXER_PASSKEY_RP_ID` stop working and cannot be recovered. Every user has to register a new one, so keep another sign-in method working before you change it.
+80 -14
View File
@@ -435,8 +435,8 @@ function Get-FluxerRefForTag([string]$Tag) {
}
# The images come from FLUXER_IMAGE_TAG and the stack files come from a git ref. A release tags its
# images and its commit with the same CalVer string, so a pinned tag names the commit that carries
# its compose files. The moving tags v1 and latest track main.
# images and its commit with the same CalVer string, so a pinned tag names the commit that holds its
# compose files. The moving tags v1 and latest map to main, which can run ahead of the v1 images.
function Assert-FluxerDerivedRef([string]$Value, [string]$EnvPath) {
if ($Value.Length -eq 0) {
Stop-Fluxer "$EnvPath declares no FLUXER_IMAGE_TAG, so no ref can be derived. Pass -Ref." $FluxerExitRefused
@@ -631,8 +631,10 @@ function Remove-FluxerStagingDirectory([string]$Path) {
# Invoke-WebRequest -Uri https://raw.githubusercontent.com/fluxerapp/fluxer/main/deploy/self-hosting/docker-compose.yml -OutFile docker-compose.yml
#
# The files come from a git ref and the images come from FLUXER_IMAGE_TAG. The ref is derived from
# the tag unless -Ref names one, which is the pairing rule that stops a compose file from asking for
# a variable the running images do not read.
# the tag unless -Ref names one. A pinned CalVer tag names the commit its images were built from, so
# its compose file asks only for variables those images read. The moving tags v1 and latest map to
# main, and main's compose file can run ahead of the v1 images until the image builds are dispatched
# again.
#
# Everything lands in a staging directory first, so a failed download leaves the working directory
# on the set it already had, and so the upgrade can compare old against new before replacing.
@@ -995,15 +997,34 @@ function Get-FluxerRunningImageId($Running, [string]$Reference) {
return ''
}
function Get-FluxerPostgresMajor([string]$Path) {
function Get-FluxerPostgresMajor([string]$Path, [string]$EnvPath) {
if (-not (Test-Path -LiteralPath $Path)) {
return ''
}
$image = ''
foreach ($line in [System.IO.File]::ReadAllText($Path).Split("`n")) {
if ($line -match '^\s*image:\s*postgres:(\d+)') {
return $Matches[1]
if ($line -match '^\s*image:\s*(postgres:\S*)') {
$image = $Matches[1]
break
}
}
if ($image.Length -eq 0) {
foreach ($line in [System.IO.File]::ReadAllText($Path).Split("`n")) {
if ($line -match '^\s*image:\s*\$\{FLUXER_POSTGRES_IMAGE:-([^}]*)\}') {
$image = $Matches[1]
$configured = Get-FluxerComposeValue $EnvPath 'FLUXER_POSTGRES_IMAGE'
if ($configured.Length -gt 0) {
$image = $configured
}
break
}
}
}
$name = ($image -split '@')[0]
$name = ($name -split '/')[-1]
if ($name -match ':(\d+)[^:]*$') {
return $Matches[1]
}
return ''
}
@@ -1297,9 +1318,12 @@ function Test-FluxerDumpHeader([string]$Path) {
# schema change.
#
# By hand:
# docker compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom > backups\fluxer.dump
# docker compose exec -T postgres sh -c 'pg_dump -U $POSTGRES_USER -d $POSTGRES_DB --format=custom -f /tmp/fluxer.dump'
# docker compose cp postgres:/tmp/fluxer.dump backups\fluxer.dump
# docker compose exec -T postgres rm /tmp/fluxer.dump
#
# The database and the role are both named fluxer and are fixed in docker-compose.yml. Keep -T.
# The postgres container's POSTGRES_USER and POSTGRES_DB follow FLUXER_POSTGRES_USERNAME and
# FLUXER_POSTGRES_DATABASE, so the command needs no names. Keep -T.
# Without it Docker attaches a terminal to the command and the dump arrives corrupted, which is
# why the first five bytes are checked against the custom-format magic rather than only the size.
#
@@ -1327,11 +1351,44 @@ function Test-FluxerStackDefinesService([string]$Name, [string]$TargetDir) {
return $script:FluxerStackServices -contains $Name
}
# The bundled postgres container takes POSTGRES_USER and POSTGRES_DB from FLUXER_POSTGRES_USERNAME
# and FLUXER_POSTGRES_DATABASE, and the image applies them only to an empty data directory. When
# those names point the apps at a database outside the stack, the bundled directory still holds the
# role and database it was first started with, so a dump that reads the container env asks for a
# role that is not there. The bundled service is idle in that shape and the dump skips it.
function Test-FluxerPostgresExternal([string]$TargetDir) {
$envPath = Join-Path $TargetDir '.env'
$pgHost = Get-FluxerComposeValue $envPath 'FLUXER_POSTGRES_HOST'
if ($pgHost.Length -gt 0 -and $pgHost -ne 'postgres') {
return $true
}
$url = Get-FluxerComposeValue $envPath 'FLUXER_POSTGRES_URL'
if ($url.Length -eq 0) {
return $false
}
$urlHost = $url
$scheme = $urlHost.IndexOf('://')
if ($scheme -ge 0) {
$urlHost = $urlHost.Substring($scheme + 3)
}
$urlHost = ($urlHost -split '[/?]', 2)[0]
$at = $urlHost.LastIndexOf('@')
if ($at -ge 0) {
$urlHost = $urlHost.Substring($at + 1)
}
$urlHost = ($urlHost -split ':', 2)[0]
return $urlHost -ne 'postgres'
}
function Backup-FluxerDatabase([string]$Record, [string]$TargetDir) {
if (-not (Test-FluxerStackDefinesService 'postgres' $TargetDir)) {
Write-FluxerLine 'Skipping the database dump. This stack defines no postgres service, so its database runs outside the stack and only the operator of that database can dump it.'
return
}
if (Test-FluxerPostgresExternal $TargetDir) {
Write-FluxerLine 'Skipping the database dump. FLUXER_POSTGRES_HOST or FLUXER_POSTGRES_URL points the stack at a database outside it, so the bundled postgres service is idle and only the operator of that database can dump it.'
return
}
if (-not (Test-FluxerPostgresRunning)) {
Write-FluxerLine 'Postgres is not running. Starting it for the dump.'
if ((Invoke-FluxerDocker @('compose', 'up', '-d', '--wait', 'postgres')) -ne 0) {
@@ -1340,7 +1397,7 @@ function Backup-FluxerDatabase([string]$Record, [string]$TargetDir) {
}
$dump = Join-Path $Record $FluxerDumpFile
Write-FluxerLine 'Dumping the database.'
$code = Invoke-FluxerDockerToFile @('compose', 'exec', '-T', 'postgres', 'pg_dump', '-U', 'fluxer', '-d', 'fluxer', '--format=custom') $dump $TargetDir
$code = Invoke-FluxerDockerToFile @('compose', 'exec', '-T', 'postgres', 'sh', '-c', '"exec pg_dump -U $POSTGRES_USER -d $POSTGRES_DB --format=custom"') $dump $TargetDir
if ($code -ne 0) {
Remove-FluxerTemporary $dump
Stop-Fluxer 'pg_dump failed. The instance is untouched.' $FluxerExitBackup
@@ -1462,8 +1519,9 @@ function Backup-FluxerInstance([string]$Record, [string]$TargetDir, [string]$Pro
# The refreshed file is still staged when this runs, so a refusal here leaves the instance exactly
# as it was.
function Assert-FluxerPostgresMajor([string]$TargetDir, [string]$StagingDir) {
$old = Get-FluxerPostgresMajor (Join-Path $TargetDir $script:FluxerComposeBase)
$new = Get-FluxerPostgresMajor (Join-Path $StagingDir 'docker-compose.yml')
$envPath = Join-Path $TargetDir '.env'
$old = Get-FluxerPostgresMajor (Join-Path $TargetDir $script:FluxerComposeBase) $envPath
$new = Get-FluxerPostgresMajor (Join-Path $StagingDir 'docker-compose.yml') $envPath
if ($old.Length -eq 0 -or $new.Length -eq 0 -or $old -eq $new) {
return
}
@@ -1569,8 +1627,8 @@ function Show-FluxerUpdatePlan([string]$TargetDir, [string]$EnvPath, [string]$Ba
if ($changed -eq 0) {
Write-FluxerLine " Note: ref $Ref moves no stack file"
}
$old = Get-FluxerPostgresMajor (Join-Path $TargetDir $script:FluxerComposeBase)
$new = Get-FluxerPostgresMajor (Join-Path $staging 'docker-compose.yml')
$old = Get-FluxerPostgresMajor (Join-Path $TargetDir $script:FluxerComposeBase) $EnvPath
$new = Get-FluxerPostgresMajor (Join-Path $staging 'docker-compose.yml') $EnvPath
if ($old.Length -gt 0 -and $new.Length -gt 0 -and $old -ne $new) {
Write-FluxerLine " Refusal: postgres moves from $old to $new, which this script does not do"
Write-FluxerLine ' Outcome: the run stops at that refusal and changes nothing'
@@ -1823,6 +1881,14 @@ function Get-FluxerEnvScalar([string]$EnvPath, [string]$Name) {
return $raw
}
function Get-FluxerComposeValue([string]$EnvPath, [string]$Name) {
$value = [string][Environment]::GetEnvironmentVariable($Name)
if ($value.Length -eq 0 -and (Test-Path -LiteralPath $EnvPath)) {
$value = Get-FluxerEnvScalar $EnvPath $Name
}
return $value
}
function Get-FluxerComposeSetting([string]$EnvPath) {
$value = ''
$source = 'the environment'
+61 -12
View File
@@ -711,8 +711,8 @@ fluxer_ref_for_tag() {
# The images come from FLUXER_IMAGE_TAG and the stack files come from a git ref.
# A release tags its images and its commit with the same CalVer string, so a
# pinned tag names the commit that carries its compose files. The moving tags v1
# and latest track main.
# pinned tag names the commit that holds its compose files. The moving tags v1
# and latest map to main, which can run ahead of the v1 images.
fluxer_resolve_ref() {
[ -z "$opt_ref" ] || return 0
if [ "$opt_update" -eq 1 ] || [ "$opt_rollback" -eq 1 ]; then
@@ -763,9 +763,11 @@ fluxer_open_scratch() {
# curl -fsSL https://raw.githubusercontent.com/fluxerapp/fluxer/main/deploy/self-hosting/docker-compose.yml -o docker-compose.yml
#
# The files come from a git ref and the images come from FLUXER_IMAGE_TAG. The
# ref is derived from the tag unless --ref names one, which is the pairing rule
# that stops a compose file from asking for a variable the running images do not
# read, or from pinning a service image the release never built.
# ref is derived from the tag unless --ref names one. A pinned CalVer tag names
# the commit its images were built from, so its compose file asks only for
# variables those images read and pins only images the release built. The moving
# tags v1 and latest map to main, and main's compose file can run ahead of the v1
# images until the image builds are dispatched again.
fluxer_fetch_stack() {
fluxer_say "Downloading the stack files from ref $opt_ref."
fluxer_stack_files > "$fluxer_scratch/files"
@@ -1237,6 +1239,14 @@ fluxer_env_scalar() {
printf '%s' "$fluxer_scalar"
}
fluxer_compose_value() {
eval "fluxer_cv=\${$1:-}"
if [ -z "$fluxer_cv" ]; then
fluxer_cv=$(fluxer_env_scalar "$1")
fi
printf '%s' "$fluxer_cv"
}
fluxer_read_compose_setting() {
fluxer_compose_file=${COMPOSE_FILE:-}
fluxer_compose_from="the environment"
@@ -1469,12 +1479,13 @@ fluxer_postgres_running() {
# the pull is the only way back across a schema change.
#
# By hand:
# docker compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom > backups/fluxer.dump
# docker compose exec -T postgres sh -c 'exec pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --format=custom' > backups/fluxer.dump
#
# The database and the role are both named fluxer and are fixed in
# docker-compose.yml. Keep -T. Without it Docker attaches a terminal to the
# command and the dump arrives corrupted, which is why the first five bytes are
# checked against the custom-format magic below rather than only the size.
# The postgres container's POSTGRES_USER and POSTGRES_DB follow
# FLUXER_POSTGRES_USERNAME and FLUXER_POSTGRES_DATABASE, so the command needs no
# names. Keep -T. Without it Docker attaches a terminal to the command and the
# dump arrives corrupted, which is why the first five bytes are checked against
# the custom-format magic below rather than only the size.
#
# The dump runs against the live stack. pg_dump reads inside one transaction, so
# it sees a consistent database without stopping anything. The volume copy below
@@ -1501,11 +1512,39 @@ $(fluxer_compose_error ' ')"
grep -qxF "$1" "$fluxer_scratch/all-services"
}
# The bundled postgres container takes POSTGRES_USER and POSTGRES_DB from
# FLUXER_POSTGRES_USERNAME and FLUXER_POSTGRES_DATABASE, and the image applies
# them only to an empty data directory. When those names point the apps at a
# database outside the stack, the bundled directory still holds the role and
# database it was first started with, so a dump that reads the container env asks
# for a role that is not there. The bundled service is idle in that shape and the
# dump skips it.
#
# By hand:
# grep -E '^FLUXER_POSTGRES_(HOST|URL)=' .env
fluxer_postgres_external() {
fluxer_pg_host=$(fluxer_compose_value FLUXER_POSTGRES_HOST)
if [ -n "$fluxer_pg_host" ] && [ "$fluxer_pg_host" != postgres ]; then
return 0
fi
fluxer_pg_url=$(fluxer_compose_value FLUXER_POSTGRES_URL)
[ -n "$fluxer_pg_url" ] || return 1
fluxer_pg_url_host=${fluxer_pg_url#*://}
fluxer_pg_url_host=${fluxer_pg_url_host%%[/?]*}
fluxer_pg_url_host=${fluxer_pg_url_host##*@}
fluxer_pg_url_host=${fluxer_pg_url_host%%:*}
[ "$fluxer_pg_url_host" != postgres ]
}
fluxer_dump_postgres() {
if ! fluxer_stack_defines_service postgres; then
fluxer_say 'Skipping the database dump. This stack defines no postgres service, so its database runs outside the stack and only the operator of that database can dump it.'
return 0
fi
if fluxer_postgres_external; then
fluxer_say 'Skipping the database dump. FLUXER_POSTGRES_HOST or FLUXER_POSTGRES_URL points the stack at a database outside it, so the bundled postgres service is idle and only the operator of that database can dump it.'
return 0
fi
if ! fluxer_postgres_running; then
fluxer_say 'Postgres is not running. Starting it for the dump.'
if ! $fluxer_engine compose up -d --wait postgres; then
@@ -1514,7 +1553,7 @@ fluxer_dump_postgres() {
fi
fluxer_dump_path="$fluxer_record/$FLUXER_DUMP_FILE"
fluxer_say 'Dumping the database.'
if ! $fluxer_engine compose exec -T postgres pg_dump -U fluxer -d fluxer --format=custom > "$fluxer_dump_path"; then
if ! $fluxer_engine compose exec -T postgres sh -c 'exec pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --format=custom' > "$fluxer_dump_path"; then
rm -f "$fluxer_dump_path"
fluxer_fail 7 'pg_dump failed. The instance is untouched.'
fi
@@ -1627,7 +1666,17 @@ fluxer_backup() {
}
fluxer_postgres_major() {
sed -n 's/^[[:space:]]*image:[[:space:]]*postgres:\([0-9][0-9]*\).*/\1/p' "$1" | head -n 1
fluxer_pg_image=$(sed -n 's/^[[:space:]]*image:[[:space:]]*\(postgres:[^[:space:]]*\).*/\1/p' "$1" | head -n 1)
if [ -z "$fluxer_pg_image" ]; then
fluxer_pg_image=$(sed -n 's/^[[:space:]]*image:[[:space:]]*${FLUXER_POSTGRES_IMAGE:-\([^}]*\)}.*/\1/p' "$1" | head -n 1)
if [ -n "$fluxer_pg_image" ] && [ -n "$(fluxer_compose_value FLUXER_POSTGRES_IMAGE)" ]; then
fluxer_pg_image=$(fluxer_compose_value FLUXER_POSTGRES_IMAGE)
fi
fi
fluxer_pg_image=${fluxer_pg_image%%@*}
case ${fluxer_pg_image##*/} in
*:*) printf '%s\n' "${fluxer_pg_image##*:}" | sed -n 's/^\([0-9][0-9]*\).*/\1/p' ;;
esac
}
# A newer Postgres major does not read the data directory an older major wrote,