Dockerized nginx is not starting

2020-02-08 03:06发布

I have tried following some tutorials and documentation on dockerizing my web server, but I am having trouble getting the service to run via the docker run command.

This is my Dockerfile:

FROM ubuntu:trusty

#Update and install stuff
RUN apt-get update
RUN apt-get install -y python-software-properties aptitude screen htop nano nmap nginx

#Add files
ADD src/main/resources/ /usr/share/nginx/html

EXPOSE 80
CMD service nginx start

I create my image:

docker build -t myImage .

And when I run it:

docker run -p 81:80 myImage

it seems to just stop:

docker ps -a

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
90e54a254efa        pms-gui:latest      /bin/sh -c service n   3 seconds ago       Exit 0                                  prickly_bohr

I would expect this to be running with port 81->80 but it is not. Running

docker start 90e

does not seem to do anything.

I also tried entering it directly

docker run -t -i -p 81:80 myImage /bin/bash

and from here I can start the service

service nginx start

and from another tab I can see it is working as intended (also in my browser):

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
408237a5e10b        myImage:latest      /bin/bash           12 seconds ago      Up 11 seconds       0.0.0.0:81->80/tcp   mad_turing 

So I assume it is something I am doing wrong with my Dockerfile? Could anyone help me out with this, I am quite new to Docker. Thank you!

SOLUTION: Based on the answer from Ivant I found another way to start nginx in the foreground. My Dockerfile CMD now looks like:

CMD /usr/sbin/nginx -g "daemon off;"

标签: nginx docker
5条回答
Rolldiameter
2楼-- · 2020-02-08 03:46

If you run "service nginx start", it is a parent process which will start a child process of nginx. If you run "service nginx start" as CMD in a container, the Process ID 1 for the container will be "service nginx start" or ServiceManager (SystemD), while actual nginx would be running as a child process.

If you run "service nginx start", and then "ps -ef", you will get output as below. I have run it my host OS.

root@ip-172-31-85-74:/home/ubuntu# service nginx start
root@ip-172-31-85-74:/home/ubuntu# 

root@ip-172-31-85-74:/home/ubuntu# ps -ef | grep nginx
root     18593     1  0 12:27 ?        00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 18595 18593  0 12:27 ?        00:00:00 nginx: worker process
root     18599 17918  0 12:27 pts/0    00:00:00 grep --color=auto nginx

So, here the process ID 18593 is the child process which has parent process 1.

Container exits when their Process ID 1 exits. And in case of CMD "service nginx start", the PID 1 is the process manager, may be SystemD. It starts nginx as a child process, and exits itself, hence the container exits.

Similarly, if you run a shell script (for eg : start.sh) in CMD, as soon as the script ends, the container will exit. Even though the script starts some services (eg - nginx) in its execution, as soon as the script ends, the container will exit, because the PID 1 will be of the shell script. The parent process will be "./start.sh", and the services started by script will be child processes. In case you want to use a shell script in CMD, and want the container to run indefinitely, you need a command at last of the script which doesn't let it end. Something as shown below:

#!/bin/bash
service nginx start
while true; do sleep 1d; done
查看更多
Evening l夕情丶
3楼-- · 2020-02-08 03:53

As of now, the official nginx image uses this to run nginx (see the Dockerfile):

CMD ["nginx", "-g", "daemon off;"]

In my case, this was enough to get it to start properly. There are tutorials online suggesting more awkward ways of accomplishing this but the above seems quite clean.

查看更多
来,给爷笑一个
4楼-- · 2020-02-08 03:55

Docker as a very nice index of offical and user images. When you want to do something, chances are someone already did it ;)

Just search for 'nginx' on index.docker.io, you will see, there is an official nginx image: https://registry.hub.docker.com/_/nginx/

There you have a full guide to help you start your webserver.

Feel free to take a look at other users nginx image to see variants :)

The idea is to start nginx in foreground mode.

查看更多
相关推荐>>
5楼-- · 2020-02-08 03:57

Using docker-compose:

To follow the recommended solution, add to docker-compose.yml:

command: nginx -g "daemon off"

I also found I could simply add to nginx.conf:

daemon off;

...and continue to use in docker-compose.yml:

command: service nginx start

...although it would make the config file less portable outside docker.

查看更多
Evening l夕情丶
6楼-- · 2020-02-08 03:58

Docker container runs as long as the command you specify with CMD, ENTRTYPOINT or through the command line is running. In your case the service command finishes right away and the whole container is shut down.

One way to fix this is to start nginx directly from the command line (make sure you don't run it as a daemon).

Another option is to create a small script which starts the service and then sleeps forever. Something like:

#!/bin/bash
service nginx start
while true; do sleep 1d; done

and run this instead of directly running the service command.

A third option would be to use something like runit or similar program, instead of the normal service.

查看更多
登录 后发表回答