1

There have been various similar cases here on stackoverflow but they're pretty much all refer to incorrect ports or using localhost as the IP instead of the docker-machine ip.

The vue.js app connects perfectly fine to the websocket and works. However, the GET requests to 192.168.99.100:8080/meows and other endpoints all hit the nginx 502 bad gateway. Manually accessing the endpoints (instead of vue.js) also hit 502 bad gateway.

The ip's are properly set. Ports are the same everywhere :8080. endpoints have the correct http verband all have an nginx upstream pointing at the server location /..{}. Yet no problems connecting to the network, all data passing through no problem.

EDIT: Im running windows 7 with the docker-toolbox because my windows version doesnt have the whole virtualization thing. No further configuration after installation has been done.

The architecture is the following:

enter image description here

docker-compose

version: "3.6"

services:
  meow:
    build: "."
    command: "meow-service"
    depends_on:
      - "postgres"
      - "nats"
    environment:
      POSTGRES_DB: "meower"
      POSTGRES_USER: "meower"
      POSTGRES_PASSWORD: "123456"
      NATS_ADDRESS: "nats:4222"
  query:
    build: "."
    command: "query-service"
    depends_on:
      - "postgres"
      - "nats"
    environment:
      POSTGRES_DB: "meower"
      POSTGRES_USER: "meower"
      POSTGRES_PASSWORD: "123456"
      NATS_ADDRESS: "nats:4222"
      ELASTICSEARCH_ADDRESS: "elasticsearch:9200"
  pusher:
    build: "."
    command: "pusher-service"
    depends_on:
      - "nats"
    environment:
      NATS_ADDRESS: "nats:4222"
  postgres:
    build: "./postgres"
    restart: "always"
    environment:
      POSTGRES_DB: "meower"
      POSTGRES_USER: "meower"
      POSTGRES_PASSWORD: "123456"
  nats:
    image: "nats-streaming:0.9.2"
    restart: "always"
  elasticsearch:
    image: 'docker.elastic.co/elasticsearch/elasticsearch:6.2.3'
  nginx:
    build: "./nginx"
    ports:
      - "8080:80"
    depends_on:
      - "meow"
      - "query"
      - "pusher"

nginx.conf:

user nginx;
worker_processes 1;

events {
  worker_connections 1024;
}

http {
  upstream meows_POST {
    server meow:8080;
  }

  upstream meows_GET {
    server query:8080;
  }

  upstream search_GET {
    server query:8080;
  }

  upstream pusher {
    server pusher:8080;
  }

  server {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    add_header Access-Control-Allow-Origin *;

    location /meows {
      limit_except GET POST OPTIONS {
        deny all;
      }
      proxy_pass http://meows_$request_method;
    }

    location /search {
      limit_except GET OPTIONS {
        deny all;
      }
      proxy_pass http://search_GET;
    }

    location /pusher {
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_pass http://pusher;
    }
  }
}

And to show that the go application also uses the correct ports, the following is the port listening for

func newRouter() (router *mux.Router) {
    router = mux.NewRouter()
    router.HandleFunc("/meows", listMeowsHandler).
        Methods("GET")
    router.HandleFunc("/search", searchMeowsHandler).
        Methods("GET")
    return
}

router := newRouter()
if err := http.ListenAndServe(":8080", router); err != nil {
    log.Fatal(err)
}
Rien
  • 398
  • 2
  • 12
  • 37

2 Answers2

1

Instead of:

ports:
  - "8080"

in every docker-compose service, try:

ports:
  // I assume your containers operate on 8080 port
  - "8080:8080"

By specifying just 8080 you assign container's port 8080 to your host's random port. I believe you don't want that. You can verify that with docker-compose ps.

Also why do you change the default port everywhere to 8080? With Docker it's not necessary, you can simply map the port to a different port on the host side, eg:

ports:
    - "8080:80"

Remember that containers talk to each other using their ports and those ports don't need to be published. You only publish ports you want to access "from the outside world".

