Docker-Compose - Communication with "Internal" Api. - angularjs

I've developed an Angular App, that communicates with an UWSGI Flask Api throught Nginx. Currently I've 3 containers(Angular [web_admin], Api [api_admin], Nginx[nginx])
When I'm running it in my development machine, the communication is working alright. The angular requests goes through the url: http://localhost:5000 and the api response well, everything is working well.
But when I deployed it to my Production Server, I noticed that the application is not working, because the port 5000 is not opened in my firewall.
My question is kind simple, how do I make the angular container, call the api container, through internal network, instead of calling it from the external?
version: '2'
services:
data:
build: data
neo4j:
image: neo4j:3.0
networks:
- back
volumes_from:
- data
ports:
- "7474:7474"
- "7473:7473"
- "7687:7687"
volumes:
- /var/diariooficial/neo4j/data:/data
web_admin:
build: frontend/web
networks:
- front
- back
ports:
- "8001:8001"
depends_on:
- api_admin
links:
- "api_admin:api_admin"
volumes:
- /var/diariooficial/upload/diario_oficial/:/var/diariooficial/upload/diario_oficial/
api_admin:
build: backend/api
volumes_from:
- data
networks:
- back
ports:
- "5000:5000"
depends_on:
- neo4j
- neo4jtest
volumes:
- /var/diariooficial/upload/diario_oficial/:/var/diariooficial/upload/diario_oficial/
nginx:
build: nginx
volumes_from:
- data
networks:
- back
- front
ports:
- "80:80"
- "443:443"
volumes:
- /var/diariooficial/log/nginx:/var/log/nginx
depends_on:
- api_admin
- web_admin
networks:
front:
back:

Links create DNS names on the network for the services. You should have the web_admin service talk to api_admin:5000 instead of localhost:5000. The api_admin DNS name will resolve to the IP address of one of the api_admin service.
See https://docs.docker.com/compose/networking/ for an explanation, specifically:
Each container can now look up the hostname web or db and get back the appropriate container’s IP address. For example, web’s application code could connect to the URL postgres://db:5432 and start using the Postgres database.

Related

Why can I not POST from frontend to backend after containerizing my MERN (React+Node/Express+MongoDB) application?

new to Docker and containers in general. Trying to containerize a simple MERN-based todo list application. Locally on my PC, I can successfully send HTTP post requests from my React frontend to my Nodejs/Express backend and create a new todo item. I use the 'proxy' field in my client folder's package.json file, as shown below:
React starts up on port 3000, my API server starts up on 3001, and with the proxy field defined, all is good locally.
My issue arises when I containerize the three services (i.e. React, API server, and MongoDB). When I try to make the same fetch post request, I receive the following console error:
I will provide the code for my docker-compose file; perhaps it is useful for helping provide me a solution?
version: '3.7'
services:
client:
depends_on:
- server
build:
context: ./client
dockerfile: Dockerfile
image: jlcomp03/rajant-client
container_name: container_client
command: npm start
volumes:
- ./client/src/:/usr/app/src
- ./client/public:/usr/app/public
# - /usr/app/node_modules
ports:
- "3000:3000"
networks:
- frontend
stdin_open: true
tty: true
server:
depends_on:
- mongo
build:
context: ./server
dockerfile: Dockerfile
image: jlcomp03/rajant-server
container_name: container_server
# command: /usr/src/app/node_modules/.bin/nodemon server.js
volumes:
- ./server/src:/usr/app/src
# - /usr/src/app/node_modules
ports:
- "3001:3001"
links:
- mongo
environment:
- NODE_ENV=development
- MONGODB_CONNSTRING='mongodb://container_mongodb:27017/todo_db'
networks:
- frontend
- backend
mongo:
image: mongo
restart: always
container_name: container_mongodb
volumes:
- mongo-data:/data/db
ports:
- "27017:27017"
networks:
- backend
volumes:
mongo-data:
driver: local
node_modules:
web-root:
driver: local
networks:
backend:
driver: bridge
frontend:
My intuition tells me the issue(s) lies in some configuration parameter I am not addressing in my docker-compose.yml file? Please help!
Your proxy config won't work with containers because of its use of localhost.
The Docker bridge network docs provide some insight why:
Containers on the default bridge network can only access each other by IP addresses, unless you use the --link option, which is considered legacy. On a user-defined bridge network, containers can resolve each other by name or alias.
I'd suggest creating your own bridge network and communicating via container name or alias.
{
"proxy": "http://container_server:3001"
}
Another option is to use http://host.docker.internal:3001.

