Hi I have a machine (server) and nginx(native) installed on this server.
My domain is hotels.com(for example)
And subdomain api.hotels.com
this is the conf file for subdomain on machine (native nginx):
server {
listen 80;
server_name api.hotels.com;
location / {
proxy_pass http://127.0.0.1:3000$request_uri;;
}
}
I build my app with microservices architecture, 2 services:
users-service:3030 , payment-service:3080
i want to expose api.hotels.com/users/ AND api.hotels.com/payment
so i choose to use nginx(docker container) as apiGateway on port:3000 and i want to proxy to specific service, so use this config
server {
listen 3000;
location /users/ {
proxy_pass http://users:3030/;
}
location /payment/ {
proxy_pass http://users:3080/;
}
}
in localhost it work fine for me but in server and with domain something wrong happen.
if i try to get http://api.hotels.com i get nginx from nginx(machine): Good
but if try to get http://api.hotels.com/users it rewrite the url in browser to http://127.0.0.1/users and then break.
*Note: i use docker-compose to up this 2 services and nginx container.
Questions:
1) how to fix this?
2) my flow is ok, or have any other flow for this app?
My purpose flow example:
1) Client http://api.hotels.com/users
2) Server all api.hotels.com ==> http://localhost:3000(api gateway)
3) Nginx Container(on port:3000) ==> proxy to spesific service by name (users in this example)
Your application looks good, the problem is only configuration.
you can try this configuration:
server {
server_name api.hotels.com;
listen 80;
location /users/ {
proxy_pass http://users:3030/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host
}
location /payment/ {
proxy_pass http://users:3080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host
}
}
in this case your nginx container expose ports => INCOMING_PORT:80
then in your example it will look like this in docker-compose.yml
...
services:
api-gateway:
image: nginx:latest
ports:
- "3000:80"
...
in this way your api gateway is more dynamically. you can change the income port any time and nginx inside container will listen for port 80, and will proxy for spesific service by name.
good luck :)
Related
I'm deploying some services using Docker, with docker-compose and a nginx container to proxy to my domain.
I have already deployed the frontend app, and it is accessible from the web. Supposedly, I only need to expose the frontend/nginx port to the web, without me needing to expose the rest of the services. But I'm not able to do that for now.
For example, Client -> Login Request -> frontend <-> (local) Backend get request.
Right now, I'm getting connection refused, and the get is pointing to http://localhost, and not the name of the service defined in docker-compose. (all containers are deployed on the same network, one that I have created)
What do I need to do to configure this?
Here is my nginx config so far:
server {
listen 80 default_server;
listen 443 ssl;
server_name mydomain;
ssl_certificate /etc/letsencrypt/live/mydomain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain/privkey.pem;
location / {
proxy_pass http://frontend:3000/;
}
location /auth {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://auth:3003;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
# Same for the other services
(...)
EDIT:
Should I create a location for every get and post that I have for my services?
As:
location getUser/ {
proxy_pass http://auth:3003;
}
I'm trying to use nginx as a reverse proxy inside a container points to the different PHP application container.
My PHP container gets requests from external port 8080 and forwards it to internal 80. I want my nginx to get listen to port 80 and forward the request to the PHP container on port 8080 but have issues redirecting the request.
My nginx Dockerfile:
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf
My nginx default.conf:
server {
listen 80;
error_page 497 http://$host:80$request_uri;
client_max_body_size 32M;
underscores_in_headers on;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_pass http://php-container:8080;
proxy_read_timeout 90;
proxy_http_version 1.1;
}
}
I've tried deploying it via docker-compose with the above yml file, but got the same error when CURL to the nginx.
When CURL to HTTP://localhost:8080 (PHP application) and also to HTTP://localhost:80 (nginx) there's a log output from the docker-compose log.
But when CURL to nginx, I got the above error:
You have a misconfiguration here.
nginx (host:80 -> container:8080)
php-app (host:8080 -> container:80)
Nginx can't reach of "localhost" of another container because it's a different container network.
I suggest you create a docker network --network and place both containers to the network. Then in Nginx config, you can refer php-app container by name.
proxy_read_timeout 90;
proxy_redirect http://localhost:80/ http://php-container:8080/;
Besides you can expose only the Nginx port and your backend will be safe.
I have a simple dockerized flask backend that listens on 0.0.0.0:8080 and simple dockerized react frontend that sends a request to localhost:8080/api/v1.0/resource.
Now i want to run those containers in docker compose and issue the request to the service's name backend
The compose file looks like this:
version: '3'
services:
backend:
ports:
- "8080:8080"
image: "tobiaslocker/simple-dockerized-flask-backend:v0.1"
frontend:
ports:
- "80:80"
image: "tobiaslocker/simple-dockerized-react-frontend:v0.1"
The NGINX configuration that works for requests to localhost:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
The frontend sends the request axios.get('http://localhost:8080/api/v1.0/resource')
My questions:
How do i have to configure NGINX to be able to use the service name (e.g. backend)
How do i have to issue the request to match the configuration.
I am not sure how the proxy_pass will take effect when sending the request from the frontend and found it hard to debug.
Regards
My Answers:
How do i have to configure NGINX to be able to use the service name (e.g. backend)
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://backend:8080;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
Taken from here. Not sure if all settings are relevant but only setting proxy_pass didn't work for me.
How do i have to issue the request to match the configuration.
Same as before: axios.get('http://localhost:8080/api/v1.0/resource'), which makes sense, since it works locally and proxied with NGINX.
I have 2 or more containers/docker services running behind Nginx reverse proxy
/app1/ -> localhost:4000
/app2/ -> localhost:5000
.
.
.
Problem is static files doesn't get loaded when accessed via proxy_pass URLs, but runs correctly when accessed separately using port references.
nginx.conf
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
server {
listen 80;
location /app1/ {
proxy_pass http://localhost:5566/;
proxy_set_header Host $host;
}
location /app2/ {
proxy_pass http://localhost:9000/;
#proxy_set_header Host $host;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host:$server_port;
}
location /app3/ {
proxy_set_header Host $host;
proxy_pass http://localhost:5000/;
}
}
}
Any suggestions would be of great help.
PS: Subdomain creation is one of the options but I am looking for any other alternatives if exists.
Do each docker run independently? I think docker-compose can help you. I wonder if you have such problems. with docker-compose, the services are intercommunicating, use nginx proxy apps
docker-compose config
I am new to Docker, and I am trying to run multiple Docker containers on the same server.
I searched and found out that I can do this Assigning vhosts to Docker ports.
Unfortunately, I cannot use wildcard DNS. Therefore, I'd like to configure using subdirectory so that (or are there any alternative solutions?):
test.com/app1 -> app1 (test.com:1234)
test.com/app2 -> app2 (test.com:0987)
Thank you!
The easiest way would be to use nginx like mentioned in the link you posted:
upstream container-1 { server 127.0.0.1:49162; }
server {
listen 80;
server_name container-1.yourdomain.com;
location /<your subdir> {
proxy_pass http://container-1;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
It is not possible directly via Docker.
You would need to use a reverse proxy like nginx or haproxy to do this.