Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom nginx container exits immediately when part of docker-compose

I'm trying to learn how to use docker compose with a simple setup of an nginx container that reroutes requests to a ghost container. I'm using the standard ghost image but have a custom nginx image (that inherits from the standard image).

When I run the composition using "docker-compose up" it exits immediately with "docker_nginx_1 exited with code 0". However, when I build and run it manually, it runs fine and I can navigate my browser to the container and view the default nginx page. What am I misunderstanding about my compose file that causes it to behave differently than being custom built? What can I change to get it to stay running?

Disclaimer: I am also learning nginx as I go, so learning two things at once may be causing me undue problems.

EDIT: The original files were a bit more complex, but I've reduced the issue to simply: If I use the build command for a custom image that does nothing but inherit from the default nginx image, it exits immediately. If I use the default nginx image, it works. These are the now relevant files:

Compose file:

ghost:  expose:    - "2368"  image: ghost  nginx:   # image: nginx << If I use this instead of my custom build, it doesn't exit   build: ./nginx   ports:     - "80:80"     - "443:443"   links:    - ghost 

nginx/Dockerfile:

FROM nginx 

ORIGINAL FILES (with the same compose file as above):

nginx/Dockerfile:

FROM nginx RUN rm /etc/nginx/nginx.conf COPY conf/nginx.conf /etc/nginx/nginx.conf COPY conf/sites-available/ghost /etc/nginx/sites-available/ghost RUN mkdir /etc/nginx/sites-enabled RUN ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost  EXPOSE 80 443  # Is this even the right command I have no idea  CMD service nginx start 

nginx/conf/nginx.conf:

daemon off;  user  nginx; # Let nginx figure out the processes I guess worker_processes  auto;  error_log  /var/log/nginx/error.log warn; pid        /var/run/nginx.pid;   events {     worker_connections  1024; }  http {     include       /etc/nginx/mime.types;     default_type  application/octet-stream;      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                       '$status $body_bytes_sent "$http_referer" '                       '"$http_user_agent" "$http_x_forwarded_for"';      access_log  /var/log/nginx/access.log  main;      sendfile        on;     #tcp_nopush     on;      keepalive_timeout  65;      #gzip  on;      include /etc/nginx/conf.d/*.conf; } 

nginx/conf/sites-available/ghost

server {   listen 80;   server_name 127.0.0.1;   access_log /var/log/nginx/localhost.log;    location / {     proxy_set_header X-Real-IP $remote_addr;     proxy_set_header HOST $http_host;     proxy_set_header X-NginX-Proxy true;      proxy_pass http://0.0.0.0:2368;     proxy_redirect off;   } } 

Running compose-up:

plays-MacBook-Pro:docker play$ docker-compose up Creating docker_ghost_1... Creating docker_nginx_1... Attaching to docker_ghost_1, docker_nginx_1 docker_nginx_1 exited with code 0 Gracefully stopping... (press Ctrl+C again to force) Stopping docker_ghost_1... done 

Running manually:

plays-MacBook-Pro:nginx play$ docker build --no-cache -t nginx_custom . Sending build context to Docker daemon 8.704 kB Step 0 : FROM nginx  ---> 914c82c5a678 Step 1 : RUN rm /etc/nginx/nginx.conf  ---> Running in 4ce9de96bb36  ---> 98f97a9da4fc Removing intermediate container 4ce9de96bb36 Step 2 : ADD conf/nginx.conf /etc/nginx/nginx.conf  ---> dd3e089208a9 Removing intermediate container 36b9a47e0806 Step 3 : ADD conf/sites-available/ghost /etc/nginx/sites-available/ghost  ---> 55fae53e5810 Removing intermediate container a82741d24af4 Step 4 : RUN mkdir /etc/nginx/sites-enabled  ---> Running in 7659ead01b7b  ---> 406be1c42394 Removing intermediate container 7659ead01b7b Step 5 : RUN ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost  ---> Running in e9658a08affa  ---> 021a84216e8a Removing intermediate container e9658a08affa Step 6 : EXPOSE 80 443  ---> Running in 230e4523794c  ---> 23d85e1a04cb Removing intermediate container 230e4523794c Step 7 : CMD service nginx start  ---> Running in 209e129cae21  ---> d7004d6fa223 Removing intermediate container 209e129cae21 Successfully built d7004d6fa223 plays-MacBook-Pro:nginx play$ docker run -t nginx_custom [It sits here on an empty line, running in the background] 
like image 867
Merrillogic Avatar asked Nov 15 '15 19:11

Merrillogic


People also ask

Why does my Docker container exit immediately?

You're running a shell in a container, but you haven't assigned a terminal: If you're running a container with a shell (like bash ) as the default command, then the container will exit immediately if you haven't attached an interactive terminal.

How do you stop a container from exiting Docker compose?

In order to prevent the docker container from exiting immediately after creation, tty should be set to true in the docker-compose. yml file. tty: true in docker-compose corresponds to the docker run -it . With tty: true for the service, the created by docker-compose up -d container status is Up .

Does Docker compose exit?

The docker compose up command aggregates the output of each container (like docker compose logs --follow does). When the command exits, all containers are stopped. Running docker compose up --detach starts the containers in the background and leaves them running.


2 Answers

The CMD in your Dockerfile should start a process which needs to run in foreground. The command service nginx start runs the process in deamon mode and thus your container exits cleanly because the service command exits.

Use the following CMD ["nginx", "-g", "daemon off;"] to start nginx (taken from official image) and it should work correctly.

like image 74
mike Avatar answered Sep 28 '22 00:09

mike


Just ran into this same issue, and the initial fix was to change the name of the service in docker-compose.yml.

This worked, but the reason it worked is because Docker-compose caches the build & ties it to the service name. Every docker-compose up after the first one just uses what it built before, so any changes you make to the Dockerfile, or that section of the docker-compose.yml are basically ignored.

When you (and I) changed the service name, it triggered a new build since that service name hasn't been tagged before.

The real solution is to do a: docker-compose build to rebuild the image (followed by a docker-compose up). Their documentation doesn't really emphasize this issue.

like image 23
Gerrat Avatar answered Sep 27 '22 23:09

Gerrat