Connection between two docker containers in nextjs in getStaticProps function

I have two separate docker files, one for running nextjs on nginx web server and another for running Laravel on another nginx:
services:
frontendx:
container_name: next_appx
build:
context: ./frontend
dockerfile: Dockerfile
restart: unless-stopped
volumes:
- ./frontend:/var/www/html/frontend
networks:
- app
nginxy:
container_name: nginxy
image: nginx:1.19-alpine
restart: unless-stopped
ports:
- '8080:80'
volumes:
- ./frontend:/var/www/html/frontend
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- frontendx
networks:
- app
and:
services:
backendx:
container_name: laravelx
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
ports:
- '8000:8000'
volumes:
- ./:/var/www
- enlive-vendor:/var/www/vendor
- .//docker-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
depends_on:
- dbx
networks:
- appx
webserverx:
image: nginx:alpine
container_name: webserverx
restart: unless-stopped
tty: true
ports:
- "8090:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- appx
I can connect to the backend container through axios and address like : http://localhost:8090/api/my/api/address
but when I try to get data through getStaticProps I've got the ECONNREFUSED connection error:
const res = await fetch(`http://localhost:8090/api/address`)
I tried to replace the localhost with container ip address like : 172.20.0.2
but I've got the 504 Gateway error.
That's expected.
With axios, you're calling from the browser which is making the request from your host machine network.
But getStaticProps being a SSR function, is run inside your nextjs container. Therefore it must be able to find your backend in your app network.
Now by your setup, the frontend and backend apps are in different isolated networks and you can't connect them like this. But if you put them all your services in the same network, lets say your app(instead of appx) network, you can easily use docker dns:
const res = await fetch(`http://webserverx/api/address`)
Docker knows how to resolve webserverx to your webserverx container.

Wordpress in Docker cannot see DB

I am trying to deploy a Wordpress instance on my PI using docker. Unfortunately I am receiving an error, that the App cannot establish a DB connction.
All containers run in the bridged network. I am exposing port 80 of the APP on 8882 and the port 3306 of the DB on 3382.
A second Wordpress installation on ports 8881 (APP) and 3381 (DB) in the same network are perfectly working, where is the flaw in my setup?
version: '2.1'
services:
wordpress:
image: wordpress
network_mode: bridge
restart: always
ports:
- 8882:80
environment:
PUID: 1000
PGID: 1000
WORDPRESS_DB_HOST: [addr. of PI]:3382
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: secret
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
db:
image: ghcr.io/linuxserver/mariadb
network_mode: bridge
environment:
- PUID=1000
- PGID=1000
- MYSQL_ROOT_PASSWORD=secret
- TZ=Europe/Berlin
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=secret #Must match the above password
volumes:
- db:/config
ports:
- 3382:3306
restart: unless-stopped
volumes:
db:
wordpress:
When containers are on the same bridge network, they can talk to each other using their service names as hostnames. In your case, the wordpress container can talk to the database container using the hostname db. Since it's not talking via the host, any port mapping is irrelevant and you just connect on port 3306.
So if you change
WORDPRESS_DB_HOST: [addr. of PI]:3382
to
WORDPRESS_DB_HOST: db
it should work.
You can remove the port mapping on the database container if you don't need to access the database directly from the host.
Ok, learned something today, like everyday.
Better to have such installations all nicely seperated in different networks and also better do not use same container names, such as DB. Better seperate them like DB-WP1, DB-WP2, etc....
In my setup, I couldn´t see any reason, why it should interfere with each other, but doing the above will not harm anything at all....
You should create network
version: '2.1'
services:
wordpress:
image: wordpress
networks:
- db_net
restart: always
ports:
- 8882:80
environment:
PUID: 1000
PGID: 1000
WORDPRESS_DB_HOST: [addr. of PI]:3382
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: secret
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
db:
image: ghcr.io/linuxserver/mariadb
networks:
- db_net
environment:
- PUID=1000
- PGID=1000
- MYSQL_ROOT_PASSWORD=secret
- TZ=Europe/Berlin
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=secret #Must match the above password
volumes:
- db:/config
ports:
- 3382:3306
restart: unless-stopped
volumes:
db:
wordpress:
networks:
db_net:
driver: bridge

