I have a reactjs front end application and a simple python flask. And I am using a docker-compose.yml to spin up both the containers, and it is like this:
version: "3.2"
services:
frontend:
build: .
environment:
CHOKIDAR_USEPOLLING: "true"
ports:
- 80:80
links:
- "backend:backend"
depends_on:
- backend
backend:
build: ./api
# volumes:
# - ./api:/usr/src/app
environment:
# CHOKIDAR_USEPOLLING: "true"
FLASK_APP: /usr/src/app/server.py
FLASK_DEBUG: 1
ports:
- 8083:8083
I have used links so the frontend service can talk to backend service using axios as below:
axio.get("http://backend:8083/monitors").then(res => {
this.setState({
status: res.data
});
});
I used docker-compose up --build -d to build and start the two containers and they are started without any issue and running fine.
But now the frontend cannot talk to backend.
I am using an AWS ec2 instance. When the page loads, I tried to see the for any console errors and I get this error:
VM167:1 GET http://backend:8083/monitors net::ERR_NAME_NOT_RESOLVED
Can someone please help me?
The backend service is up and running.
You can use a nginx as reverse proxy for both
The compose file
version: "3.2"
services:
frontend:
build: .
environment:
CHOKIDAR_USEPOLLING: "true"
depends_on:
- backend
backend:
build: ./api
# volumes:
# - ./api:/usr/src/app
environment:
# CHOKIDAR_USEPOLLING: "true"
FLASK_APP: /usr/src/app/server.py
FLASK_DEBUG: 1
proxy:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/conf.d/example.conf
ports:
- 80:80
minimal nginx config (nginx.conf):
server {
server_name example.com;
server_tokens off;
location / {
proxy_pass http://frontend:80;
}
}
server {
server_name api.example.com;
server_tokens off;
location / {
proxy_pass http://backend:8083;
}
}
The request hits the nginx container and is routed according the domain to the right container.
To use example.com and api.example.com you need to edit your hosts file:
Linux: /etc/hosts
Windows: c:\windows\system32\drivers\etc\hosts
Mac: /private/etc/hosts
127.0.0.1 example.com api.example.com
Related
I have one docker container with nginx (path docker/nginx):
services:
web:
image: nginx
volumes:
- ./templates:/etc/nginx/templates
ports:
- "80:80"
networks:
- nginx-net
networks:
nginx-net:
name: proxynet
external: true
And docker with app (docker/app):
services:
php:
build:
context: .
dockerfile: Dockerfile
container_name: app_php
networks:
- nginx-net
networks:
nginx-net:
external: true
name: proxynet
File nginx conf.template
server {
listen 80 default_server;
server_name subdomain.domain.com;
location /{
proxy_pass app_php:80/;
}
}
I want nginx to redirect to the app container and to other containers in the future.
But in web browser subdomain.domain.com show 504 error.
ping -c 4 app_php - ping from nginx container is ok
I spent a few hours and I don't know what the problem is, I suspect nginx conf
You need to expose app_php on another port eg. 8000 and have nginx act as proxy for that. Something like:
services:
php:
build:
context: .
dockerfile: Dockerfile
container_name: app_php
networks:
- nginx-net
ports:
- 8000:80
nginx.conf:
server {
listen 80 default_server;
server_name subdomain.domain.com;
location /{
proxy_pass app_php:8000;
}
}
Probably best to have all containers in a single docker-compose.yml file also.
I have a docker-compose.yml file with multiple services connected to the same network. the services include nginx exposes port 80, a web app(app1) running on 0.0.0.0:8000, a second web app(app2) running on 0.0.0.0:7000, yet another web app(app3) running on 0.0.0.0:5000 and so on
I can access all the apps from the browser when a go to 0.0.0.0:8000 or 0.0.0.0:5000 etc
I want to access the first app with "http://localhost" from the browser i.e the first web app to be the root. then the others to be subdomains for example; for app2 to be access from this: "http://localhost/app2"
WHAT I HAVE TRIED
I have created a server block for each web app as shown bellow
>> cat app1.conf
upstream app1 {
server app1:8000;
}
server {
# this server listens on port 80
listen 80 ;
server_name app1;
# the location / means that when we visit the root url (localhost:80/), we use this configuration
location / {
proxy_pass http://app1;
}
}
now for one of the subdomains i have :
upstream app2 {
server app2:8000;
}
server {
# this server listens on port 80
listen 80 ;
server_name app2;
# the location / means that when we visit the root url (localhost:80/), we use this configuration
location /app2 {
proxy_pass http://app2;
}
}
Here is my docker-compose.yml file:
version: "3.8"
services:
app1:
image: app1 image
container_name: app1
networks:
- local-network
ports:
- "8000:80"
restart: unless-stopped
app2:
image: app2 image
container_name: app2
networks:
- local-network
ports:
- "7000:80"
restart: unless-stopped
app3:
image: app3 image
container_name: app3
networks:
- local-network
ports:
- "5000:80"
restart: unless-stopped
nginx:
image: nginx:latest
container_name: nginx
networks:
- local-network
command: nginx -g "daemon off;"
volumes:
- ./nginx/sites-available/app1.conf:/etc/nginx/conf.d/sites-available/app1.conf
- ./nginx/sites-available/app2.conf:/etc/nginx/conf.d/sites-available/app2.conf
- ./nginx/sites-available/app3.conf:/etc/nginx/conf.d/sites-available/app3.conf
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
restart: unless-stopped
depends_on:
- app1
- app2
- app3
networks:
local-network
in my nginx.conf I including the sites-enabled and manually created symlink of the mounted sites-available configuration files in the nginx container.
On the browser "http://localhost/" works fine but "http://localhost/app1" or app2 or app3 redirects to http://localhost/
There are no errors in the docker logs
What might I be doing wrong?
Here is a quick example, both nginx conf file and docker-compose.yml below:
~/Projects/docker/echo-test $ tree
.
├── docker-compose.yml
└── nginx
└── app.conf
1 directory, 2 files
~/Projects/docker/echo-test $ cat nginx/app.conf
upstream app1 {
server echoer1:7777;
}
upstream app2 {
server echoer2:8888;
}
upstream app3 {
server echoer3:9999;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app1;
}
location /app2 {
proxy_pass http://app2;
}
location /app3 {
proxy_pass http://app3;
}
}
~/Projects/docker/echo-test $ cat docker-compose.yml
version: "3.8"
services:
echoer1:
hostname: echoer1
image: mendhak/http-https-echo
environment:
- HTTP_PORT=7777
echoer2:
hostname: echoer2
image: mendhak/http-https-echo
environment:
- HTTP_PORT=8888
echoer3:
hostname: echoer3
image: mendhak/http-https-echo
environment:
- HTTP_PORT=9999
nginx:
image: nginx
command: nginx -g "daemon off;"
volumes:
- ./nginx/app.conf:/etc/nginx/conf.d/app.conf
ports:
- "80:80"
fhsmgr proxy works at / but not any other location with 404
fhsdir proxy gives 404 at /dir, though when i browse directly to it on localhost:5000 i get the expected output, so the host is up and running. also, nginx does not complain about invalid host and exit like i've seen it do before.
i have tried trailing '/' so '/dir/' to no avail.
i have tried putting fhsmgr at '/mgr' and i get the expected 404 at index '/' but then 404 again at '/mgr'.
i have tried without proxy_redirect off; as well.
i have removed the upstream statements and just directly put in container names
seemingly the only thing it'll let me proxy is at '/', though i know i've proxied to other servers at different location paths in setups like this before.
-- docker compose
version: "3.7"
services:
fhsmgr:
build: fhsmgr
restart: always
fhsdir:
build: fhsdir
restart: always
ports:
- 5000:5000
nginx:
build: nginx
restart: always
ports:
- 80:80
environment:
- NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx
- FHSMGR_HOST=fhsmgr
- FHSMGR_PORT=5000
- FHSDIR_HOST=fhsdir
- FHSDIR_PORT=5000
-- nginx conf
events {}
http {
# upstream fhsmgr {
# server ${FHSMGR_HOST}:${FHSMGR_PORT};
# }
# upstream fhsdir {
# server ${FHSDIR_HOST}:${FHSDIR_PORT};
# }
# a simple reverse-proxy
server {
listen 80 default_server;
location / {
proxy_pass http://fhsmgr:5000;
proxy_redirect off;
}
location /dir {
proxy_pass http://fhsdir:5000;
proxy_redirect off;
}
}
}
i am modifying this project https://github.com/AwsGeek/lightsail-containers-nginx to get it to work for my use case. Haven't gotten to lightsail, just using docker compose locally
You miss the container_name in your docker-compose,try this
version: "3.7"
services:
fhsmgr:
build: fhsmgr
restart: always
container_name: fhsmgr # allow other containers to access by container_name
fhsdir:
build: fhsdir
restart: always
container_name: fhsdir
ports:
- 5000:5000
nginx:
build: nginx
restart: always
ports:
- 80:80
environment:
- NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx
- FHSMGR_HOST=fhsmgr
- FHSMGR_PORT=5000
- FHSDIR_HOST=fhsdir
- FHSDIR_PORT=5000
I am trying to setup an nginx container that will show at the "http://server_ip/" path the nginx html page and on the "/app" path the tutum/hello-world container. as a follow up, want to be able to get to the "hello-world" container only from the "http://server_ip/app" path and not via http://server_ip:1500.
I created the following docker-compose:
version: '3'
services:
proxy:
container_name: proxy
image: nginx
ports:
- "80:80"
volumes:
- $PWD/html:/usr/share/nginx/html
- $PWD/config/nginx.conf:/etc/nginx/conf.d/nginx.conf
networks:
- backend
webapp:
container_name: webapp
image: tutum/hello-world
ports:
- "1500:80"
networks:
- backend
networks:
backend:
then I have the following nginx.conf file:
server {
listen 80; # not really needed, but more informative
location = / {
root /usr/share/nginx/html;
}
location = /app/ {
proxy_pass http://localhost:1500/;
}
}
If I try to get to each of the containers by their http://server_ip:PORT, I get there. if I try http://server_ip/app I get "404 not found". what am I missing? did I put the conf file in the wrong folder? how do I limit the availability of the "hello-world" only to the "http://server_ip/app" path and not via "http://server_ip:1500".
Your containers using the "backend" docker network, as you stated in the compose file.
Inside that they reach each other with the service names, so from the "proxy" service you can reach "webapp" service on http://webapp (or http://webapp:80) and from the "webapp" service you can reach "proxy" on http://proxy or (http://proxy:80).
On your computer if you type http://localhost:1500/ you will reach the webapp service and if you type http://localhost:80/ you will reach proxy service.
The port mapping 1500:80 means that your computer 1500 port is mapped to the webapp container 80 port.
So in nginx.conf do this:
proxy_pass http://webapp:80/;
Also if you want to make your webapp not accessible from your host on localhost:1500 remove the ports part in the webapp service spec:
version: '3'
services:
proxy:
container_name: proxy
image: nginx:1.11
ports:
- "80:80"
volumes:
- $PWD/html:/usr/share/nginx/html
- $PWD/nginx.conf:/etc/nginx/conf.d/default.conf
networks:
- backend
webapp:
container_name: webapp
image: tutum/hello-world
networks:
- backend
networks:
backend:
I am completly lost.. So i have two proxy_paths in my nginx conf: '/' and '/api'. '/' redirects to my frontend and is working perfectly but the '/api' proxy path is not working at all. The proxy server is logging requests to '/api/' but not forwarding them to my actual api-server. I'm missing something. Is the '/' proxy_path some sort of catch all that overrides any other proxy paths? Any assistance would be invaluable! Thanks! Here are my configs:
nginx reverse proxy conf:
server {
listen 80;
server_name proxy;
location / {
proxy_pass http://frontend_prod:3000/;
}
location /api {
proxy_pass http://api_prod:3333/;
}
}
docker-compose:
version: '3.1'
services:
proxy:
build: ./proxy/
ports:
- '9000:80'
restart: always
depends_on:
- frontend_prod
- api_prod
frontend_prod:
build: ./frontend/nginx/
ports:
- '3000'
depends_on:
- api_prod
restart: always
db:
image: mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: hunter2
api_prod:
build: ./backend/api/
command: npm run production
ports:
- '3333'
depends_on:
- db