I have the following setup:
Four services in docker-compose.yml: my_nginx
, my_client
, my_api
and my_db
.
my_nginx
as a proxy pass to reach my_client:8000
and my_api:8001
(both are Node.js).my_client
is the Angular application which has server side
rendering.my_api
is a node app, which gets data from my_db
.Then, in my windows hosts
file I have the same host names I defined in the my_nginx
config server blocks:
`127.0.0.1 my-app.local api.my-app.local`
so they can be accessed by host name.
Next, in my angular application I have the api url defined in each environment file, so for the local dev environment it is http://api.my-app.local
.
It works perfectly fine when the api request comes from within the browser. But when the request is initiated server side, from the my_client
container, I get a very long (many rows) error, but the gist of it (and the commonly used text I could find it by, searching Google) is: message: 'Http failure response for (unknown url): 0 Unknown Error'
. However, the other questions I could find didn't answer my issue. They're either not server-rendered, or mentioning CORS or containers not having internet access.
I do allow any client from my api: res.setHeader('Access-Control-Allow-Origin', '*');
, CORS is not an issue. Also, if I replaced http://api.my-app.local
with http://some-real-website.com
, then the request works, it goes through, I'm just not receiving appropriate data because it's not my api, but the point is that my containers are able to access the internet. Jumping into the my_client
container and ping api.my-app.local
works (showing 127.0.0.1, don't know if this means anything). I don't know why that works, while pinging with http://...
doesn't, but I can't replace http://api.my-app.local
with api.my-app.local
in my Angular app, because then it would make the request to itself, like: http://my-app.local/api.my-app.local
.
And lastly, if I ping http://api.my-app.local
then I get unknown host
. Don't know why, as far as the container is concerned, http://api.my-app.local
is on the internet, right?. I mean, I expect things to work the same, no matter who/what/where from tries to access, like:
http://api.my-app.local
(can be me/browser, can be a container, whatever)127.0.0.1
my_nginx
containerapi.my-app.local
my_api
container.Should be very simple.
EDIT:
Docker version: 17.12.0-ce-win47 (15139) stable
docker-compose.yml
:
version: '3.4'
services:
my_nginx:
container_name: my_nginx
build:
context: ./nginx
image: my_nginx
ports:
- '80:80'
- '443:443' # SSL (not used on 'my-app.local')
links:
- my_api
- my_client
my_api:
container_name: my_api
build:
context: ./node_api
image: my_api
ports:
- '8001:8001'
volumes:
- ./node_api/app:/var/www/api.my-app.com
- /var/www/api.my-app.com/node_modules
links:
- my_db
depends_on:
- my_db
networks:
default:
aliases:
- api.my-app.local
tty: true
# command: ["pm2-docker", "pm2.config.json"] < moved to Dockerfile
my_client:
container_name: my_client
build:
context: ./node_client
image: my_client
ports:
- '8000:8000'
volumes:
- ./node_client/app:/var/www/my-app.com
- /var/www/my-app.com/node_modules # Inside the container, use the node_modules installed there.
links:
- my_api
tty: true
command: ["pm2-docker", "pm2.config.json"]
my_db:
container_name: my_db
build:
context: ./mysql
image: my_db
restart: always
ports:
- '3306:3306'
volumes:
- './_space/mysql:/var/lib/mysql'
Nginx config api server block:
server {
listen 80;
server_name api.my-app.local;
charset utf-8;
client_max_body_size 4096M;
location / {
proxy_pass http://my_api:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location ~ /\.ht {
deny all;
}
}
And the one for the client is the same, except server_name
and proxy_pass
directives, of course. I don't know what proxy_http_version
, proxy_set_header
and proxy_cache_bypass
are for, I just copied the config from an online example.
In your docker-compose.yml you need to declare the alias for my_nginx and link for my_client:
my_nginx:
networks:
default:
aliases:
- api.my-app.local
my_client:
links:
- my_nginx