Mobile
Streaming Platform Products
Virtual & Dedicated Servers Products
Containers Products
Serverless Computing Products
AI & Machine Learning Products
Private and Hybrid Solutions Products
Monitoring Products
Custom Services Products
Media & Entertainment
Financial Services
IT / Technology
Retail
Education
Website Acceleration
Video Streaming
Security & Protection
Cloud
Partnership Solutions
Corporate Solutions
While developing a web application, a common method of calling the application from a local machine is through http://localhost:x
ports, which essentially means that we are required to expose several ports to access different modules of the application. In the article below, we will go through the method of using Reverse Proxy to call an application and the benefits of using it.
The most prominent reason of using Reverse Proxy is to avoid changing ports everytime you try to access different modules of the application through the same URL. Through Reverse Proxy we can reach Frontend, Backend or other services without changing port through a single domain. Other important reasons of using Reverse Proxy is to mask services behind a proxy and avoid dealing with CORS issues.
# Without Reverse Proxy # Domain Name: http://mydomain.com # Mysql wordpress: http://mydomain.com:10088 # Angular app: http://mydomain.com:7787 # Backend: https://mydomain:9876
# With Reverse Proxy # Domain Name: http://mydomain.com # Mysql wordpress: http://mydomain.com/db # Angular app: http://mydomain.com/ang # Backend: https://mydomain/wp
For the reference of this article, let us create a WordPress-MySQL server with Nginx in one service. Start by creating the docker container, along with defining ports, base image, container name and service names.
version: '2' services: whilefly_wp: container_name: production_wp image: nginx:latest volumes: - "/home/xx/Desktop/cust/xx/html:/var/www/html" - "/home/xx/Desktop/cust/xx/Docker/logs:/logs" - "/home/xx/Desktop/cust/xx/Docker/database:/docker-entrypoint-initdb.d" - "xx_db_data:/var/lib/mysql" user: root restart: always ports: - "8081:80" environment: MYSQL_ROOT_PASSWORD: 'xxxxx' MYSQL_DATABASE: 'production_db' MYSQL_USER: 'production_admin' MYSQL_PASSWORD: 'xxxxxx' nginx: image: nginx:latest container_name: production_nginx volumes: - /home/xx/Desktop/cust/xx/Docker/nginx/reverse_proxy.conf:/etc/nginx/conf.d/default.conf - /home/xx/Desktop/cust/xx/Docker/nginx/cert/star_xx_com.pem:/etc/nginx/cert/star_xx_com.pem - /home/xx/Desktop/cust/xx/Docker/nginx/cert/star_xx_com.key:/etc/nginx/cert/star_xx_com.key - /home/xx/Desktop/cust/xx/Docker/nginx/cert/star_xx_com.crt:/etc/nginx/cert/star_xx_com.crt ports: - 8080:8080 - 443:443 links: - whilefly_wp volumes: xx_db_data:
Let’s explain the setup in steps.
services
command defines the service you will build in Docker.version: '2' services: running_wp: nginx:
running_wp
service uses nginx:latest
as the base image. You can also use your own custom image for MySQL and WordPress. Next is to assign a container name, for instance currently production_wp
is used below. Copy the local files under volume section to the given directory while building this docker image. It is important to assign Ports which are to be used for accessibility within or outside of the application. As shown below, we have mapped 8081
host to 80
port for container.version: '2' services: running_wp: container_name: production_wp image: boraozkan/nginx:latest volumes: - "/home/xx/Desktop/cust/xx/html:/var/www/html" - "/home/xx/Desktop/cust/xx/Docker/logs:/logs" - "/home/xx/Desktop/cust/xx/Docker/database:/docker-entrypoint-initdb.d" - "xx_db_data:/var/lib/mysql" user: root restart: always ports: - "8081:80" environment: MYSQL_ROOT_PASSWORD: 'xxxxx' MYSQL_DATABASE: 'production_db' MYSQL_USER: 'production_admin' MYSQL_PASSWORD: 'xxxxxx'
environment
command.environment: MYSQL_ROOT_PASSWORD: 'xxxxx' MYSQL_DATABASE: 'production_db' MYSQL_USER: 'production_admin' MYSQL_PASSWORD: 'xxxxxx'
version: '2' nginx: image: nginx:latest container_name: production_nginx volumes: - /home/xx/Desktop/cust/xx/Docker/nginx/reverse_proxy.conf:/etc/nginx/conf.d/default.conf - /home/xx/Desktop/cust/xx/Docker/nginx/cert/star_xx_com.pem:/etc/nginx/cert/star_xx_com.pem - /home/xx/Desktop/cust/xx/Docker/nginx/cert/star_xx_com.key:/etc/nginx/cert/star_xx_com.key - /home/xx/Desktop/cust/xx/Docker/nginx/cert/star_xx_com.crt:/etc/nginx/cert/star_xx_com.crt ports: - 8080:8080 - 443:443 links: - running_wp volumes: xx_db_data:
conf.d
path – this is the default directory for virtual host descriptions./home/xx/Desktop/cust/xx/Docker/nginx/reverse_proxy.conf:/etc/nginx/conf.d/default.conf
8080
and 443
). Secondly, the forward traffic would be directed to port 8081
– this is the port of production container for reaching.# re-route everything to production_wp server { listen 8080; server_name production_wp; error_page 497 http://$host:80$request_uri; ssl on; ssl_certificate /etc/nginx/cert/star_xx_com.crt; ssl_certificate_key /etc/nginx/cert/star_xx_com.key; location /wp { proxy_pass http://localhost:8081/wp; rewrite /wp(.*) /origin-d$1 proxy_pass http://localhost:8081; proxy_redirect / /wp; sub_filter 'href="/' 'href="/wp' } } # wordpress container via production_wp server { listen 443; server_name production_wp; error_page 497 http://$host:80$request_uri;
ssl on
command.ssl on; ssl_certificate /etc/nginx/cert/star_xx_com.crt; ssl_certificate_key /etc/nginx/cert/star_xx_com.key;
proxy_set_header
directive which helps in redefining or appending fields to the request header passed through the proxied server.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;
location /wp {proxy_pass http://localhost:8081/wp;rewrite /wp(.*) /origin-d$1proxy_pass http://localhost:8081;proxy_redirect / /wp;sub_filter 'href="/' 'href="/wp' }
docker-compose.yaml
while starting containers.docker-compose up -d
#docker-compose up -d Pulling nginx (nginx:latest)... 2.1: Pulling from nginx:latest b8f262c62ec6: Pulling fs layer a98660e7def6: Pulling fs layer 4d75689ceb37: Pulling fs layer 639eb0368afa: Waiting 99e337926e9c: Waiting 431d44b3ce98: Waiting beb665ea0e0e: Pulling fs layer c98a22d85c62: Waiting bf70d116f1d7: Waiting 97f2d71621e0: Waiting ea02a46a87c8: Waiting 78fff17c3a50: Waiting
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9c327bb01a85 nginx:latest "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes 0.0.0.0:8080->8080/tcp, 0.0.0.0:443->443/tcp production_nginx 3823ce1f25d8 boraozkan/nginx:latest "/usr/bin/supervisord" 8 minutes ago Up 8 minutes 3306/tcp, 0.0.0.0:8081->80/tcp production_wp
Once the services are up, try to connect your web application to the localhost link. If it is not answered, check your iptables table for correctness.
By default Docker containers can make connections to the outside world, but the outside world cannot connect to containers. Each outgoing connection will appear to originate from one of the host machine’s own IP addresses thanks to an iptables
masquerading rule on the host machine that the Docker server creates when it starts:
$ sudo iptables -t nat -L -n ... Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
This article is aimed to show how you can use Nginx with docker-compose
easily. It also shows setting of Reverse Proxy configuration on containers. Using this will give you additional flexibility during deployment of a web application.