Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker multiple entrypoints

Tags:

docker

Say I have the following Dockerfile:

FROM ubuntu

RUN apt-get update
RUN apt-get install -y apache2
RUN apt-get install -y mongod #pretend this exists

EXPOSE 80

ENTRYPOINT ["/usr/sbin/apache2"]

The ENTRYPOINT command makes it so that apache2 starts when the container starts. I want to also be able to start mongod when the the container starts with the command service mongod start. According to the documentation however, there must be only one ENTRYPOINT in a Dockerfile. What would be the correct way to do this then?

like image 429
Snowman Avatar asked Sep 14 '13 18:09

Snowman


People also ask

Can a Dockerfile have multiple Entrypoints?

The ENTRYPOINT command makes it so that apache2 starts when the container starts. I want to also be able to start mongod when the the container starts with the command service mongod start . According to the documentation however, there must be only one ENTRYPOINT in a Dockerfile.

Can you have 2 Dockerfiles?

As Kingsley Uchnor said, you can have multiple Dockerfile , one per directory, which represent something you want to build.

Can we have multiple CMD in Dockerfile?

There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect. If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.


3 Answers

As Jared Markell said, if you wan to launch several processes in a docker container, you have to use supervisor. You will have to configure supervisor to tell him to launch your different processes.

I wrote about this in this blog post, but you have a really nice article here detailing how and why using supervisor in Docker.

Basically, you will want to do something like:

FROM ubuntu

RUN apt-get update
RUN apt-get install -y apache2
RUN apt-get install -y mongod #pretend this exists
RUN apt-get install -y supervisor # Installing supervisord

ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf 

EXPOSE 80

ENTRYPOINT ["/usr/bin/supervisord"]

And add a configuration a file supervisord.conf

[supervisord]
nodaemon=true

[program:mongodb]
command=/etc/mongod/mongo #To adapt, I don't know how to launch your mongodb process

[program:apache2]
command=/usr/sbin/apache2 -DFOREGROUND

EDIT: As this answer has received quite lot of upvotes, I want to precise as a warning that using Supervisor is not considered as a best practice to run several jobs. Instead, you may be interested in creating several containers for your different processes and managing them through docker compose. In a nutshell, Docker Compose allows you to define in one file all the containers needed for your app and launch them in one single command.

like image 161
Pierre-Jean Avatar answered Oct 08 '22 02:10

Pierre-Jean


My solution is to throw individual scripts into /opt/run/ and execute them with:

#!/bin/bash

LOG=/var/log/all

touch $LOG

for a in /opt/run/*
do
    $a >> $LOG &
done

tail -f $LOG

And my entry point is just the location of this script, say it's called /opt/bin/run_all:

ADD 00_sshd /opt/run/
ADD 01_nginx /opt/run/

ADD run_all /opt/bin/
ENTRYPOINT ["/opt/bin/run_all"]
like image 26
gak Avatar answered Oct 08 '22 00:10

gak


The simple answer is that you should not because it breaks the single responsibility principle: one container, one service. Imagine that you want to spawn additional cloud images of MongoDB because of a sudden workload - why increasing Apache2 instances as well and at a 1:1 ratio? Instead, you should link the boxes and make them speak through TCP. See https://docs.docker.com/userguide/dockerlinks/ for more info.

like image 11
Alessandro Santini Avatar answered Oct 08 '22 02:10

Alessandro Santini