diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..4ff3bd7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Always use LF endings.
+* text eol=lf
\ No newline at end of file
diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index 213d5b8..ae26510 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -10,7 +10,7 @@ jobs:
steps:
-
name: Checkout Branch ${{ github.ref_name }}
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
-
name: Create Pull Request
uses: bfren/pull-request@v2
diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml
index 79579e1..d1ef8e5 100644
--- a/.github/workflows/dev.yml
+++ b/.github/workflows/dev.yml
@@ -12,7 +12,7 @@ jobs:
steps:
-
name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
build:
strategy:
fail-fast: false
@@ -22,7 +22,7 @@ jobs:
steps:
-
name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
-
name: Get repository name
run: echo "REPOSITORY_NAME=$(echo '${{ github.repository }}' | awk -F '/' '{print $2}')" >> $GITHUB_ENV
@@ -35,20 +35,20 @@ jobs:
id: version
-
name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
- uses: docker/login-action@v2
+ uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
id: docker_build
- uses: docker/build-push-action@v4
+ uses: docker/build-push-action@v5
with:
context: .
file: ./${{ matrix.postgresql }}/Dockerfile
@@ -59,7 +59,7 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: |
bfren/postgresql:postgresql${{ matrix.postgresql }}-dev
- bfren/postgresql:postgresql${{ matrix.postgresql }}-${{ steps.version.outputs.contents }}-beta
+ bfren/postgresql:postgresql${{ matrix.postgresql }}-${{ steps.version.outputs.contents }}-dev
-
name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index d9d4c8d..59ba126 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -15,7 +15,7 @@ jobs:
steps:
-
name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
-
name: Get repository name
run: echo "REPOSITORY_NAME=$(echo '${{ github.repository }}' | awk -F '/' '{print $2}')" >> $GITHUB_ENV
@@ -46,20 +46,20 @@ jobs:
id: version
-
name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
- uses: docker/login-action@v2
+ uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
id: docker_build
- uses: docker/build-push-action@v4
+ uses: docker/build-push-action@v5
with:
context: .
file: ./${{ matrix.postgresql }}/Dockerfile
diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml
index 14fd935..7fc7506 100644
--- a/.github/workflows/update-readme.yml
+++ b/.github/workflows/update-readme.yml
@@ -15,10 +15,10 @@ jobs:
shell: bash
-
name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
-
name: Login to DockerHub
- uses: docker/login-action@v2
+ uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
diff --git a/12/Dockerfile b/12/Dockerfile
index 75c2b3d..be7cbb3 100644
--- a/12/Dockerfile
+++ b/12/Dockerfile
@@ -1,21 +1,21 @@
-FROM bfren/alpine-s6:alpine3.18-4.5.9
+FROM bfren/alpine-s6:alpine3.18-5.0.5
LABEL org.opencontainers.image.source="https://github.com/bfren/docker-postgresql"
ARG BF_IMAGE
ARG BF_VERSION
-ENV \
- # set to "1" to compress backup sql files
- POSTGRESQL_BACKUP_COMPRESS_FILES="0" \
- # the number of days after which backups will be deleted
- POSTGRESQL_BACKUP_KEEP_FOR_DAYS="28"
-
EXPOSE 5432
COPY ./overlay /
COPY ./12/overlay /
+ENV \
+ # set to "1" to compress backup sql files
+ BF_PG_BACKUP_COMPRESS_FILES="0" \
+ # the duration for which backups will be kept
+ BF_PG_BACKUP_KEEP_FOR="28day"
+
RUN bf-install
-VOLUME [ "/data", "/backup" ]
+VOLUME [ "/backup", "/data" ]
diff --git a/12/overlay/tmp/POSTGRESQL_BUILD b/12/overlay/tmp/POSTGRESQL_BUILD
index a93a48b..59321dc 100644
--- a/12/overlay/tmp/POSTGRESQL_BUILD
+++ b/12/overlay/tmp/POSTGRESQL_BUILD
@@ -1 +1 @@
-12.16-r0
\ No newline at end of file
+12.17-r0
\ No newline at end of file
diff --git a/12/overlay/tmp/POSTGRESQL_MINOR b/12/overlay/tmp/POSTGRESQL_MINOR
index 499fd8b..339dacb 100644
--- a/12/overlay/tmp/POSTGRESQL_MINOR
+++ b/12/overlay/tmp/POSTGRESQL_MINOR
@@ -1 +1 @@
-12.16
\ No newline at end of file
+12.17
\ No newline at end of file
diff --git a/13/Dockerfile b/13/Dockerfile
index e42116c..471eafc 100644
--- a/13/Dockerfile
+++ b/13/Dockerfile
@@ -1,21 +1,21 @@
-FROM bfren/alpine-s6:alpine3.18-4.5.9
+FROM bfren/alpine-s6:alpine3.18-5.0.5
LABEL org.opencontainers.image.source="https://github.com/bfren/docker-postgresql"
ARG BF_IMAGE
ARG BF_VERSION
-ENV \
- # set to "1" to compress backup sql files
- POSTGRESQL_BACKUP_COMPRESS_FILES="0" \
- # the number of days after which backups will be deleted
- POSTGRESQL_BACKUP_KEEP_FOR_DAYS="28"
-
EXPOSE 5432
COPY ./overlay /
COPY ./13/overlay /
+ENV \
+ # set to "1" to compress backup sql files
+ BF_PG_BACKUP_COMPRESS_FILES="0" \
+ # the duration for which backups will be kept
+ BF_PG_BACKUP_KEEP_FOR="28day"
+
RUN bf-install
-VOLUME [ "/data", "/backup" ]
+VOLUME [ "/backup", "/data" ]
diff --git a/13/overlay/tmp/POSTGRESQL_BUILD b/13/overlay/tmp/POSTGRESQL_BUILD
index 197b9b2..8b980ab 100644
--- a/13/overlay/tmp/POSTGRESQL_BUILD
+++ b/13/overlay/tmp/POSTGRESQL_BUILD
@@ -1 +1 @@
-13.12-r0
\ No newline at end of file
+13.13-r0
\ No newline at end of file
diff --git a/13/overlay/tmp/POSTGRESQL_MINOR b/13/overlay/tmp/POSTGRESQL_MINOR
index 2476028..1f8009c 100644
--- a/13/overlay/tmp/POSTGRESQL_MINOR
+++ b/13/overlay/tmp/POSTGRESQL_MINOR
@@ -1 +1 @@
-13.12
\ No newline at end of file
+13.13
\ No newline at end of file
diff --git a/14/Dockerfile b/14/Dockerfile
index c0470b2..5138a2d 100644
--- a/14/Dockerfile
+++ b/14/Dockerfile
@@ -1,21 +1,21 @@
-FROM bfren/alpine-s6:alpine3.18-4.5.9
+FROM bfren/alpine-s6:alpine3.18-5.0.5
LABEL org.opencontainers.image.source="https://github.com/bfren/docker-postgresql"
ARG BF_IMAGE
ARG BF_VERSION
-ENV \
- # set to "1" to compress backup sql files
- POSTGRESQL_BACKUP_COMPRESS_FILES="0" \
- # the number of days after which backups will be deleted
- POSTGRESQL_BACKUP_KEEP_FOR_DAYS="28"
-
EXPOSE 5432
COPY ./overlay /
COPY ./14/overlay /
+ENV \
+ # set to "1" to compress backup sql files
+ BF_PG_BACKUP_COMPRESS_FILES="0" \
+ # the duration for which backups will be kept
+ BF_PG_BACKUP_KEEP_FOR="28day"
+
RUN bf-install
-VOLUME [ "/data", "/backup" ]
+VOLUME [ "/backup", "/data" ]
diff --git a/14/overlay/tmp/POSTGRESQL_BUILD b/14/overlay/tmp/POSTGRESQL_BUILD
index 4ee21b4..595925a 100644
--- a/14/overlay/tmp/POSTGRESQL_BUILD
+++ b/14/overlay/tmp/POSTGRESQL_BUILD
@@ -1 +1 @@
-14.9-r0
\ No newline at end of file
+14.10-r0
\ No newline at end of file
diff --git a/14/overlay/tmp/POSTGRESQL_MINOR b/14/overlay/tmp/POSTGRESQL_MINOR
index 94837c4..d3a61db 100644
--- a/14/overlay/tmp/POSTGRESQL_MINOR
+++ b/14/overlay/tmp/POSTGRESQL_MINOR
@@ -1 +1 @@
-14.9
\ No newline at end of file
+14.10
\ No newline at end of file
diff --git a/15/Dockerfile b/15/Dockerfile
index b4e77e8..2569394 100644
--- a/15/Dockerfile
+++ b/15/Dockerfile
@@ -1,21 +1,21 @@
-FROM bfren/alpine-s6:alpine3.18-4.5.9
+FROM bfren/alpine-s6:alpine3.18-5.0.5
LABEL org.opencontainers.image.source="https://github.com/bfren/docker-postgresql"
ARG BF_IMAGE
ARG BF_VERSION
-ENV \
- # set to "1" to compress backup sql files
- POSTGRESQL_BACKUP_COMPRESS_FILES="0" \
- # the number of days after which backups will be deleted
- POSTGRESQL_BACKUP_KEEP_FOR_DAYS="28"
-
EXPOSE 5432
COPY ./overlay /
COPY ./15/overlay /
+ENV \
+ # set to "1" to compress backup sql files
+ BF_PG_BACKUP_COMPRESS_FILES="0" \
+ # the duration for which backups will be kept
+ BF_PG_BACKUP_KEEP_FOR="28day"
+
RUN bf-install
-VOLUME [ "/data", "/backup" ]
+VOLUME [ "/backup", "/data" ]
diff --git a/15/overlay/tmp/POSTGRESQL_BUILD b/15/overlay/tmp/POSTGRESQL_BUILD
index c50dc6e..bbab991 100644
--- a/15/overlay/tmp/POSTGRESQL_BUILD
+++ b/15/overlay/tmp/POSTGRESQL_BUILD
@@ -1 +1 @@
-15.4-r0
\ No newline at end of file
+15.5-r0
\ No newline at end of file
diff --git a/15/overlay/tmp/POSTGRESQL_MINOR b/15/overlay/tmp/POSTGRESQL_MINOR
index 441e3fb..474b680 100644
--- a/15/overlay/tmp/POSTGRESQL_MINOR
+++ b/15/overlay/tmp/POSTGRESQL_MINOR
@@ -1 +1 @@
-15.4
\ No newline at end of file
+15.5
\ No newline at end of file
diff --git a/Dockerfile.esh b/Dockerfile.esh
index 5c6bab7..0be9b3d 100644
--- a/Dockerfile.esh
+++ b/Dockerfile.esh
@@ -1,21 +1,21 @@
-FROM bfren/alpine-s6:alpine3.18-<%= ${BASE_REVISION} %>
+FROM bfren/alpine-s6:alpine3.18-<%= ${BASE_VERSION} %>
LABEL org.opencontainers.image.source="https://github.com/bfren/docker-postgresql"
ARG BF_IMAGE
ARG BF_VERSION
-ENV \
- # set to "1" to compress backup sql files
- POSTGRESQL_BACKUP_COMPRESS_FILES="0" \
- # the number of days after which backups will be deleted
- POSTGRESQL_BACKUP_KEEP_FOR_DAYS="28"
-
EXPOSE 5432
COPY ./overlay /
COPY ./<%= ${POSTGRESQL_MAJOR} %>/overlay /
+ENV \
+ # set to "1" to compress backup sql files
+ BF_PG_BACKUP_COMPRESS_FILES="0" \
+ # the duration for which backups will be kept
+ BF_PG_BACKUP_KEEP_FOR="28day"
+
RUN bf-install
-VOLUME [ "/data", "/backup" ]
+VOLUME [ "/backup", "/data" ]
diff --git a/README.md b/README.md
index 26aa0d5..c282767 100644
--- a/README.md
+++ b/README.md
@@ -40,29 +40,28 @@ See [For Backups](#for-backups) for configuration variables.
### For Backups
-| Variable | Values | Description | Default |
-| ---------------------------------- | ---------------------------- | -------------------------------------------------------- | ------- |
-| `POSTGRESQL_BACKUP_COMPRESS_FILES` | 0 or 1 | Whether or not to compress backup files (using gzip). | 0 |
-| `POSTGRESQL_BACKUP_KEEP_FOR_DAYS` | 0: keep forever
Num: days | How many days to keep backups before auto-deleting them. | 14 |
+| Variable | Values | Description | Default |
+| ----------------------------- | ------------- | ----------------------------------------------------- | --------- |
+| `PG_BACKUP_COMPRESS_FILES` | 0 or 1 | Whether or not to compress backup files (using bzip). | 0 |
+| `BF_PG_BACKUP_KEEP_FOR` | Nu duration | The length of time to keep backups. | 28day |
### For Database
-| Variable | Values | Description | Default |
-| --------------------- | ------ | ----------------------------------------------------------------------------------------- | ----------------- |
-| `POSTGRESQL_USERNAME` | string | Application username - will be used as database name if `POSTGRESQL_DATABASE` is not set. | *None* - required |
-| `POSTGRESQL_PASSWORD` | string | Application password. | *None* - required |
-| `POSTGRESQL_DATABASE` | string | Database name(s) - multiple databases can be separated by a comma. | *None* |
+| Variable | Values | Description | Default |
+| ----------------- | ------ | -------------------------------------------------------------------------------------------------------- | --------- |
+| `PG_APPLICATION` | string | Application name - will be used as `PG_DATABASE`, `PG_PASSWORD` and `PG_USERNAME` if they are not set. | *None* |
+| `PG_DATABASE` | string | Database name(s) - multiple databases can be separated by a comma. | *None* |
+| `PG_PASSWORD` | string | Application password. | *None* |
+| `PG_USERNAME` | string | Application username. | *None* |
## Helper Functions
-| Function | Purpose | Usage |
-| ------------ | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
-| `db-backup` | Run backup manually. | `docker exec <> db-backup` |
-| `db-exists` | Echoes '0' or '1' depending on whether or not the specified database exists on the server. | `docker exec <> db-exists "foo"` |
-| `db-export` | Dumps the specified database as a SQL file to the root of the `/backup` volume. | `docker exec <> db-export <>` |
-| `db-import` | Executes all files in the root of the `/backup` volume. | `docker exec <> db-import` |
-| `db-restore` | Deletes all files in `/data` volume, then shuts container down - on restart, the container will restore from the specified backup. | `docker exec <> db-restore 202107180500` |
-| `db-stop` | Stops the database server (will automatically terminate the container). | `docker exec <> db-stop` |
+| Function | Arguments | Purpose | Usage |
+| ------------- | ----------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------- |
+| `pg-dump` | *None* | Run backup manually. | `docker exec <> pg-dump` |
+| `pg-export` | 1: Database name | Dumps the specified database as a SQL file to the root of the `/backup` volume. | `docker exec <> pg-export <>` |
+| `pg-import` | 1: Database name | Executes all files in the root of the `/backup` volume. | `docker exec <> pg-import <>` |
+| `pg-restore` | 1: Backup set | Deletes all files in `/data` volume, then restores from the specified backup dump. | `docker exec <> pg-restore 202107180500` |
## Licence
diff --git a/VERSION b/VERSION
index 47ccbfa..56fea8a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.3.29
\ No newline at end of file
+3.0.0
\ No newline at end of file
diff --git a/VERSION_MAJOR b/VERSION_MAJOR
index d8263ee..e440e5c 100644
--- a/VERSION_MAJOR
+++ b/VERSION_MAJOR
@@ -1 +1 @@
-2
\ No newline at end of file
+3
\ No newline at end of file
diff --git a/VERSION_MINOR b/VERSION_MINOR
index c0943d3..f398a20 100644
--- a/VERSION_MINOR
+++ b/VERSION_MINOR
@@ -1 +1 @@
-2.3
\ No newline at end of file
+3.0
\ No newline at end of file
diff --git a/generate-dockerfiles.sh b/generate-dockerfiles.sh
index 100cbdc..e0ac7a1 100755
--- a/generate-dockerfiles.sh
+++ b/generate-dockerfiles.sh
@@ -4,8 +4,8 @@ set -euo pipefail
docker pull bfren/alpine
-BASE_REVISION="4.5.9"
-echo "Base: ${BASE_REVISION}"
+BASE_VERSION="5.0.5"
+echo "Base: ${BASE_VERSION}"
POSTGRESQL_VERSIONS="12 13 14 15"
for V in ${POSTGRESQL_VERSIONS} ; do
@@ -17,7 +17,7 @@ for V in ${POSTGRESQL_VERSIONS} ; do
-e BF_DEBUG=0 \
bfren/alpine esh \
"/ws/Dockerfile.esh" \
- BASE_REVISION=${BASE_REVISION} \
+ BASE_VERSION=${BASE_VERSION} \
POSTGRESQL_MAJOR=${V}
)
diff --git a/overlay/etc/bf/ch.d/10-postgresql b/overlay/etc/bf/ch.d/10-postgresql
index 4177848..8fd4af9 100644
--- a/overlay/etc/bf/ch.d/10-postgresql
+++ b/overlay/etc/bf/ch.d/10-postgresql
@@ -1,4 +1,3 @@
-/backup postgres:postgres 0770 0750
-/data postgres:postgres 0770 0750
-/run/postgresql postgres:postgres 0770 0750
-/usr/bin/bf/db-exists root:root 0555
+/backup postgres:postgres 0600 0700
+/data postgres:postgres 0600 0700
+/run/postgresql postgres:postgres 0600 0700
diff --git a/overlay/etc/bf/init.d/10-env b/overlay/etc/bf/init.d/10-env
deleted file mode 100644
index 6b230d9..0000000
--- a/overlay/etc/bf/init.d/10-env
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Add environment variables.
-#======================================================================================================================
-
-# Library configuration
-bf-env "POSTGRESQL_LIB" "${BF_LIB}/postgresql"
-
-POSTGRESQL_BACKUP="/backup"
-bf-env "POSTGRESQL_DATA" "/data"
-bf-env "POSTGRESQL_BACKUP" "${POSTGRESQL_BACKUP}"
-
-bf-env "POSTGRESQL_BACKUP_FILENAME" "dump"
-bf-env "POSTGRESQL_RESTORE" "${POSTGRESQL_BACKUP}/restore.sql"
-
-bf-env "POSTGRESQL_SERVER_VERSION" `cat /usr/libexec/postgresql/PG_VERSION`
-
-PG_VERSION="/data/PG_VERSION"
-if [ -f "${PG_VERSION}" ]; then
- bf-env "POSTGRESQL_DATA_VERSION" `cat ${PG_VERSION}`
-fi
diff --git a/overlay/etc/bf/init.d/10-env.nu b/overlay/etc/bf/init.d/10-env.nu
new file mode 100644
index 0000000..3fa91c8
--- /dev/null
+++ b/overlay/etc/bf/init.d/10-env.nu
@@ -0,0 +1,30 @@
+use bf
+bf env load
+
+# Set environment variables
+def main [] {
+ let data = "/data"
+ bf env set PG_DATA $data
+ bf env set PG_DATA_CONF $"($data)/postgresql.conf"
+ bf env set PG_DATA_HBA_CONF $"($data)/pg_hba.conf"
+
+ let backup = "/backup"
+ let backup_basename = "dump"
+ bf env set PG_BACKUP $backup
+ bf env set PG_DUMP_BASENAME $backup_basename
+ bf env set PG_DUMP_FILE_WITHOUT_EXT $"($backup)/($backup_basename)"
+
+ let version = "PG_VERSION"
+ let data_version_file = $"($data)/($version)"
+ bf env set PG_DATA_VERSION (bf fs read --quiet $data_version_file)
+ bf env set PG_DATA_VERSION_FILE $data_version_file
+ bf env set PG_SERVER_VERSION (bf fs read --quiet $"/usr/libexec/postgresql/($version)")
+
+ let application = bf env --safe PG_APPLICATION
+ bf env set PG_USERNAME (bf env PG_USERNAME $application)
+ bf env set PG_PASSWORD (bf env PG_PASSWORD $application)
+ bf env set PG_DATABASE (bf env PG_DATABASE $application)
+
+ # return nothing
+ return
+}
diff --git a/overlay/etc/bf/init.d/11-user b/overlay/etc/bf/init.d/11-user
deleted file mode 100644
index 3c75ba8..0000000
--- a/overlay/etc/bf/init.d/11-user
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Check for application user and password.
-#======================================================================================================================
-
-[[ -z "${POSTGRESQL_USERNAME-}" || -z "${POSTGRESQL_PASSWORD-}" ]] \
- && bf-error "POSTGRESQL_USERNAME and POSTGRESQL_PASSWORD must be set."
-
-
-#======================================================================================================================
-# Add user with password.
-#======================================================================================================================
-
-# add user if it doesn't exist
-if [ -z "$(getent passwd ${POSTGRESQL_USERNAME})" ] ; then
-
- bf-echo "Adding user ${POSTGRESQL_USERNAME}..."
- bf-adduser ${POSTGRESQL_USERNAME} 1001
- echo -e "${POSTGRESQL_PASSWORD}\n${POSTGRESQL_PASSWORD}" | passwd ${POSTGRESQL_USERNAME}
- bf-done
-
-else
-
- bf-debug "User ${POSTGRESQL_USERNAME} exists."
-
-fi
diff --git a/overlay/etc/bf/init.d/11-user.nu b/overlay/etc/bf/init.d/11-user.nu
new file mode 100644
index 0000000..48c25c1
--- /dev/null
+++ b/overlay/etc/bf/init.d/11-user.nu
@@ -0,0 +1,20 @@
+use bf
+bf env load
+
+# Ensure specified user exists
+def main [] {
+ # get variables
+ let user = bf env PG_USERNAME
+ let pass = bf env PG_PASSWORD
+ if $user == "" or $pass == "" { bf write error "You must set PG_USERNAME and PG_PASSWORD (or PG_APPLICATION)." }
+
+ # if user exists, return
+ if (bf user exists $user) {
+ bf write $"User ($user) already exists."
+ return
+ }
+
+ # create user account and set password
+ bf user add --uid 1001 $user
+ { $"($pass)\n($pass)" | ^passwd $user } | bf handle
+}
diff --git a/overlay/etc/bf/init.d/12-postgresql-init b/overlay/etc/bf/init.d/12-postgresql-init
deleted file mode 100644
index 83daed6..0000000
--- a/overlay/etc/bf/init.d/12-postgresql-init
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Start server.
-#======================================================================================================================
-
-start () {
-
- # initialise data directory
- bf-debug "Running db-init."
- s6-setuidgid postgres initdb -D "${POSTGRESQL_DATA}"
-
- # generate configuration
- db-generate-config
-
- # start server
- bf-echo "Starting PostgreSQL for initialisation."
- s6-setuidgid postgres pg_ctl start -D "${POSTGRESQL_DATA}"
-
-}
-
-
-#======================================================================================================================
-# Stop server.
-#======================================================================================================================
-
-stop () {
- bf-echo "Stopping PostgreSQL."
- s6-setuidgid postgres pg_ctl stop -D "${POSTGRESQL_DATA}"
-}
-
-
-#======================================================================================================================
-# Check data version against server version.
-#======================================================================================================================
-
-[[ -f "/data/PG_VERSION" ]] && POSTGRESQL_DATA_VERSION=`cat /data/PG_VERSION`
-POSTGRESQL_SERVER_VERSION=`cat /usr/libexec/postgresql/PG_VERSION`
-
-if [[ -z "${POSTGRESQL_DATA_VERSION-}" ]] || [[ "${POSTGRESQL_DATA_VERSION}" = "${POSTGRESQL_SERVER_VERSION}" ]] ; then
- bf-debug "Versions ok."
-else
- bf-notok "PostgreSQL server (v${POSTGRESQL_SERVER_VERSION}) does not match data (v${POSTGRESQL_DATA_VERSION})."
- bf-notok "You must upgrade the data or use a version of this image that matches the data version."
- bf-notok "Container will now quit."
- s6-svscanctl -t ${S6_SERVICES}
- exit 1
-fi
-
-
-#======================================================================================================================
-# Check for restore file.
-#======================================================================================================================
-
-if [ -f "${POSTGRESQL_RESTORE}" ] ; then
-
- # delete existing files
- bf-debug "Deleting existing files."
- bf-rmrf "${POSTGRESQL_DATA}/*"
-
- # run restore
- start
- bf-debug "Restoring server."
- s6-setuidgid postgres psql -f "${POSTGRESQL_RESTORE}"
- stop
-
- # delete restore file
- rm "${POSTGRESQL_RESTORE}"
-
-fi
-
-
-#======================================================================================================================
-# Run library init executable.
-#======================================================================================================================
-
-if [ ! -f ${POSTGRESQL_DATA}/PG_VERSION ] ; then
-
- # run init
- start
- bf-debug "Initialising server."
- s6-setuidgid postgres ${POSTGRESQL_LIB}/init
- stop
-
-fi
-
-
-#======================================================================================================================
-# Be friendly.
-#======================================================================================================================
-
-bf-debug "Server ready."
diff --git a/overlay/etc/bf/init.d/12-postgresql-init.nu b/overlay/etc/bf/init.d/12-postgresql-init.nu
new file mode 100644
index 0000000..e0b54ab
--- /dev/null
+++ b/overlay/etc/bf/init.d/12-postgresql-init.nu
@@ -0,0 +1,54 @@
+use bf
+use bf-postgresql
+use bf-s6
+bf env load
+
+def main [] {
+ # check data version against server version
+ let data_version = bf env PG_DATA_VERSION 0
+ let server_version = bf env PG_SERVER_VERSION 0
+ if $data_version == $server_version {
+ bf write debug "Versions match."
+ } else if $data_version > 0 {
+ bf write notok $"PostgreSQL server v($server_version) does not match data v($data_version)."
+ bf write notok "You must upgrade the data or use a version of this image that matches the data version."
+ bf write notok "This container will now quit."
+ bf-s6 cont terminate
+ exit 1
+ }
+
+ # run restore
+ bf-postgresql restore
+
+ # create data if it doesn't exist
+ if (bf env PG_DATA_VERSION_FILE | bf fs is_not_file) { create_empty }
+
+ # ready to go!
+ bf write ok "Server ready."
+}
+
+# Create empty database(s)
+def create_empty [] {
+ bf write "Initialising empty data." create_empty
+
+ # get variables
+ let user = bf env PG_USERNAME
+ let pass = bf env PG_PASSWORD
+
+ # start server
+ bf-postgresql ctl init
+ bf-postgresql ctl start
+
+ # create role for user
+ bf write debug $" .. creating role ($user)"
+ { $"($pass)\n($pass)" | ^pg createuser --superuser --pwprompt $user } | bf handle create_empty
+
+ # create database(s)
+ bf env PG_DATABASE | split row "," | each {|x|
+ bf write debug $" .. creating database ($x)"
+ { ^pg createdb $"($x)" $"--owner=($user)" } | bf handle create_empty
+ }
+
+ # stop server
+ bf-postgresql ctl stop
+}
diff --git a/overlay/etc/bf/init.d/13-cron b/overlay/etc/bf/init.d/13-cron
deleted file mode 100644
index d69ef22..0000000
--- a/overlay/etc/bf/init.d/13-cron
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Generate crontab and append backup task - set the minutes to a random number so multiple containers on one host don't
-# all try to backup at the same time.
-#======================================================================================================================
-
-bf-echo "Generating crontab..."
-CRONTAB=/etc/crontabs/root
-bf-esh \
- ${BF_TEMPLATES}/crontab.esh \
- ${CRONTAB}
-echo "$((1 + ${RANDOM} % 59)) */8 * * * db-backup" >> /etc/crontabs/root >> ${CRONTAB}
-bf-done
diff --git a/overlay/etc/bf/init.d/13-cron.nu b/overlay/etc/bf/init.d/13-cron.nu
new file mode 100644
index 0000000..f23e733
--- /dev/null
+++ b/overlay/etc/bf/init.d/13-cron.nu
@@ -0,0 +1,6 @@
+use bf
+use bf-s6
+bf env load
+
+# Append backup task to crontab
+def main [] { bf-s6 crontab append --min (random int 1..59) --hour "*/8" "pg-dump" }
diff --git a/overlay/etc/nu/scripts/bf-postgresql/conf.nu b/overlay/etc/nu/scripts/bf-postgresql/conf.nu
new file mode 100644
index 0000000..945b64a
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/conf.nu
@@ -0,0 +1,7 @@
+use bf
+
+# Generate data configuration files
+export def generate [] {
+ bf esh template (bf env PG_DATA_CONF)
+ bf esh template (bf env PG_DATA_HBA_CONF)
+}
diff --git a/overlay/etc/nu/scripts/bf-postgresql/ctl.nu b/overlay/etc/nu/scripts/bf-postgresql/ctl.nu
new file mode 100644
index 0000000..812099f
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/ctl.nu
@@ -0,0 +1,28 @@
+use bf
+use conf.nu
+
+# Execute a pg_ctl command as the PostgreSQL user, using the correct data directory
+def cmd [
+ command: string # The pg_ctl command to run
+] {
+ try {
+ ^pg pg_ctl $command -D $"(bf env PG_DATA)"
+ } catch {
+ bf write error $"There was an error running pg_ctl ($command)."
+ }
+}
+
+# Use pg_ctl to initialise PostgreSQL server and then regenerate configuration
+export def init [] { cmd init ; conf generate }
+
+# Use pg_ctl to restart PostgreSQL server
+export def restart [] { cmd restart }
+
+# Use pg_ctl to start PostgreSQL status
+export def start [] { cmd start }
+
+# Use pg_ctl to get PostgreSQL server status
+export def status [] { cmd status }
+
+# Use pg_ctl to stop the PostgreSQL server
+export def stop [] { cmd stop }
diff --git a/overlay/etc/nu/scripts/bf-postgresql/db.nu b/overlay/etc/nu/scripts/bf-postgresql/db.nu
new file mode 100644
index 0000000..768f0e3
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/db.nu
@@ -0,0 +1,34 @@
+use bf
+
+# Returns true if database $name exists in the cluster
+export def exists [
+ name: string # Database name
+] {
+ $name in (get_all)
+}
+
+# Dump a database
+export def dump [
+ name: string # The name of the database to dump
+ file: string # The path to save the dump script to
+] {
+ # ensure the database exists
+ if not (exists $name) { bf write error $"Database ($name) does not exist." export }
+
+ # dump database and save to specified file
+ { ^pg pg_dump --clean --if-exists $name } | bf handle -s {|x| $x | save --force $file } ctl/dump
+}
+
+# Get a list of databases, ignoring system databases
+export def get_all [] {
+ # ignore these database
+ let ignore = [
+ "postgres"
+ "template0"
+ "template1"
+ ]
+
+ # execute SQL and process response
+ let sql = "SELECT datname FROM pg_database;"
+ { ^pg psql -c $sql | ^tail -n+3 | ^head -n-2 | ^xargs } | bf handle -d "Selecting PostgreSQL databases" ctl/get_all | split row " " | where {|x| $x not-in $ignore } | compact
+}
diff --git a/overlay/etc/nu/scripts/bf-postgresql/dump.nu b/overlay/etc/nu/scripts/bf-postgresql/dump.nu
new file mode 100644
index 0000000..a9ad8dd
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/dump.nu
@@ -0,0 +1,74 @@
+use bf
+use db.nu
+
+# Backup the cluster to a dump file, compressing if required
+export def main [] {
+ # set variables
+ bf write $"Dumping data cluster." dump
+
+ # create backup directories
+ let backup_dir = create_backup_dir
+ let temp_dir = create_temp_dir
+
+ # dump cluster and save to dump file
+ let dump_file = $"($temp_dir)/(bf env PG_DUMP_BASENAME).sql"
+ bf write debug $" .. to ($dump_file)" dump
+ { ^pg pg_dumpall --clean --if-exists } | bf handle -s {|x| $x | save --force $dump_file } dump
+
+ # compress dump file
+ if (bf env check PG_BACKUP_COMPRESS_FILES) {
+ bf write debug " .. compressing dump file" dump
+ { ^pg bzip2 $dump_file } | bf handle dump
+ }
+
+ # get list of individual databases and back them up
+ db get_all | each {|x|
+ # dump database to backup file
+ bf write debug $" .. backing up database ($x)" dump
+ let backup_file = $"($temp_dir)/($x).sql"
+ db dump $x $backup_file
+
+ # compress backup file
+ if (bf env check PG_BACKUP_COMPRESS_FILES) {
+ bf write debug " compressing backup file" dump
+ { ^pg bzip2 $backup_file } | bf handle dump
+ }
+ }
+
+ # move files to backup directory
+ bf write debug $" .. moving files to ($backup_dir)" dump
+ mv $"($temp_dir)/*" $backup_dir
+
+ # delete temporary directory
+ bf write debug $" .. deleting ($temp_dir)" dump
+ rm -rf $temp_dir
+
+ # cleanup old backup files
+ bf write debug " .. removing expired backup files" dump
+ bf del old --type d (bf env PG_BACKUP) (bf env PG_BACKUP_KEEP_FOR | into duration)
+
+ # if we get here there have been no errors
+ bf write ok "Done." dump
+}
+
+# Create a backup directory
+def create_backup_dir [] {
+ # create temporary directory
+ let date = date now | format date "%Y%m%d%H%M"
+ let dir = $"(bf env PG_BACKUP)/($date)"
+ mkdir $dir
+
+ # return if directory exists
+ if ($dir | bf fs is_not_dir) { bf write error "Unable to create backup directory." dump/create_backup_dir }
+ $dir
+}
+
+# Create a temporary directory
+def create_temp_dir [] {
+ # create temporary directory
+ let dir = { ^mktemp -d -t backup.XXXXXX } | bf handle dump/create_temp_dir
+
+ # return if directory exists
+ if ($dir | bf fs is_not_dir) { bf write error "Unable to create temporary directory." dump/create_temp_dir }
+ $dir
+}
diff --git a/overlay/etc/nu/scripts/bf-postgresql/export.nu b/overlay/etc/nu/scripts/bf-postgresql/export.nu
new file mode 100644
index 0000000..40cba47
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/export.nu
@@ -0,0 +1,17 @@
+use bf
+use db.nu
+
+# Database $name will be exported as a sql file to the root backup directory
+export def main [
+ name: string # The name of the database to export
+] {
+ # create path to export file
+ let export_file = $"(bf env PG_BACKUP)/($name).sql"
+
+ # dump database to file
+ bf write $"Dumping ($name) to ($export_file)." export
+ db dump $name $export_file
+
+ # if we get here there have been no errors
+ bf write ok "Done." export
+}
diff --git a/overlay/etc/nu/scripts/bf-postgresql/import.nu b/overlay/etc/nu/scripts/bf-postgresql/import.nu
new file mode 100644
index 0000000..ad6ecf0
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/import.nu
@@ -0,0 +1,26 @@
+use bf
+use db.nu
+use ctl.nu
+
+# A file named $name.sql will be used from the root of the /backup directory
+export def main [
+ name: string # The name of the database to import
+] {
+ # ensure the file exists
+ let import_file = $"(bf env PG_BACKUP)/($name).sql"
+ if ($import_file | bf fs is_not_file) { bf write error $"Cannot find import file ($import_file)." import }
+
+ # ensure the database exists
+ bf write $"Importing database ($name) from sql file." import
+ if not (db exists $name) {
+ bf write debug " .. creating database"
+ { ^pg createdb $"($name)" $"--owner=(bf env PG_USERNAME)" } | bf handle import
+ }
+
+ # execute script file using psql
+ bf write debug " .. executing script file" import
+ { ^pg psql -f $import_file $name } | bf handle import
+
+ # if we get here there have been no errors
+ bf write ok "Done."
+}
diff --git a/overlay/etc/s6-overlay/s6-rc.d/postgres/dependencies.d/init b/overlay/etc/nu/scripts/bf-postgresql/mod.nu
similarity index 100%
rename from overlay/etc/s6-overlay/s6-rc.d/postgres/dependencies.d/init
rename to overlay/etc/nu/scripts/bf-postgresql/mod.nu
diff --git a/overlay/etc/nu/scripts/bf-postgresql/restore.nu b/overlay/etc/nu/scripts/bf-postgresql/restore.nu
new file mode 100644
index 0000000..298c2db
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/restore.nu
@@ -0,0 +1,94 @@
+use bf
+use ctl.nu
+
+# the name of the restoring environment variable
+const restoring = "PG_RESTORING"
+
+# Returns true if we are restoring a database backup
+export def is_restoring [] { bf env check $restoring }
+
+# Restore the data from a dump file
+export def main [] {
+ # if dump file does not exist, return
+ let dump_file = check_dump_file
+ if not $dump_file.exists {
+ bf write "Dump file not found." restore
+ return
+ }
+
+ # mark as restoring so the container is not brought down when we stop the PostgreSQL service
+ bf write "Restoring cluster from dump file." restore
+ bf env set $restoring 1
+
+ # stop the PostgreSQL service
+ bf write debug " .. stopping PostgreSQL service" restore
+ ctl stop
+
+ # delete data files
+ let data = bf env PG_DATA
+ bf write debug " .. deleting data files" restore
+ rm -rf $"($data)/*"
+
+ # restart the PostgreSQL service
+ bf write debug " .. reinitialising cluster" restore
+ ctl init
+ ctl start
+
+ # run restore
+ bf write debug " .. restoring data" restore
+ { ^pg psql -f $dump_file.path } | bf handle restore
+
+ # stop the PostgreSQL service
+ bf write debug " .. stopping PostgreSQL service" restore
+ ctl stop
+
+ # unset restoring variable and delete dump file
+ bf env unset $restoring
+ rm -f $dump_file.path
+
+ # if we get here there have been no errors
+ bf write ok "Done." restore
+}
+
+# Get details of a dump file - returns a record with the following values, having decompressed the file if required
+# - exists: bool Whether or not a dump file exists
+# - path: string Absolute path to the dump file if it exists, or null
+def check_dump_file [] {
+ # get file paths
+ let file = bf env PG_DUMP_FILE_WITHOUT_EXT
+ let compressed_file = $"($file).bz2"
+ let sql_file = $"($file).sql"
+
+ # if there is a compressed file, decompress it
+ if ($compressed_file | path exists) {
+ # Flags:
+ # -d Decompress
+ # -f Force
+ { ^pg bzip2 -d -f $compressed_file } | bf handle restore/check_dump_file
+ }
+
+ # if the sql file exists, return it
+ if ($sql_file | path exists) {
+ return {exists: true, path: $sql_file}
+ } else {
+ return {exists: false}
+ }
+}
+
+# Restore cluster from a backup dump file
+export def from [
+ backup: string # Restore the dump file this backup directory
+] {
+ # ensure requested backup directory exists
+ let backup_dir = $"(bf env PG_BACKUP)/($backup)"
+ if ($backup_dir | bf fs is_not_dir) { bf write error $"Backup directory ($backup_dir) does not exist." restore/from }
+
+ # ensure a dump file exists within requested backup directory
+ let dump_file = glob $"/backup/($backup)/(bf env PG_DUMP_BASENAME).*" | str join
+ if ($dump_file | bf fs is_not_file) { bf write error $"Cannot find a dump file in ($backup_dir)." restore/from }
+
+ # copy dump file to backup root and run restore function
+ bf write $"Copying dump file from backup ($backup)." restore/from
+ cp --force $dump_file (bf env PG_BACKUP)
+ main
+}
diff --git a/overlay/etc/nu/scripts/bf-postgresql/run.nu b/overlay/etc/nu/scripts/bf-postgresql/run.nu
new file mode 100644
index 0000000..95b2f17
--- /dev/null
+++ b/overlay/etc/nu/scripts/bf-postgresql/run.nu
@@ -0,0 +1,22 @@
+use bf
+use restore.nu
+
+# Run preflight checks before executing process
+export def preflight [] {
+ # load environment
+ bf env load
+
+ # manually set executing script
+ bf env x_set --override run postgresql
+
+ # exit if we are restoring
+ if (restore is_restoring) {
+ let for = 5sec
+ bf write $"A backup is being restored so sleep for ($for)."
+ sleep $for
+ exit 0
+ }
+
+ # if we get here we are ready to start PostgreSQL
+ bf write "Starting PostgreSQL."
+}
diff --git a/overlay/etc/s6-overlay/s6-rc.d/postgres/finish b/overlay/etc/s6-overlay/s6-rc.d/postgres/finish
deleted file mode 100644
index e37c787..0000000
--- a/overlay/etc/s6-overlay/s6-rc.d/postgres/finish
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E="${PWD##*/}/$(basename ${0})"
-
-
-#======================================================================================================================
-# Show helpful log message.
-#======================================================================================================================
-
-s6-setuidgid postgres ${POSTGRESQL_LIB}/finish
-bf-svc-finish -t
diff --git a/overlay/etc/s6-overlay/s6-rc.d/postgres/run b/overlay/etc/s6-overlay/s6-rc.d/postgres/run
deleted file mode 100644
index 4b70b6f..0000000
--- a/overlay/etc/s6-overlay/s6-rc.d/postgres/run
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E="${PWD##*/}/$(basename ${0})"
-
-
-#======================================================================================================================
-# Run as PostgreSQL user.
-#======================================================================================================================
-
-bf-echo "Starting PostgreSQL server."
-s6-setuidgid postgres postgres -D "${POSTGRESQL_DATA}"
diff --git a/overlay/etc/s6-overlay/s6-rc.d/user/contents.d/postgres b/overlay/etc/s6-overlay/s6-rc.d/postgresql/dependencies.d/init
similarity index 100%
rename from overlay/etc/s6-overlay/s6-rc.d/user/contents.d/postgres
rename to overlay/etc/s6-overlay/s6-rc.d/postgresql/dependencies.d/init
diff --git a/overlay/etc/s6-overlay/s6-rc.d/postgresql/finish b/overlay/etc/s6-overlay/s6-rc.d/postgresql/finish
new file mode 100644
index 0000000..9b91aa7
--- /dev/null
+++ b/overlay/etc/s6-overlay/s6-rc.d/postgresql/finish
@@ -0,0 +1,21 @@
+#!/usr/bin/nu
+
+use bf
+use bf-postgresql
+use bf-s6
+bf env load -x postgresql
+
+# Stop server and terminate container, unless we are restoring from a backup
+def main [...args] {
+ # check whether or not we are restoring from a backup
+ if (bf-postgresql restore is_restoring) {
+ bf write debug "A restore operation is running: do not stop PostgreSQL or terminate the container."
+ exit 0
+ }
+
+ # stop server gracefully
+ bf-postgresql ctl stop
+
+ # terminate container
+ bf-s6 svc finish --terminate
+}
diff --git a/overlay/usr/bin/bf/db-exists b/overlay/etc/s6-overlay/s6-rc.d/postgresql/run
similarity index 65%
rename from overlay/usr/bin/bf/db-exists
rename to overlay/etc/s6-overlay/s6-rc.d/postgresql/run
index c20e246..858026e 100644
--- a/overlay/usr/bin/bf/db-exists
+++ b/overlay/etc/s6-overlay/s6-rc.d/postgresql/run
@@ -1,19 +1,18 @@
-#!/command/with-contenv sh
+#!/bin/withenv sh
set -euo pipefail
-export BF_E=`basename ${0}`
#======================================================================================================================
-# Check arguments.
-# 1 Database name
+# Run preflight checks
#======================================================================================================================
-[[ -z "${1-}" ]] && bf-error "You must provide the name of the database to check."
+nu -c "use bf-postgresql run ; run preflight"
#======================================================================================================================
-# Query psql to see if database exists.
+# Run as PostgreSQL user
+# -D path to the data directory
#======================================================================================================================
-psql -U postgres -l | grep -w "${1}" | wc -l
+pg postgres -D "${BF_PG_DATA}"
diff --git a/overlay/etc/s6-overlay/s6-rc.d/postgres/type b/overlay/etc/s6-overlay/s6-rc.d/postgresql/type
similarity index 100%
rename from overlay/etc/s6-overlay/s6-rc.d/postgres/type
rename to overlay/etc/s6-overlay/s6-rc.d/postgresql/type
diff --git a/overlay/etc/s6-overlay/s6-rc.d/user/contents.d/postgresql b/overlay/etc/s6-overlay/s6-rc.d/user/contents.d/postgresql
new file mode 100644
index 0000000..e69de29
diff --git a/overlay/tmp/install b/overlay/tmp/install
index bb3ca96..9fe9497 100644
--- a/overlay/tmp/install
+++ b/overlay/tmp/install
@@ -1,52 +1,26 @@
-#!/bin/sh
+#!/usr/bin/nu
-set -euo pipefail
-export BF_E=`basename ${0}`
+use bf
+# Setup and install PostgreSQL
+def main [] {
+ # add PostgreSQL user
+ bf user add postgres
-#======================================================================================================================
-# Add postgres user.
-#======================================================================================================================
+ # get PostgreSQL version and install
+ cd /tmp
+ let version = bf fs read POSTGRESQL_BUILD
+ let major = $version | split row "." | first
+ bf write $"Installing PostgreSQL v($version)."
+ bf pkg install [$"postgresql($major)=($version)"]
-bf-adduser postgres
+ # save PostgreSQL version to build log
+ bf build add PostgreSQL $version
+ # create run directory
+ bf write "Creating PostgreSQL run directory."
+ mkdir /run/postgresql
-#======================================================================================================================
-# Get PostgreSQL version.
-#======================================================================================================================
-
-cd /tmp
-
-VERSION=$(cat POSTGRESQL_BUILD)
-bf-echo "PostgreSQL version ${VERSION}."
-
-
-#======================================================================================================================
-# Install PostgreSQL and dependencies.
-#======================================================================================================================
-
-bf-echo "Installing PostgreSQL v${VERSION}..."
-
-MAJOR_VERSION="$(echo ${VERSION} | cut -c 1-2)"
-apk add --no-cache \
- postgresql${MAJOR_VERSION}=${VERSION}
-
-bf-done
-
-
-#======================================================================================================================
-# Create PostgreSQL directories.
-#======================================================================================================================
-
-bf-echo "Creating PostgreSQL directories."
-
-mkdir /data
-mkdir /backup
-mkdir /run/postgresql
-
-
-#======================================================================================================================
-# Store default crontab as a template.
-#======================================================================================================================
-
-cp /etc/crontabs/root /etc/bf/templates/crontab.esh
+ # add bf-postgresql module to config
+ bf config use bf-postgresql
+}
diff --git a/overlay/usr/bin/bf/db-backup b/overlay/usr/bin/bf/db-backup
deleted file mode 100644
index 6d96302..0000000
--- a/overlay/usr/bin/bf/db-backup
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Run library backup executable.
-#======================================================================================================================
-
-s6-setuidgid postgres ${POSTGRESQL_LIB}/backup
diff --git a/overlay/usr/bin/bf/db-export b/overlay/usr/bin/bf/db-export
deleted file mode 100644
index 05c4b2c..0000000
--- a/overlay/usr/bin/bf/db-export
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Run library export executable with first argument.
-#======================================================================================================================
-
-s6-setuidgid postgres ${POSTGRESQL_LIB}/export "${1-}"
diff --git a/overlay/usr/bin/bf/db-generate-config b/overlay/usr/bin/bf/db-generate-config
deleted file mode 100644
index 98346cd..0000000
--- a/overlay/usr/bin/bf/db-generate-config
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-
-
-#======================================================================================================================
-# Run library config executable.
-#======================================================================================================================
-
-bf-debug "Generating configuration files." "db-generate-config"
-s6-setuidgid postgres ${POSTGRESQL_LIB}/generate-config
diff --git a/overlay/usr/bin/bf/db-import b/overlay/usr/bin/bf/db-import
deleted file mode 100644
index 1f09354..0000000
--- a/overlay/usr/bin/bf/db-import
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Run library import executable.
-#======================================================================================================================
-
-s6-setuidgid postgres ${POSTGRESQL_LIB}/import
diff --git a/overlay/usr/bin/bf/db-restore b/overlay/usr/bin/bf/db-restore
deleted file mode 100644
index efafd6d..0000000
--- a/overlay/usr/bin/bf/db-restore
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Check arguments.
-# 1 Backup date
-#======================================================================================================================
-
-[[ -z "${1-}" ]] && bf-error "You must provide the date/time of the backup to restore."
-DATE=${1}
-
-
-#======================================================================================================================
-# Look for compressed dump file.
-#======================================================================================================================
-
-BACKUP_PATH="${POSTGRESQL_BACKUP}/${DATE}"
-bf-echo "Looking for backup in ${BACKUP_PATH}..."
-
-COMPRESSED_DUMP_FILE="${BACKUP_PATH}/${POSTGRESQL_BACKUP_FILENAME}.gz"
-if [ -f "${COMPRESSED_DUMP_FILE}" ] ; then
- bf-debug " .. decompressing ${COMPRESSED_DUMP_FILE}"
- gzip -d "${COMPRESSED_DUMP_FILE}"
-fi
-
-DUMP_FILE="${BACKUP_PATH}/${POSTGRESQL_BACKUP_FILENAME}.sql"
-[[ ! -f "${DUMP_FILE}" ]] && bf-error " .. ${DUMP_FILE} does not exist."
-bf-ok " .. found ${DUMP_FILE}."
-
-
-#======================================================================================================================
-# Move dump file to restore location and restart.
-#======================================================================================================================
-
-mv ${DUMP_FILE} ${POSTGRESQL_RESTORE}
-bf-cont-terminate
diff --git a/overlay/usr/bin/bf/db-stop b/overlay/usr/bin/bf/db-stop
deleted file mode 100644
index cc359db..0000000
--- a/overlay/usr/bin/bf/db-stop
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/command/with-contenv sh
-
-set -euo pipefail
-export BF_E=`basename ${0}`
-
-
-#======================================================================================================================
-# Run library finish executable.
-#======================================================================================================================
-
-s6-setuidgid postgres ${POSTGRESQL_LIB}/finish
diff --git a/overlay/usr/bin/bf/healthcheck b/overlay/usr/bin/bf/healthcheck
index f677c5d..1545b9b 100644
--- a/overlay/usr/bin/bf/healthcheck
+++ b/overlay/usr/bin/bf/healthcheck
@@ -1,14 +1,10 @@
-#!/command/with-contenv sh
+#!/bin/withenv sh
set -euo pipefail
-export BF_E=`basename ${0}`
#======================================================================================================================
-# Perform a basic sql command to check the server is running.
+# Perform a basic sql command to check the server is running
#======================================================================================================================
-CHECK=$(psql -U postgres -c "SELECT 1;" 2> /dev/null | tail -n3 | head -n1 | xargs || echo "0")
-
-[[ "${CHECK}" == "1" ]] && exit 0
-exit 1
+exit $(psql -U ${BF_PG_USERNAME} -c "SELECT 0;" 2> /dev/null | tail -n3 | head -n1 | xargs || echo "1")
diff --git a/overlay/usr/lib/bf/postgresql/finish b/overlay/usr/bin/bf/pg
similarity index 77%
rename from overlay/usr/lib/bf/postgresql/finish
rename to overlay/usr/bin/bf/pg
index 7fd3c82..cf66a21 100644
--- a/overlay/usr/lib/bf/postgresql/finish
+++ b/overlay/usr/bin/bf/pg
@@ -1,10 +1,10 @@
-#!/bin/sh
+#!/bin/withenv sh
set -euo pipefail
#======================================================================================================================
-# Stop the server gracefully.
+# Run a command as postgres user
#======================================================================================================================
-pg_ctl stop -D ${POSTGRESQL_DATA}
+s6-setuidgid postgres "$@"
diff --git a/overlay/usr/bin/bf/pg-dump b/overlay/usr/bin/bf/pg-dump
new file mode 100644
index 0000000..c3c4936
--- /dev/null
+++ b/overlay/usr/bin/bf/pg-dump
@@ -0,0 +1,8 @@
+#!/usr/bin/nu
+
+use bf
+use bf-postgresql
+bf env load -x
+
+# Dump data cluster
+def main [] { bf-postgresql dump }
diff --git a/overlay/usr/bin/bf/pg-export b/overlay/usr/bin/bf/pg-export
new file mode 100644
index 0000000..f1f795d
--- /dev/null
+++ b/overlay/usr/bin/bf/pg-export
@@ -0,0 +1,12 @@
+#!/usr/bin/nu
+
+use bf
+use bf-postgresql
+bf env load -x
+
+# Export a database to a script file
+def main [
+ name: string # The name of the database to export
+] {
+ bf-postgresql export $name
+}
diff --git a/overlay/usr/bin/bf/pg-import b/overlay/usr/bin/bf/pg-import
new file mode 100644
index 0000000..97c9046
--- /dev/null
+++ b/overlay/usr/bin/bf/pg-import
@@ -0,0 +1,12 @@
+#!/usr/bin/nu
+
+use bf
+use bf-postgresql
+bf env load -x
+
+# Import a database from a script file
+def main [
+ name: string # The name of the database to import
+] {
+ bf-postgresql import $name
+}
diff --git a/overlay/usr/bin/bf/pg-restore b/overlay/usr/bin/bf/pg-restore
new file mode 100644
index 0000000..92b63c1
--- /dev/null
+++ b/overlay/usr/bin/bf/pg-restore
@@ -0,0 +1,12 @@
+#!/usr/bin/nu
+
+use bf
+use bf-postgresql
+bf env load -x
+
+# Restore the data from a dump file
+def main [
+ backup: string # Restore the dump file this backup directory
+] {
+ bf-postgresql restore from $backup
+}
diff --git a/overlay/usr/lib/bf/postgresql/backup b/overlay/usr/lib/bf/postgresql/backup
deleted file mode 100644
index 4a67620..0000000
--- a/overlay/usr/lib/bf/postgresql/backup
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-
-set -euo pipefail
-
-
-#======================================================================================================================
-# Set variables.
-#======================================================================================================================
-
-DATE=$(date '+%Y%m%d%H%M')
-bf-debug "Backup: ${DATE}."
-
-
-#======================================================================================================================
-# Create temporary directory for backups.
-#======================================================================================================================
-
-TEMP_BACKUP_PATH=$(mktemp -d -t backup.XXXXXX) || bf-error "Unable to make temporary backup directory."
-bf-echo "Backing up server to ${TEMP_BACKUP_PATH}..."
-
-
-#======================================================================================================================
-# Dump database cluster and compress.
-#======================================================================================================================
-
-# dump cluster
-DUMP_FILE="${TEMP_BACKUP_PATH}/${POSTGRESQL_BACKUP_FILENAME}.sql"
-bf-debug " .. dumping cluster"
-pg_dumpall > "${DUMP_FILE}"
-
-# compress file
-if [ "${POSTGRESQL_BACKUP_COMPRESS_FILES}" = "1" ] ; then
- bf-debug " .. compressing"
- gzip ${DUMP_FILE}
-fi
-
-
-#======================================================================================================================
-# Get list of individual databases, dump and compress.
-#======================================================================================================================
-
-# remove header / footer from output
-EXCLUDE="postgres|template0|template1"
-bf-debug " .. excluding ${EXCLUDE} from individual backups"
-DATABASES=$(psql -c "SELECT datname FROM pg_database;" | tail -n+3 | head -n-2 | grep -v -E "(${EXCLUDE})")
-
-# dump each database
-for DATABASE in ${DATABASES} ; do
-
- # path to this database dump
- DUMP_FILE="${TEMP_BACKUP_PATH}/${DATABASE}.sql"
-
- # dump database and continue on failure
- bf-debug " .. dumping database ${DATABASE}"
- pg_dump ${DATABASE} > ${DUMP_FILE}|| true
-
- # compress file
- if [ "${POSTGRESQL_BACKUP_COMPRESS_FILES}" = "1" ] ; then
- bf-debug " .. compressing"
- gzip ${DUMP_FILE}
- fi
-
-done
-
-bf-done
-
-
-#======================================================================================================================
-# Move backups to backup directory.
-#======================================================================================================================
-
-BACKUP_PATH=${POSTGRESQL_BACKUP}/${DATE}
-bf-echo "Moving backups to ${BACKUP_PATH}..."
-mv ${TEMP_BACKUP_PATH} ${BACKUP_PATH}
-bf-done
-
-
-#======================================================================================================================
-# Remove old backups.
-#======================================================================================================================
-
-if [ "${POSTGRESQL_BACKUP_KEEP_FOR_DAYS}" -gt 0 ] ; then
-
- bf-echo "Deleting backups older than ${POSTGRESQL_BACKUP_KEEP_FOR_DAYS} days..."
- MMIN=$((60*24*${POSTGRESQL_BACKUP_KEEP_FOR_DAYS}))
- find ${POSTGRESQL_BACKUP}/* -type d -mmin +${MMIN} | xargs rm -rf
- bf-done
-
-fi
diff --git a/overlay/usr/lib/bf/postgresql/export b/overlay/usr/lib/bf/postgresql/export
deleted file mode 100644
index 9402575..0000000
--- a/overlay/usr/lib/bf/postgresql/export
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-set -euo pipefail
-
-
-#======================================================================================================================
-# Check arguments.
-# 1 Database name
-#======================================================================================================================
-
-[[ -z "${1-}" ]] && bf-error "You must provide the name of the database to export."
-DATABASE=${1}
-
-
-#======================================================================================================================
-# Check database exists.
-#======================================================================================================================
-
-EXISTS=$(db-exists "${DATABASE}")
-[[ "${EXISTS}" = "0" ]] && bf-error "Database '${DATABASE}' does not exist."
-
-
-#======================================================================================================================
-# Dump database to file.
-#======================================================================================================================
-
-EXPORT_FILE="${POSTGRESQL_BACKUP}/${DATABASE}.sql"
-bf-echo "Exporting database '${DATABASE}' to ${EXPORT_FILE}..."
-pg_dump "${DATABASE}" > "${EXPORT_FILE}" \
- || bf-error " .. unable to export database '${DATABASE}'."
-bf-done
diff --git a/overlay/usr/lib/bf/postgresql/generate-config b/overlay/usr/lib/bf/postgresql/generate-config
deleted file mode 100644
index ef8a250..0000000
--- a/overlay/usr/lib/bf/postgresql/generate-config
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-set -euo pipefail
-
-
-#======================================================================================================================
-# Config is re-written every time in case environment variables have been changed.
-#======================================================================================================================
-
-bf-echo "Writing PostgreSQL config..."
-bf-esh ${BF_TEMPLATES}/pg_hba.conf.esh \
- ${POSTGRESQL_DATA}/pg_hba.conf
-bf-esh ${BF_TEMPLATES}/postgresql.conf.esh \
- ${POSTGRESQL_DATA}/postgresql.conf
-bf-done
diff --git a/overlay/usr/lib/bf/postgresql/import b/overlay/usr/lib/bf/postgresql/import
deleted file mode 100644
index 8d23f59..0000000
--- a/overlay/usr/lib/bf/postgresql/import
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-
-set -euo pipefail
-
-
-#======================================================================================================================
-# Get import files (from backup directory).
-#======================================================================================================================
-
-bf-echo "Importing SQL files from ${POSTGRESQL_BACKUP}..."
-for FILE in ${POSTGRESQL_BACKUP}/*.sql ; do
-
- # split out database name from file
- NAME=$(basename -- "${FILE}")
- DATABASE="${NAME%.*}"
-
- # create database if it does not exist
- EXISTS=$(db-exists "${DATABASE}")
- if [ "${EXISTS}" = "0" ] ; then
- bf-echo " .. creating '${DATABASE}'."
- createdb "${DATABASE}" --owner="${POSTGRESQL_USERNAME}"\
- || bf-notok " . something went wrong."
- fi
-
- # execute dump file using psql
- bf-echo " .. importing '${DATABASE}'."
- psql "${DATABASE}" < ${FILE} \
- || bf-notok " . something went wrong."
-
-done
-bf-done
diff --git a/overlay/usr/lib/bf/postgresql/init b/overlay/usr/lib/bf/postgresql/init
deleted file mode 100644
index 940da9d..0000000
--- a/overlay/usr/lib/bf/postgresql/init
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-
-set -euo pipefail
-
-
-#======================================================================================================================
-# Check for application user and password.
-#======================================================================================================================
-
-[[ -z "${POSTGRESQL_USERNAME-}" || -z "${POSTGRESQL_PASSWORD-}" ]] \
- && bf-error "POSTGRESQL_USERNAME and POSTGRESQL_PASSWORD must be set."
-
-
-#======================================================================================================================
-# Initialise server, create role and application database(s), enable remote connections.
-#======================================================================================================================
-
-# create specified role
-bf-debug "Creating role ${POSTGRESQL_USERNAME}..."
-echo -e "${POSTGRESQL_PASSWORD}\n${POSTGRESQL_PASSWORD}" | createuser --superuser --pwprompt ${POSTGRESQL_USERNAME}
-
-# create database(s)
-bf-debug "Creating..."
-if [ ! -z "${POSTGRESQL_DATABASE-}" ] ; then
-
- bf-debug " .. specified database(s):"
- DATABASES=$(echo ${POSTGRESQL_DATABASE} | tr "," "\n")
-
- for DATABASE in ${DATABASES} ; do
- bf-debug " .. ${DATABASE}."
- createdb "${DATABASE}" --owner="${POSTGRESQL_USERNAME}"
- done
-
-# no database specified so use username as database name
-else
-
- bf-debug " .. application database: ${POSTGRESQL_USERNAME}."
- createdb "${POSTGRESQL_USERNAME}" --owner="${POSTGRESQL_USERNAME}"
-
-fi
diff --git a/run.sh b/run.sh
index f41440f..634e57a 100644
--- a/run.sh
+++ b/run.sh
@@ -5,10 +5,17 @@ POSTGRESQL=${1:-15}
docker buildx build \
--load \
+ --progress plain \
--build-arg BF_IMAGE=postgresql \
--build-arg BF_VERSION=${IMAGE} \
-f ${POSTGRESQL}/Dockerfile \
-t postgresql${POSTGRESQL}-dev \
. \
&& \
- docker run -it -e POSTGRESQL_USERNAME=test -e POSTGRESQL_PASSWORD=test postgresql${POSTGRESQL}-dev sh
+ docker run -it \
+ -e BF_DEBUG=1 \
+ -e BF_PG_APPLICATION=test \
+ postgresql${POSTGRESQL}-dev \
+ sh
+
+ #-v /tmp/pg-data:/data \