问题
I am using the "plain" postgresql:alpine docker image, but have to schedule a database backup daily. I think this is a pretty common task.
I created a script backup
and stored in the container in /etc/periodic/15min
, and made it executable:
bash-4.4# ls -l /etc/periodic/15min/
total 4
-rwxr-xr-x 1 root root 95 Mar 2 15:44 backup
I tried executing it manually, that works fine.
My problem is getting crond
to run automatically.
If I exec docker exec my-postgresql-container crond
, the deamon is started and cron works, but I would like to embed this into my Dockerfile
FROM postgres:alpine
# my backup script, MUST NOT have .sh extension
COPY backup.sh /etc/periodic/15min/backup
RUN chmod a+x /etc/periodic/15min/backup
RUN crond # <- doesn't work
I have no idea how to rewrite or overwrite the commands in the official image. For update reasons I also would like to stay on these images, if possible.
回答1:
Note: This option if you would like to use the same container with multiple service
Install Supervisord which will makes you able to run crond
and postgresql
. The Dockerfile
will be as the following:
FROM postgres:alpine
RUN apk add --no-cache supervisor
RUN mkdir /etc/supervisor.d
COPY postgres_cron.ini /etc/supervisor.d/postgres_cron.ini
ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
And postgres_cron.ini
will be as the following:
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
loglevel=info ; (log level;default info; others: debug,warn,trace)
nodaemon=true ; (start in foreground if true;default false)
[program:postgres]
command=/usr/local/bin/docker-entrypoint.sh postgres
autostart=true
autorestart=true
[program:cron]
command =/usr/sbin/crond -f
autostart=true
autorestart=true
Then you can start the docker build process and run a container from your new image. Feel free to modify the Dockerfile
or postgres_cron.ini
as needed
回答2:
I had the exact same problem a few month ago. The key aspect is that a container can have only one main process defined by the ENTRYPOINT
and/or CMD
in your Dockerfile
.
You cannot just swap out postgres
with crond
otherwise your database isn't running. It is generally recommended to separate areas of concern by using one service per container.
With that in mind either use a separate container which runs nothing but crond
and thus Docker
can both track its lifecycle, and restart it when/if it fails, the machine restarts, etc.
Or run the jobs via cron
on your host using docker exec
.
The third and in my opinion best (but also advanced) solution is pg_cron. It is an postgres
extension and therefore runs the jobs in the same database container. Your challenge would be to adapt the configuration and installation of it.
The easy part should be the postgresql.conf:
# add to postgresql.conf:
shared_preload_libraries = 'pg_cron'
cron.database_name = 'postgres'
Next, you need to add the pg_cron
extension to your image by adjusting the Dockerfile
, which you can derive from the official alpine postgres
image. The installation of it is described here.
来源:https://stackoverflow.com/questions/49074458/cron-in-postgresqlalpine-docker-container