Answer a question

I want to be able to run a simple bash script within a container service on the hour using cron. I'm using Alpine Linux via docker-compose with a custom Dockerfile to produce a php-fpm based image, on which I hope to get crond running as well - except I can't.

Executing ps aux | grep cron on the container once built, returns nothing.

From what I understand, the usual Linux startup processes don't exist in Docker containers - fine - so how do I auto-start crond? Its dirs under /etc/periodic/ are created automatically, so I don't understand why the applicable process that consumes those dirs, isn't also running.

I tried creating a dedicated service definition within docker-compose.yml, which actually worked but the shell script to be run hourly needs access to a php binary which is running in a different container, so this isn't a viable solution.

If I shell into the container and run rc-service crond start I get this - but it never "finishes":

/var/www/html # rc-service crond start
 * WARNING: crond is already starting
#> docker --version
Docker version 19.03.8, build afacb8b7f0
#> docker-compose --version
docker-compose version 1.23.2, build 1110ad01

I need a solution that I can place into my Dockerfile or docker-compose.yml files.

Dockerd is running on Ubuntu Xenial FWIW.

Answers

to run a cronjob container (Alpine), you need to make sure sure that the command of your docker container is

exec crond -f

if you want to add this to a docker file

CMD ["exec", "crond", "-f"]

you also may need to update the corn files before running the above command

Update based on the docker file and compose

To be able to solve your issues you need to update your docker-compose to have two containers one for cron and one for web

 service_php_cron:
    build:
      context: .
      dockerfile: .docker/services/php/Dockerfile.dev
    container_name: base_service_php
    command: 'cron_jobs'
    volumes:
      - ./app:/var/www/html/public
    env_file:
      - ./.env
    # Low level container logging
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
        max-file: "5"

  service_php:
    build:
      context: .
      dockerfile: .docker/services/php/Dockerfile.dev
    ports:
      - "9000:9000"
    command: 'web_server'
    container_name: base_service_php
    volumes:
      - ./app:/var/www/html/public
    env_file:
      - ./.env
    # Low level container logging
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
        max-file: "5"

you also need to update your docker file to be able to handle multiple commands using docker entry points

Add the below line to your docker file + remove the CMD one

COPY ./docker-entrypoint.sh /
RUN chmod a+x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]

and finally, create the entry point (make sure it hash execute permissions)

#!/bin/sh -e

case $1 in

  web_server)
    YOUR WEB SERVER COMMAND 
  ;;

  cron_jobs)
     exec crond -f
  ;;

  *)
    exec "$@"
  ;;

esac

exit 0

you can check this link for more info about entrypoints

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