0

So I'm learning Docker and how to containerize apps into services. Not sure if I get it all the way.

I have three services:

  1. web-server nginx server that binds ports 80 and 443 to outside. Basically the "frontend" of the app.
  2. app1 NodeJS app that serves content on port 3000
  3. app2 NodeJS app that serves content on port 3000, basically it's a clone of app1 and I use it just for learning purposes.

Now my idea of running this "app" in prod would be to launch docker-compose up which launches all the services. Is this a correct way to launch multi container apps?

My repo structure is this:

.
├── Dockerfile
├── app1
│   ├── Dockerfile
│   ├── index.js
│   ├── package-lock.json
│   └── package.json
├── app2
│   ├── Dockerfile
│   ├── index.js
│   ├── package-lock.json
│   └── package.json
├── docker-compose.yml
├── index.html
└── web-server.conf

The root Dockerfile is for web-server service. My docker-compose.yml looks like this:

version: '3'
services:
  web-server:
    container_name: web-server
    build: .
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - app1
      - app2
  app1:
    container_name: app1
    build: ./app1
    restart: always
  app2:
    container_name: app2
    build: ./app2
    restart: always

The command docker-compose up builds app1 and app2 images, however it fails on web-server image because nginx throws an error:

host not found in upstream "app1" in /etc/nginx/conf.d/default.conf:11
nginx: [emerg] host not found in upstream "app1" in /etc/nginx/conf.d/default.conf:11

web-server service Dockerfile

FROM nginx:alpine
EXPOSE 80

COPY ./web-server.conf /etc/nginx/conf.d/default.conf
COPY ./index.html /var/www/html/

RUN apk add bash

RUN nginx

Contents of web-server.conf:

server {
 listen *:80;
 server_name web_server;
 root /var/www/html;

 location / {
   index index.html;
 }

 location /app1 {
   proxy_pass http://app1:3000;
   proxy_redirect off;
 }

 location /app2 {
   proxy_pass http://app2:3000;
   proxy_redirect off;
 }
}

To me it looks like the config for nginx won't recognize http://app1 hostname at the build time. I tried experimenting and I replaced the values for proxy_pass directives with localhost. This will build the image which I can run along with other images. If I do bundle exec -it web-server-image /bin/bash and I try curl http://app1:3000 then it works. If I edit the nginx config to point to these URLs it starts to work.

So I think I'm getting there but it seems it won't recognize the host names when running docker-compose up.

Any ideas? Is my approach correct?

1 Answer 1

1

If you just delete the two RUN lines at the end of the web-server Dockerfile this will work fine.

If you look at the nginx image's Dockerfile that ends with

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

which will be inherited by your image; you don't need to do anything special to cause nginx to start when the container launches.

Meanwhile, at the point the Dockerfile runs, the build sequence runs in a fairly isolated environment: none of the Compose network environment is set up, other containers aren't necessarily running, volumes aren't attached, etc. The only custom settings that take effect are things specifically in the build: block in the docker-compose.yml file.

So: when the Dockerfile runs RUN nginx, it tries to start nginx inside the build environment, but that's not attached to the Compose network, so it fails. But you don't need to do that at all because the base image already has a CMD nginx ... setting, and just deleting that line will fix it.

Sign up to request clarification or add additional context in comments.

1 Comment

For real! Damn serves me well, I should read more about hosted docker images next time (or just build my own). Works great now, thanks a ton. I wasted several hours on this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.