skip to Main Content

I understood there should be only one process running on foreground in a docker container. Is there any chance of running both apache and cron together in foreground? A quick search says there is something called supervisord to achieve this. But is there any other method using Entrypoint script or CMD?

Here is my Dockerfile

FROM alpine:edge
RUN  apk update && apk upgrade
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk   /repositories
RUN  apk add 
     bash  
     apache2 
     php7-apache2 
     php7 
     curl 
     php7-mysqli 
     php7-pdo 
     php7-pdo_mysql

 RUN cp /usr/bin/php7 /usr/bin/php
 RUN mkdir /startup
 COPY script.sh /startup
 RUN chmod 755 /startup/script.sh
 ENTRYPOINT ["/startup/script.sh"]

The content of script.sh is pasted below

#!/bin/bash
# start cron
/usr/sbin/crond -f -l 8
# start apache
httpd -D FOREGROUND

When the docker is run with this image only crond is running and most interestingly when I kill the cron then apache starts and running in the foreground.

I am using aws ecs ec2 to run the docker container using task definition and a service.

2

Answers


  1. The problem is that you’re running crond -f, without telling bash to run it in the background, basically keeping bash waiting for crond to exit to continue running the script. There’s two solutions for this:

    1. Remove the -f flag (that flag causes crond to run in the foreground).
    2. Add & at the end of the crond line, after -l 8 (I wouldn’t recommend this).

    Also, I’d start apache with exec:

    exec httpd -D FOREGROUND
    

    Otherwise /startup/script.sh will remain running, while it’s not doing anything useful anymore anyway. exec tells bash to replace the current process with the command to execute.

    Login or Signup to reply.
  2. Docker container is running while main process inside it is running. So if you want to run two services inside docker container, one of them has to be run in a background mode.

    I suggest to get rid of scrip.sh at all and replace it just with one CMD layer:

    CMD ( crond -f -l 8 & ) && httpd -D FOREGROUND
    

    The final Dockerfile is:

    FROM alpine:edge
    RUN  apk update && apk upgrade
    RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
    RUN  apk add 
         bash  
         apache2 
         php7-apache2 
         php7 
         curl 
         php7-mysqli 
         php7-pdo 
         php7-pdo_mysql
    
    RUN cp /usr/bin/php7 /usr/bin/php
    CMD ( crond -f -l 8 & ) && httpd -D FOREGROUND
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search