-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathDockerfile
More file actions
157 lines (132 loc) · 6.52 KB
/
Dockerfile
File metadata and controls
157 lines (132 loc) · 6.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
FROM python:3.14.1-slim AS builder
WORKDIR /app
ADD pyproject.toml poetry.lock ./
RUN pip install --no-cache-dir poetry==2.1.1
RUN poetry self add "poetry-plugin-export==1.10.0"
# Build a requirements.txt file matching poetry.lock, that pip understands
# Test comment
RUN poetry export --extras duplicity --output /app/requirements.txt
FROM python:3.14.1-alpine AS base
ENV CRONTAB_15MIN='*/15 * * * *' \
CRONTAB_HOURLY='0 * * * *' \
CRONTAB_DAILY='0 2 * * MON-SAT' \
CRONTAB_WEEKLY='0 1 * * SUN' \
CRONTAB_MONTHLY='0 5 1 * *' \
DST='' \
EMAIL_FROM='' \
EMAIL_SUBJECT='Backup report: {hostname} - {periodicity} - {result}' \
EMAIL_TO='' \
JOB_300_WHAT='backup' \
JOB_300_WHEN='daily' \
OPTIONS='' \
OPTIONS_EXTRA='--metadata-sync-mode partial' \
SMTP_HOST='smtp' \
SMTP_PORT='25' \
SMTP_USER='' \
SMTP_PASS='' \
SMTP_TLS='' \
SMTP_REPORT_SUCCESS='1' \
SRC='/mnt/backup/src'
ENTRYPOINT [ "/usr/local/bin/entrypoint" ]
CMD ["/usr/sbin/crond", "-fd8"]
# Runtime dependencies and database clients
RUN apk add --no-cache \
ca-certificates \
dbus \
gettext \
gnupg \
krb5-libs \
lftp \
libffi \
librsync \
ncftp \
openssh \
openssl \
rsync \
tzdata \
&& sync
# Default backup source directory
RUN mkdir -p "$SRC"
# Preserve cache among containers
VOLUME [ "/root" ]
# Build dependencies
COPY --from=builder /app/requirements.txt requirements.txt
RUN apk add --no-cache --virtual .build \
build-base \
python3-dev \
krb5-dev \
libffi-dev \
librsync-dev \
libxml2-dev \
libxslt-dev \
openssl-dev \
cargo
# Trick for passing as a warning this build message and gets netifaces installed:
# initialization of 'int' from 'void *' makes integer from pointer without a cast [-Wint-conversion]
RUN CFLAGS="-Wno-int-conversion" pip install netifaces
# Runtime dependencies, based on https://gitlab.com/duplicity/duplicity/-/blob/master/requirements.txt
RUN pip install --no-cache-dir -r requirements.txt \
&& apk del .build \
&& rm -rf /root/.cargo
COPY bin/* /usr/local/bin/
RUN chmod a+rx /usr/local/bin/* && sync
FROM base AS s3
ENV JOB_500_WHAT='dup full $SRC $DST' \
JOB_500_WHEN='weekly' \
OPTIONS_EXTRA='--metadata-sync-mode partial --full-if-older-than 1W --file-prefix-archive archive-$(hostname -f)- --file-prefix-manifest manifest-$(hostname -f)- --file-prefix-signature signature-$(hostname -f)- --s3-european-buckets --s3-multipart-chunk-size 10 --s3-use-new-style'
FROM base AS docker
RUN apk add --no-cache docker-cli
FROM docker AS docker-s3
ENV JOB_500_WHAT='dup full $SRC $DST' \
JOB_500_WHEN='weekly' \
OPTIONS_EXTRA='--metadata-sync-mode partial --full-if-older-than 1W --file-prefix-archive archive-$(hostname -f)- --file-prefix-manifest manifest-$(hostname -f)- --file-prefix-signature signature-$(hostname -f)- --s3-european-buckets --s3-multipart-chunk-size 10 --s3-use-new-style'
FROM base AS postgres
ENV DB_VERSION="18" \
APK_POSTGRES_DIR="/opt/postgresql-client-collection"
RUN apk add --no-cache grep libpq postgresql-common
# To get support for psql 9.6 need create the folder for 9.6, use alpine 3.6 and use these lines:
# echo "http://dl-cdn.alpinelinux.org/alpine/v3.6/main" > psql_repos
# apk fetch --no-cache --repositories-file psql_repos postgresql-client postgresql-dev -o "$APK_POSTGRES_DIR/9.6"
RUN set -eux; \
mkdir -p \
"$APK_POSTGRES_DIR/10" \
"$APK_POSTGRES_DIR/11" \
"$APK_POSTGRES_DIR/12" \
"$APK_POSTGRES_DIR/13" \
"$APK_POSTGRES_DIR/14" \
"$APK_POSTGRES_DIR/15" \
"$APK_POSTGRES_DIR/16" \
"$APK_POSTGRES_DIR/17" \
"$APK_POSTGRES_DIR/18"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.8/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql-client -o "$APK_POSTGRES_DIR/10"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.10/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql-client -o "$APK_POSTGRES_DIR/11"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.12/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql-client -o "$APK_POSTGRES_DIR/12"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.14/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql-client -o "$APK_POSTGRES_DIR/13"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.17/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql14-client -o "$APK_POSTGRES_DIR/14"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.20/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql15-client -o "$APK_POSTGRES_DIR/15"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.21/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql16-client -o "$APK_POSTGRES_DIR/16"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.22/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql17-client -o "$APK_POSTGRES_DIR/17"; \
echo "http://dl-cdn.alpinelinux.org/alpine/v3.23/main" > psql_repos; \
apk fetch --no-cache --repositories-file psql_repos postgresql18-client -o "$APK_POSTGRES_DIR/18"; \
rm psql_repos;
ENV JOB_200_WHAT set -euo pipefail; psql -0Atd postgres -c \"SELECT datname FROM pg_database WHERE NOT datistemplate AND datname != \'postgres\'\" | grep --null-data -E \"\$DBS_TO_INCLUDE\" | grep --null-data --invert-match -E \"\$DBS_TO_EXCLUDE\" | xargs -0tI DB pg_dump --dbname DB --no-owner --no-privileges --file \"\$SRC/DB.sql\"
ENV JOB_200_WHEN='daily weekly' \
DBS_TO_INCLUDE='.*' \
DBS_TO_EXCLUDE='$^' \
PGHOST=db
FROM postgres AS postgres-s3
ENV JOB_500_WHAT='dup full $SRC $DST' \
JOB_500_WHEN='weekly' \
OPTIONS_EXTRA='--metadata-sync-mode partial --full-if-older-than 1W --file-prefix-archive archive-$(hostname -f)- --file-prefix-manifest manifest-$(hostname -f)- --file-prefix-signature signature-$(hostname -f)- --s3-european-buckets --s3-multipart-chunk-size 10 --s3-use-new-style'
FROM postgres-s3 AS postgres-multi
ENV DST='multi' \
OPTIONS_EXTRA='--metadata-sync-mode partial --full-if-older-than 1W --file-prefix-archive archive-$(hostname -f)- --file-prefix-manifest manifest-$(hostname -f)- --file-prefix-signature signature-$(hostname -f)-' \
OPTIONS_EXTRA_S3='--s3-european-buckets --s3-multipart-chunk-size 10 --s3-use-new-style'