Run Laravel schedule in docker image using supervisord (#6606)

* docker: Rename /entrypoint.sh to /startup.sh

This script is not configured as the docker image ENTRYPOINT, thus it is
misleading to name it so.

* docker: Terminate supervisord if a process enters the FATAL state

By terminating PID 1, this will also terminate the Docker container.

* docker: Use supervisord to start up apache and cron

Note that this uses `apache2ctl -DFOREGROUND` rather than manually
sourcing /etc/apache2/envvars and running apache2, as recommended at
https://advancedweb.hu/2018/07/03/supervisor_docker/.

* docker: Add artisan schedule:run to crontab

This also switches to executing /var/www/html/artisan directly.

* docker: Run artisan schedule:run directly from supervisor

This has the following benefits over using cron:
- Cron doesn't need to be installed
- Docker-provided environment variables are preserved
- It's easy and explicit to run as the docker user
This commit is contained in:
Jonathon Reinhart 2019-03-07 15:42:00 -05:00 committed by snipe
parent 6d98bd6846
commit e59ec8b27f
4 changed files with 56 additions and 15 deletions

View file

@ -18,9 +18,8 @@ patch \
curl \
vim \
git \
cron \
mysql-client \
cron \
supervisor \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@ -69,7 +68,9 @@ RUN \
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
&& mkdir "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
&& chown docker "/var/lib/snipeit/keys/"
&& chown docker "/var/lib/snipeit/keys/" \
&& chmod +x /var/www/html/artisan \
&& echo "Finished setting up application in /var/www/html"
############## DEPENDENCIES via COMPOSER ###################
@ -96,16 +97,11 @@ VOLUME ["/var/lib/snipeit"]
##### START SERVER
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
COPY docker/startup.sh docker/supervisord.conf /
COPY docker/supervisor-exit-event-listener /usr/bin/supervisor-exit-event-listener
RUN chmod +x /startup.sh /usr/bin/supervisor-exit-event-listener
# Add Tini
ENV TINI_VERSION v0.14.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
CMD ["/entrypoint.sh"]
CMD ["/startup.sh"]
EXPOSE 80
EXPOSE 443

View file

@ -5,7 +5,7 @@ if [ -z "$APP_KEY" ]
then
echo "Please re-run this container with an environment variable \$APP_KEY"
echo "An example APP_KEY you could use is: "
php artisan key:generate --show
/var/www/html/artisan key:generate --show
exit
fi
@ -47,5 +47,4 @@ then
cp -ax /var/www/html/vendor/laravel/passport/database/migrations/* /var/www/html/database/migrations/
fi
. /etc/apache2/envvars
exec apache2 -DNO_DETACH < /dev/null
exec supervisord -c /supervisord.conf

View file

@ -0,0 +1,19 @@
#!/usr/bin/env python
# A supervisor event listener which terminates supervisord if any of its child
# processes enter the FATAL state.
# https://stackoverflow.com/a/37527488/119527
import os
import signal
from supervisor import childutils
def main():
while True:
headers, payload = childutils.listener.wait()
childutils.listener.ok()
if headers['eventname'] != 'PROCESS_STATE_FATAL':
continue
os.kill(os.getppid(), signal.SIGTERM)
if __name__ == "__main__":
main()

27
docker/supervisord.conf Normal file
View file

@ -0,0 +1,27 @@
[supervisord]
nodaemon=true
[program:apache]
; https://advancedweb.hu/2018/07/03/supervisor_docker/
command=apache2ctl -DFOREGROUND
killasgroup=true
stopasgroup=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:run_schedule]
; Simply run the Laravel command scheduler every minute
command=/bin/bash -c "while true; do /var/www/html/artisan schedule:run; sleep 1m; done"
user=docker
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
; https://stackoverflow.com/a/37527488/119527
[eventlistener:exit_on_any_fatal]
command=supervisor-exit-event-listener
events=PROCESS_STATE_FATAL