Docker + React App: how to use in the Frontend side, files saved in the API (server) side folder?

So, I'm stuck in an issue related to using files stored in a server and not able to display them in the frontend.
My project is:
React + Redux using Docker
The React app is full, i.e., there's an API folder for the backend (react/redux), a CLIENT folder for the frontend (react/libraries) and MongoDB as DB.
Docker Compose creates these 3 parts, API, CLIENT and MONGO in just 1 container.
So, in the frontend, the user is able to select an image as an avatar, and then, this image is sent through the layers and saved in a specific folder (NOT BUILD/PUBLIC etc) inside the API docker image. It's possible to remove/delete and re-select it. Everything's working fine!
The issue is the display of this image in the frontend. The avatar component uses an IMAGE SRC to display it, but I can't find a valid URL to use to be able for the frontend TO SEE that image file saved in the API/server.
Since it's inside a container, I tried all possibilities I could find in Docker documentation... I think the solution relays in the NETWORK docker-compose option, but even though couldn't make it.
Docker Compose File:
version: '3.8'
services:
client:
build: ./client
stdin_open: true
image: my-client
restart: always
ports:
- "3000:3000"
volumes:
- ./client:/client
- /client/node_modules
depends_on:
- api
networks:
mynetwork:
ipv4_address: 172.19.0.9
api:
build: ./api
image: my-api
restart: always
ports:
- "3003:3003"
volumes:
- ./api:/api
- logs:/api/logs
- /api/node_modules
depends_on:
- mongo
networks:
mynetwork:
ipv4_address: 172.19.0.10
mongo:
image: mongo
restart: always
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
networks:
- mynetwork
volumes:
mongo_data:
logs:
networks:
mynetwork:
driver: bridge
ipam:
config:
- subnet: "172.19.0.0/24"
To summarize, there's a folder in the API side with images/files and I want to reference them as in
<img src="mynetwork:3003/imagefolder/imagefile.png"> or something like that...
I can't believe I have to use this other solution...Another Stackoverflow Reply

Docker angular instance can't get data from Docker express instance

Through Docker compose I build up a set of images. Among them, there's a node.js/express server and an angularjs 2.0 frontend.
Here's the docker-compose file:
version: "3.3"
services:
angular:
image: micheleminno/angular-client:latest
build: ./angular-client
ports:
- "4200:4200"
express:
image: micheleminno/express-server:latest
build: ./express-server
depends_on:
- mysql
- elasticsearch
ports:
- "3000:3000"
networks:
- sql
- nosql
elasticsearch:
build: elasticsearch/
ports:
- "9200:9200"
- "9300:9300"
networks:
- nosql
environment:
- MAX_OPEN_FILES=1048576
cap_add:
- IPC_LOCK
ulimits:
memlock:
soft: -1
hard: -1
command: echo "Elasticsearch disabled"
kibana:
build: kibana/
volumes:
- ./kibana/config/:/usr/share/kibana/config
ports:
- "5601:5601"
networks:
- nosql
depends_on:
- elasticsearch
command: echo "Kibana disabled"
mysql:
image: mysql:5.5
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=real-affinities
- MYSQL_USER=production
- MYSQL_PASSWORD=production
ports:
- "3306:3306"
networks:
- sql
migrations:
image: micheleminno/db-migrations:latest
environment:
- NODE_ENV=production
depends_on:
- mysql
networks:
- sql
networks:
nosql:
driver: bridge
sql:
driver: bridge
When everything starts, loading page http://localhost:4200/ triggers the following GET request to the express server:
https://localhost:3000/target
but the request doesn't succeed:
Whereas if I do by myself the GET request, I can get results correctly:
Update
Here's my CORS section in server.js:
const cors = require('cors');
const app = express();
app.use(cors());
You have to enable CORS in your Express Server. The CORS spec requires the OPTIONS call to precede the POST or GET if the POST or GET has any non-simple content or headers in it.
As you can see in your error pic, the target is a xhr OPTIONS request. See also the "Preflighted requests" section in the link above.
One possible and simple solution is to use the node.js package cors.
I changed https://localhost:3000 to http://localhost:3000 as url for the http requests from angular client and now it works.

Resources