How to setup a simple reverse proxy in docker? - nginx

I am new in docker. I have of applications running on multiple container. Now, I would like to publish all my apps. What I am planning to do is do make a cluster containning all my application. I want at least 4 containers.
Nginx container that is facing internet like a reverse proxy. He is responsible to redirect traffic to other containers, since there are not directly accessible through internet.
Node_js container that publishes a web in nodejs (http://www.node-app.me).
java_EE container that publishes Java EE application (http://www.java_ee-app.me).
Django container that publishes a Django application(http://www.django-app.me).
This is the idear I have, but I don't no how to set nginx container to play the proxy role and make the request to the correct container so that if user send a request like http://www.node-app.me, the container nginx will return result from Node_js, and so on. Can you please give idear on where to start ?
The setup could look like this (sorry I am not very good at drawing) :

Unless you have a specific need for nginx, I suggest you use Træfik to do the reverse proxy. It can be configured to dynamically pick up reverse proxy rules via labels on your containers. Here's a basic example.
First, create a common network for Træfik and your three containers.
docker network create traefik
Run Træfik with port 80 exposed and the docker backend enabled.
docker run --name traefik \
-p 80:80 \
-v /var/run/docker.sock:/var/run/docker.sock \
--network traefik \
traefik:1.2.3-alpine \
--entryPoints='Name:http Address::80' \
--docker \
--docker.watch
Run your three services with the appropriate labels. Make sure they share a common network with Træfik so that Træfik can reach it. The node_js one might look something like this.
docker run --name node_js \
--network traefik \
--label 'traefik.frontend.rule=Host:www.node-app.me' \
--label 'traefik.frontend.entryPoints=http' \
--label 'traefik.port=80' \
--label 'traefik.protocol=http' \
your_node_js_image
Træfik will dynamically create a frontend rule that matches on the Host header for www.node-app.me when it sees this container running. The traefik.port and traefik.protocol labels let Træfik know how to communicate with your container.
See the documentation for Træfik's Docker backend for more options and details.

Related

How to migrate existing domain with ssl certificate from CentOS/Apache to Docker/Nginx?

We have a site running on CentOS/PHP/Apache stack. We want to migrate the whole site to Docker/PHP-FPM/Nginx using docker-compose.
So far we've set up plans for migrating pretty much everything except the domain and the existing ssl certificate .
How do we go about this ?
Nginx is up and running on port 80
ports:
- '9007:80'
How can we redirect the existing domain to the docker container and also use the existing ssl certificate ?
No need for the hassle, someone already did the work for you:
https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion
Its a fully configured auto-ssl docker, which does basically exactly what you need. Start your Website-Container with the following additional parameters (from the git-repo):
docker run -d -e VIRTUAL_HOST=your.domain.com \
-e LETSENCRYPT_HOST=your.domain.com \
-e LETSENCRYPT_EMAIL=your.email#your.domain.com \
--network=webproxy \
--name my_app \
httpd:alpine
I can only recommend it, its a great solution for hosting multiple projects on one server.

Change mapped ip in wordpress docker container

I'm a little bit newbie with Docker. The problem is my server provider changed the public IP recently. When I ran my wordpress container I used the following:
docker run -e WORDPRESS_DB_PASSWORD=xxx --name wordpress-xx --link wordpressdb-xx -p 185.166.xx.xx:8081:80 -v "$PWD/docker/data/wordpress/xx":/var/www/html -d wordpress
How can I change the old IP in order to assign the new one in a container that is already running?
Is it possible to run this containers with localhost IP? For example:
docker run -e WORDPRESS_DB_PASSWORD=xxx --name wordpress-xx --link wordpressdb-xx -p 127.0.0.1:8081:80 -v "$PWD/docker/data/wordpress/xx":/var/www/html -d wordpress
You can also try to save the current container as an image using docker commit and then run the image as a new container with the new IP.
If you have only a single network interface just pass the port only. You can also use the 127.0.0.1 address
See https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p-expose

How to expose ports only within the docker network?

I have a few apps running in a Docker network with their ports (3000,4200, etc) exposed. I also have an nginx container running within the same Docker network which hosts these apps on port 80 with different domain names (site1.com, site2.com).
But right now if I go directly to the ports the apps are running on (localhost:3000) I can access them that way too.
How do I expose those ports only to the nginx container and not the host system?
But right now if I go directly to the ports the apps are running on
(localhost:3000) I can access them that way too.
Thats because you are using -p aka --publish command in your docker run
Explanation:
If you want to expose ports between containers only, Do Not use -p or --publish just put them on the same docker network.
Example:
Lets create a new user-defined network:
sudo docker network create appnet
Lets create nginx container for reverse proxy, It should be available to outside world so we use publish.
sudo docker run --name nginx -d --network appnet nginx
Now put your apps in the same network but do not expose ports.
sudo docker run --name app1 -d --network appnet <app image name/id>
You have to use Docker networks.
The default network is shared with host, thus accessible from localhost. You can either configure Docker, creating a network manually, or let tools like docker-compose or Kubernetes to do it for you.

docker userdefined network - no connection to the outside world

I try to expose a docker container to the outside world (well, to be specific just in my internal network - 10.0.0.0/24) with a static ip adress. In my example the container should have the IP address 10.0.0.200.
Docker version is 1.10.3.
Therefore i created a userdefined network:
docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.254 dn in bridge mode.
Then i created a container and attached it to the container.
docker run -d \
--name testhost \
-it \
-h testhost \
--net dn \
--ip 10.0.0.200 \
-p 8080:8080 \
some image
The container has the correct ip and gw assigned (10.0.0.200, 10.0.0.254 - which is also the ip from the docker created bridge interface) but no communication from the container to the outside world nor from the outside to the container is possible. only thing that works is nslookup but tbh i dont know why this is working.
From another host in the network i can ping the bridge interface which was created through the docker network create command.
A second container connected the the dn network can ping my first container. so communication inside the network seems fine.
As in the docker [network documentation][1]
[1]: https://docs.docker.com/engine/userguide/networking/#a-bridge-network "docker network docu" (second picture in bridge network) it should be possible
It seems that im missing some step or config. Any advice is appreciated, thank you.

NGINX-Proxy: Running multiple ports tied to different virtual hosts on one container

Using Jason Wilder's NGINX-Proxy, is it possible to tie two or more sets of virtual hosts to individual ports on just one container?
What I'm thinking:
# start the reverse proxy
docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy
# start a first container for http://tutum.test.local
docker run -d -e "VIRTUAL_HOST=tutum.test.local" -e "VIRTUAL_HOST=tutum.school.nationwide" -p 80:80 -p 3000:3000 tutum/hello-world
Where the first virtual host could be linked to a socket running on port 3000 in the code, and the second virtual host could be linked to the 8080 port and handle regular API calls.
Is that possible or would I be better served to just break the socket off into a separate docker container?
After further examining the code I realized this is not currently supported. The best method I've found is to break the sockets and API into different containers.

Resources