Reputation: 940
I have tried reading through the other stackoverflow questions here but I am either missing something or none of them are working for me.
I have two docker containers setup on a DigitalOcean server running Ubuntu.
root_frontend_1 running on ports 0.0.0.0:3000->3000/tcp
root_nginxcustom_1 running on ports 0.0.0.0:80->80/tcp
If I connect to http://127.0.0.1
, I get the default Nginx index.html
homepage. If I http://127.0.0.1:3000
I am getting my react app.
What I am trying to accomplish is to get my react app when I visit http://127.0.0.1
. Following the documentation and suggestions here on StackOverflow, I have the following:
docker-compose.yml
in root of my DigitalOcean server.
version: "3"
services:
nginxcustom:
image: nginx
hostname: nginxcustom
ports:
- "80:80"
volumes:
- ./nginx.conf:/root/nginxcustom/conf/custom.conf
tty: true
backend:
build: https://github.com/Twitter-Clone/twitter-clone-api.git
ports:
- "8000:8000"
tty: true
frontend:
build: https://github.com/dougmellon/react-api.git
ports:
- "3000:3000"
stdin_open: true
tty: true
nginxcustom/conf/custom.conf
:
server {
listen 80;
server_name http://127.0.0.1;
location / {
proxy_pass http://root_frontend_1:3000; # this one here
proxy_redirect off;
}
}
When I run docker-compose up
, it builds but when I visit the ip of my server, it's still showing the default nginx html file.
What am I doing wrong here and how can I get it so the main URL points to my react container?
Thank you for your time, and if there is anything I can add for clarity, please don't hesitate to ask.
Upvotes: 1
Views: 1082
Reputation: 4150
The nginx
service should proxy_pass
to the service name (customnginx
), not the container name (root_frontend_1
) and the nginx
config should be mounted to the correct location inside the container.
Tip: the container name can be set in the docker-compose.yml
for services setting the container_name
however beware you can not --scale
services with a fixed container_name
.
Tip: the container name (root_frontend_1
) is generated using the compose project name which defaults to using the current directory name if not set.
Tip: the nginx
images are packaged with a default /etc/nginx/nginx.conf
that will include the default server config from /etc/nginx/conf.d/default.conf
. You can docker cp
the default configuration files out of a container if you'd like to inspect them or use them as a base for your own configuration:
docker create --name nginx nginx
docker cp nginx:/etc/nginx/conf.d/default.conf default.conf
docker cp nginx:/etc/nginx/nginx.conf nginx.conf
docker container rm nginx
With nginx
proxying connections for the frontend
service we don't need to bind the hosts port to the container, the services ports
definition can be replaced with an expose
definition to prevent direct connections to http://159.89.135.61:3000 (depending on the backend
you might want prevent direct connections as well):
version: "3"
services:
...
frontend:
build: https://github.com/dougmellon/react-api.git
expose:
- "3000"
stdin_open: true
tty: true
Taking it a step further we can configure an upstream
for the
frontend
service then configure the proxy_pass
for the upstream
:
upstream frontend {
server frontend:3000 max_fails=3;
}
server {
listen 80;
server_name http://159.89.135.61;
location / {
proxy_pass http://frontend/;
}
}
... then bind-mount the custom default.conf
on top of the default.conf
inside the container:
version: "3"
services:
nginxcustom:
image: nginx
hostname: nginxcustom
ports:
- "80:80"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
tty: true
... and finally --scale
our frontend
service (bounce the services removing the containers to make sure changes to the config take effect):
docker-compose stop nginxcustom \
&& docker-compose rm -f \
&& docker-compose up -d --scale frontend=3
docker
will resolve the service name to the IP's of the 3 frontend
containers which nginx
will proxy the connections for in a (by default) round robin manner.
Tip: you can not --scale
a service that has ports
mappings, only a single container can bind to the port.
Tip: if you've updated the config and can connect to your load balanced service then you're all set to create a DNS record to resolve a hostname to your public IP address then update your default.conf
's server_name
.
Tip: for security I maintain specs for building a nginx
docker image
with Modsecurity and Modsecurity-nginx pre-baked with the OWASP Core Rule Set.
Upvotes: 2
Reputation: 3672
In Docker when multiple services needs to communicate with each other, you can use the service name in the url (set in the docker-composer.yml instead of the ip (which is attributed from the available pool of the network, default by default), it will automatically be resolve to the right container ip due to network management by docker.
For you it would be http://frontend:3000
Upvotes: 0