Skip to content

Commit 23f24ca

Browse files
authoredSep 4, 2024
Merge pull request #158 from prodrigestivill/initial-backup
Add support to perform an initial backup on startup
2 parents 2cbc34e + 8aa2ae7 commit 23f24ca

8 files changed

+95
-69
lines changed
 

‎README.md

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ services:
5151
# - POSTGRES_PASSWORD_FILE=/run/secrets/db_password <-- alternative for POSTGRES_PASSWORD (to use with docker secrets)
5252
- POSTGRES_EXTRA_OPTS=-Z1 --schema=public --blobs
5353
- SCHEDULE=@daily
54+
- BACKUP_ON_START=TRUE
5455
- BACKUP_KEEP_DAYS=7
5556
- BACKUP_KEEP_WEEKS=4
5657
- BACKUP_KEEP_MONTHS=6
@@ -75,6 +76,7 @@ Most variables are the same as in the [official postgres image](https://hub.dock
7576
|--|--|
7677
| BACKUP_DIR | Directory to save the backup at. Defaults to `/backups`. |
7778
| BACKUP_SUFFIX | Filename suffix to save the backup. Defaults to `.sql.gz`. |
79+
| BACKUP_ON_START | If set to `TRUE` performs an backup on each container start or restart. Defaults to `FALSE`. |
7880
| BACKUP_KEEP_DAYS | Number of daily backups to keep before removal. Defaults to `7`. |
7981
| BACKUP_KEEP_WEEKS | Number of weekly backups to keep before removal. Defaults to `4`. |
8082
| BACKUP_KEEP_MONTHS | Number of monthly backups to keep before removal. Defaults to `6`. |

‎alpine.Dockerfile

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
ARG BASETAG=alpine
22
FROM postgres:$BASETAG
33

4-
ARG GOCRONVER=v0.0.10
4+
ARG GOCRONVER=v0.0.11
55
ARG TARGETOS
66
ARG TARGETARCH
77
RUN set -x \
@@ -21,6 +21,7 @@ ENV POSTGRES_DB="**None**" \
2121
POSTGRES_EXTRA_OPTS="-Z1" \
2222
POSTGRES_CLUSTER="FALSE" \
2323
SCHEDULE="@daily" \
24+
BACKUP_ON_START="FALSE" \
2425
BACKUP_DIR="/backups" \
2526
BACKUP_SUFFIX=".sql.gz" \
2627
BACKUP_LATEST_TYPE="symlink" \
@@ -36,12 +37,12 @@ ENV POSTGRES_DB="**None**" \
3637
WEBHOOK_EXTRA_ARGS=""
3738

3839
COPY hooks /hooks
39-
COPY backup.sh /backup.sh
40+
COPY backup.sh env.sh init.sh /
4041

4142
VOLUME /backups
4243

43-
ENTRYPOINT ["/bin/sh", "-c"]
44-
CMD ["exec /usr/local/bin/go-cron -s \"$SCHEDULE\" -p \"$HEALTHCHECK_PORT\" -- /backup.sh"]
44+
ENTRYPOINT []
45+
CMD ["/init.sh"]
4546

4647
HEALTHCHECK --interval=5m --timeout=3s \
4748
CMD curl -f "http://localhost:$HEALTHCHECK_PORT/" || exit 1

‎backup.sh

+1-58
Original file line numberDiff line numberDiff line change
@@ -9,64 +9,7 @@ if [ -d "${HOOKS_DIR}" ]; then
99
trap 'on_error' ERR
1010
fi
1111

12-
if [ "${POSTGRES_DB}" = "**None**" -a "${POSTGRES_DB_FILE}" = "**None**" ]; then
13-
echo "You need to set the POSTGRES_DB or POSTGRES_DB_FILE environment variable."
14-
exit 1
15-
fi
16-
17-
if [ "${POSTGRES_HOST}" = "**None**" ]; then
18-
if [ -n "${POSTGRES_PORT_5432_TCP_ADDR}" ]; then
19-
POSTGRES_HOST=${POSTGRES_PORT_5432_TCP_ADDR}
20-
POSTGRES_PORT=${POSTGRES_PORT_5432_TCP_PORT}
21-
else
22-
echo "You need to set the POSTGRES_HOST environment variable."
23-
exit 1
24-
fi
25-
fi
26-
27-
if [ "${POSTGRES_USER}" = "**None**" -a "${POSTGRES_USER_FILE}" = "**None**" ]; then
28-
echo "You need to set the POSTGRES_USER or POSTGRES_USER_FILE environment variable."
29-
exit 1
30-
fi
31-
32-
if [ "${POSTGRES_PASSWORD}" = "**None**" -a "${POSTGRES_PASSWORD_FILE}" = "**None**" -a "${POSTGRES_PASSFILE_STORE}" = "**None**" ]; then
33-
echo "You need to set the POSTGRES_PASSWORD or POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE environment variable or link to a container named POSTGRES."
34-
exit 1
35-
fi
36-
37-
#Process vars
38-
if [ "${POSTGRES_DB_FILE}" = "**None**" ]; then
39-
POSTGRES_DBS=$(echo "${POSTGRES_DB}" | tr , " ")
40-
elif [ -r "${POSTGRES_DB_FILE}" ]; then
41-
POSTGRES_DBS=$(cat "${POSTGRES_DB_FILE}")
42-
else
43-
echo "Missing POSTGRES_DB_FILE file."
44-
exit 1
45-
fi
46-
if [ "${POSTGRES_USER_FILE}" = "**None**" ]; then
47-
export PGUSER="${POSTGRES_USER}"
48-
elif [ -r "${POSTGRES_USER_FILE}" ]; then
49-
export PGUSER=$(cat "${POSTGRES_USER_FILE}")
50-
else
51-
echo "Missing POSTGRES_USER_FILE file."
52-
exit 1
53-
fi
54-
if [ "${POSTGRES_PASSWORD_FILE}" = "**None**" -a "${POSTGRES_PASSFILE_STORE}" = "**None**" ]; then
55-
export PGPASSWORD="${POSTGRES_PASSWORD}"
56-
elif [ -r "${POSTGRES_PASSWORD_FILE}" ]; then
57-
export PGPASSWORD=$(cat "${POSTGRES_PASSWORD_FILE}")
58-
elif [ -r "${POSTGRES_PASSFILE_STORE}" ]; then
59-
export PGPASSFILE="${POSTGRES_PASSFILE_STORE}"
60-
else
61-
echo "Missing POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE file."
62-
exit 1
63-
fi
64-
export PGHOST="${POSTGRES_HOST}"
65-
export PGPORT="${POSTGRES_PORT}"
66-
KEEP_MINS=${BACKUP_KEEP_MINS}
67-
KEEP_DAYS=${BACKUP_KEEP_DAYS}
68-
KEEP_WEEKS=`expr $(((${BACKUP_KEEP_WEEKS} * 7) + 1))`
69-
KEEP_MONTHS=`expr $(((${BACKUP_KEEP_MONTHS} * 31) + 1))`
12+
source "$(dirname "$0")/env.sh"
7013

7114
# Pre-backup hook
7215
if [ -d "${HOOKS_DIR}" ]; then

‎debian.Dockerfile

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
ARG BASETAG=latest
22
FROM postgres:$BASETAG
33

4-
ARG GOCRONVER=v0.0.10
4+
ARG GOCRONVER=v0.0.11
55
ARG TARGETOS
66
ARG TARGETARCH
77

@@ -35,6 +35,7 @@ ENV POSTGRES_DB="**None**" \
3535
POSTGRES_EXTRA_OPTS="-Z1" \
3636
POSTGRES_CLUSTER="FALSE" \
3737
SCHEDULE="@daily" \
38+
BACKUP_ON_START="FALSE" \
3839
BACKUP_DIR="/backups" \
3940
BACKUP_SUFFIX=".sql.gz" \
4041
BACKUP_LATEST_TYPE="symlink" \
@@ -50,12 +51,12 @@ ENV POSTGRES_DB="**None**" \
5051
WEBHOOK_EXTRA_ARGS=""
5152

5253
COPY hooks /hooks
53-
COPY backup.sh /backup.sh
54+
COPY backup.sh env.sh init.sh /
5455

5556
VOLUME /backups
5657

57-
ENTRYPOINT ["/bin/sh", "-c"]
58-
CMD ["exec /usr/local/bin/go-cron -s \"$SCHEDULE\" -p \"$HEALTHCHECK_PORT\" -- /backup.sh"]
58+
ENTRYPOINT []
59+
CMD ["/init.sh"]
5960

6061
HEALTHCHECK --interval=5m --timeout=3s \
6162
CMD curl -f "http://localhost:$HEALTHCHECK_PORT/" || exit 1

‎docker-bake.hcl

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ variable "BUILD_REVISION" {
1515
}
1616

1717
target "debian" {
18-
args = {"GOCRONVER" = "v0.0.10"}
18+
args = {"GOCRONVER" = "v0.0.11"}
1919
dockerfile = "debian.Dockerfile"
2020
}
2121

2222
target "alpine" {
23-
args = {"GOCRONVER" = "v0.0.10"}
23+
args = {"GOCRONVER" = "v0.0.11"}
2424
dockerfile = "alpine.Dockerfile"
2525
}
2626

‎env.sh

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env bash
2+
# Pre-validate the environment
3+
if [ "${POSTGRES_DB}" = "**None**" -a "${POSTGRES_DB_FILE}" = "**None**" ]; then
4+
echo "You need to set the POSTGRES_DB or POSTGRES_DB_FILE environment variable."
5+
exit 1
6+
fi
7+
8+
if [ "${POSTGRES_HOST}" = "**None**" ]; then
9+
if [ -n "${POSTGRES_PORT_5432_TCP_ADDR}" ]; then
10+
POSTGRES_HOST=${POSTGRES_PORT_5432_TCP_ADDR}
11+
POSTGRES_PORT=${POSTGRES_PORT_5432_TCP_PORT}
12+
else
13+
echo "You need to set the POSTGRES_HOST environment variable."
14+
exit 1
15+
fi
16+
fi
17+
18+
if [ "${POSTGRES_USER}" = "**None**" -a "${POSTGRES_USER_FILE}" = "**None**" ]; then
19+
echo "You need to set the POSTGRES_USER or POSTGRES_USER_FILE environment variable."
20+
exit 1
21+
fi
22+
23+
if [ "${POSTGRES_PASSWORD}" = "**None**" -a "${POSTGRES_PASSWORD_FILE}" = "**None**" -a "${POSTGRES_PASSFILE_STORE}" = "**None**" ]; then
24+
echo "You need to set the POSTGRES_PASSWORD or POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE environment variable or link to a container named POSTGRES."
25+
exit 1
26+
fi
27+
28+
#Process vars
29+
if [ "${POSTGRES_DB_FILE}" = "**None**" ]; then
30+
POSTGRES_DBS=$(echo "${POSTGRES_DB}" | tr , " ")
31+
elif [ -r "${POSTGRES_DB_FILE}" ]; then
32+
POSTGRES_DBS=$(cat "${POSTGRES_DB_FILE}")
33+
else
34+
echo "Missing POSTGRES_DB_FILE file."
35+
exit 1
36+
fi
37+
if [ "${POSTGRES_USER_FILE}" = "**None**" ]; then
38+
export PGUSER="${POSTGRES_USER}"
39+
elif [ -r "${POSTGRES_USER_FILE}" ]; then
40+
export PGUSER=$(cat "${POSTGRES_USER_FILE}")
41+
else
42+
echo "Missing POSTGRES_USER_FILE file."
43+
exit 1
44+
fi
45+
if [ "${POSTGRES_PASSWORD_FILE}" = "**None**" -a "${POSTGRES_PASSFILE_STORE}" = "**None**" ]; then
46+
export PGPASSWORD="${POSTGRES_PASSWORD}"
47+
elif [ -r "${POSTGRES_PASSWORD_FILE}" ]; then
48+
export PGPASSWORD=$(cat "${POSTGRES_PASSWORD_FILE}")
49+
elif [ -r "${POSTGRES_PASSFILE_STORE}" ]; then
50+
export PGPASSFILE="${POSTGRES_PASSFILE_STORE}"
51+
else
52+
echo "Missing POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE file."
53+
exit 1
54+
fi
55+
export PGHOST="${POSTGRES_HOST}"
56+
export PGPORT="${POSTGRES_PORT}"
57+
KEEP_MINS=${BACKUP_KEEP_MINS}
58+
KEEP_DAYS=${BACKUP_KEEP_DAYS}
59+
KEEP_WEEKS=`expr $(((${BACKUP_KEEP_WEEKS} * 7) + 1))`
60+
KEEP_MONTHS=`expr $(((${BACKUP_KEEP_MONTHS} * 31) + 1))`
61+
62+
# Validate backup dir
63+
if [ '!' -d "${BACKUP_DIR}" -o '!' -w "${BACKUP_DIR}" -o '!' -x "${BACKUP_DIR}" ]; then
64+
echo "BACKUP_DIR points to a file or folder with insufficient permissions."
65+
exit 1
66+
fi

‎generate-docker-bake.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -e
44

5-
GOCRONVER="v0.0.10"
5+
GOCRONVER="v0.0.11"
66
MAIN_TAG="16"
77
TAGS_EXTRA="15 14 13 12"
88
PLATFORMS="linux/amd64 linux/arm64 linux/arm/v7 linux/s390x linux/ppc64le"

‎init.sh

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
set -Eeo pipefail
3+
4+
# Prevalidate configuration (don't source)
5+
/env.sh
6+
7+
EXTRA_ARGS=""
8+
# Initial background backup
9+
if [ "${BACKUP_ON_START}" = "TRUE" ]; then
10+
EXTRA_ARGS="-i"
11+
fi
12+
13+
exec /usr/local/bin/go-cron -s "$SCHEDULE" -p "$HEALTHCHECK_PORT" $EXTRA_ARGS -- /backup.sh

0 commit comments

Comments
 (0)