Mike Doe
  • 16,349
  • 11
  • 65
  • 88
  • Im pretty new to docker so certain decisions like the port are unfounded. When changing the `docker-compose` meow, query and pusher to `8080:8080` or `8080:80` I get errors that `bind for 0.0.0.0:8080 failed: port is already allocated` – Rien May 31 '19 at 10:11
  • The ports must be published I believe because I am trying to access them from my own machine (which docker is also running on) for the vue.js application, that one isnt docker-ized. – Rien May 31 '19 at 10:12
  • Yes, because your host have only one port 8080. Only nginx's port should be exposed in my opinion. That's the only endpoint which should be exposed. Vue is going to talk ONLY to this endpoint which acts as a gateway to the underlying infrastructure. – Mike Doe May 31 '19 at 10:12
  • Sounds logical. How do I change it so that only nginx port is exposed and all the services endpoints are accessible? – Rien May 31 '19 at 10:13
  • Is Vue going to talk to other services directly? Or only nginx? – Mike Doe May 31 '19 at 10:14
  • But it doesn't talk to the `meow` service per se (directly to that container). It talks to the `nginx` container which proxies the request. You don't need to expose any `meow`'s ports at all. Containers CAN talk to each other without having any ports exposed. You only expose ports when you want an access to a container from the OUTSIDE (eg. JavaScript app in the browser). – Mike Doe May 31 '19 at 10:19
  • I understand that, however, I am attempting to access all containers via my own machine using my browser (eventually vue.js running on my own machine) but `502 bad gateway`. I edited the ports to be different in both `docker-compose` and the `nginx.con` but still 502. Edit: i edited my original post with my current configuration (aka different ports) – Rien May 31 '19 at 10:22
  • 1
    If you wish to access containers from your machine then use a different port for each service, eg. 8080:8080, in another 8081:8080, 8082:8080 etc. Can't help you more, you should check nginx's logs. Also please keep your question updated with current docker-compose file for reference. – Mike Doe May 31 '19 at 10:22
  • It seems to have been solved, allow me to properly test it and ill get back in a bit. – Rien May 31 '19 at 10:25
  • It works @emix but is there also a solution where all services work through 8080? Ive seen it work on other apps and wonder why it doesnt on mine – Rien May 31 '19 at 10:54
  • How would I solve it by directing it only though nginx? – Rien May 31 '19 at 10:57
  • It should already be working this way, through `/meows`, `/pusher` etc. endpoints. Please check your nginx config, am I supposed to explain to you how your app works? :D – Mike Doe May 31 '19 at 10:58
  • Well, this did not lead to a proper solution, endpoints should be accessible via same port, a requirement. Replies are becoming condescending and unfriendly. – Rien May 31 '19 at 11:14
  • That endpoints are accessible via the same port (nginx's exposed port), I'm trying to explain that to you from the beginning. The whole idea of the nginx service on the picture is that the nginx should be exposed ONLY, other services should NOT be accessible from the outside world. Kindly read about API Gateways. – Mike Doe May 31 '19 at 11:15
  • Using `port - 8080` leads to `502 bad gateway` and `8080:8080` to `port already allocated`. Nginx is set to let 80 to 8080 and the endpoints are 8080 yet either 502 or already allocated. – Rien May 31 '19 at 11:22
  • And did you check nginx logs why's that? Your nginx configuration is simply invalid. I already told you: containers don't talk through exposed ports but their internal ports. You don't need to expose ports everywhere, only nginx port should be exposed (8080:80 since nginx works on port 80) so VUE app can talk to it. Nginx CAN talk to every container inside its network without them having their ports exposed. Sorry I already pointed out every reason why's this not working. Please go through my comments again thoroughly, I'm not going to discuss this in comments any further. – Mike Doe May 31 '19 at 11:40
0

Removed all

  ports:
  - "8080"

properties from all services in the ngix.conf as was proposed.

The underlying problem however was the elasticsearch docker image. Using docker ps -a i could see that after a minute it would exit 78. Using docker-compose logs elasticsearch the error was max virtual memory areas vm.max_map_count px[ is too low, increase to at least [x]. Using belows command the host machine allocated more memory for the containers and everything was solved.

docker-machine ssh
sudo sysctl -w vm.max_map_count=262144
Rien
  • 398
  • 2
  • 12
  • 37