I was trying to start my Angular client on Nginx in the docker container.
The source codes is here.
The docker-compose file:
mongodb:
image: mongo
volumes:
- mongodata:/data/db
ports:
- "27017:27017"
networks:
- backend
client:
image: hantsy/angular-spring-reactive-sample-client
environment:
- "BACKEND_API_URL=http://api:8080/"
ports:
- "80:80"
depends_on:
- api
networks:
- frontend
- backend
api:
image: hantsy/angular-spring-reactive-sample-server
environment:
- "SPRING_DATA_MONGODB_URI=mongodb://mongodb:27017/blog"
ports:
- "8080:8080"
depends_on:
- mongodb
networks:
- backend
volumes:
mongodata:
# driver: local-persist
# driver_opts:
# mountpoint: ./data
networks:
frontend:
backend:
And Nginx config, I used the Perl module to load dynamic env at runtime.
# see: https://hackerbox.io/articles/dockerised-nginx-env-vars/ to set env in nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
load_module modules/ngx_http_perl_module.so;
env BACKEND_API_URL;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
sendfile on;
perl_set $baseApiUrl 'sub { return $ENV{"BACKEND_API_URL"}; }';
server {
listen 80;
server_name localhost;
location /api {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^/api/(.*) /$1 break;
proxy_pass ${baseApiUrl};
}
location /test {
return 200 'the environment variable contains: ${baseApiUrl}';
}
location / {
try_files $uri $uri/ index.html;
}
}
}
The Dockerfile for Angular client.
# Set nginx base image
FROM nginx:alpine-perl
LABEL maintainer="Hantsy Bai"
EXPOSE 80
## Remove default Nginx website
RUN rm -rf /usr/share/nginx/html/*
RUN rm /etc/nginx/conf.d/default.conf
ADD ./nginx/nginx.conf /etc/nginx/nginx.conf
ADD ./client/dist /usr/share/nginx/html
When build and run the applications with docker-compose up
command, and try to access sign in, it will hint the /api
URI, which is configured to pass through API service.
But I got a 502 Gateway in the browser console.
In the Nginx logging, I saw the following info.
client_1 | 2020/05/24 13:47:21 [error] 9#9: *4 no resolver defined to resolve api, client: 172.20.0.1, server: localhost, request: "GET /api/auth/user HTTP/1.1", host: "localhost", referrer: "http://localhost/auth/signin"
The api service name is not resolved in Nginx. I have tested the api uri http://localhost:8080, and make sure it is available.
Update: I ran a ping command on client
docker and got the result.
❯ docker exec 05dd7dfb01ab ping api
PING api (172.20.0.4): 56 data bytes
64 bytes from 172.20.0.4: seq=0 ttl=64 time=0.118 ms
64 bytes from 172.20.0.4: seq=1 ttl=64 time=0.259 ms
64 bytes from 172.20.0.4: seq=2 ttl=64 time=0.171 ms
64 bytes from 172.20.0.4: seq=3 ttl=64 time=0.091 ms
64 bytes from 172.20.0.4: seq=4 ttl=64 time=0.223 ms
64 bytes from 172.20.0.4: seq=5 ttl=64 time=0.169 ms
64 bytes from 172.20.0.4: seq=6 ttl=64 time=0.220 ms
Resolved: add resolver 127.0.0.11
hard code in the nginx.conf to overcome this issue temporarily.