Saturday, December 28, 2024
Google search engine
HomeGuest BlogsRunning Nginx in Docker Container using BunkerWeb

Running Nginx in Docker Container using BunkerWeb

Getting started with Docker and Docker networking can present some challenges. One of the initial hurdles is understanding the concepts of container networking, which operates differently from traditional networking. You need to familiarize yourself with concepts like bridges, overlays, network modes, and DNS resolution within Docker. This understanding is crucial to grasp how containers communicate with each other and with the host system.

Another challenge lies in choosing the appropriate networking option. Docker offers various networking options such as bridge networks, host networking, overlay networks, and macvlan networks. Selecting the right option for a specific use case can be challenging, particularly for beginners who are not yet acquainted with the characteristics and implications of each option.

Configuring networking for containers is another area that can pose difficulties. It involves creating and managing Docker networks, assigning IP addresses, defining ports, and linking containers together. Users may struggle with setting up networking configurations correctly, especially when dealing with complex multi-container setups or external connectivity requirements.

BunkerWeb is a web server that is built on the NGINX server software and is specifically focused on enhancing security. Familiar to many, NGINX is a web server and reverse proxy server with a reputation for high performance, scalability, and flexibility. It is commonly used to serve web content, handle load balancing, and act as a reverse proxy to distribute incoming requests to backend servers. By building BunkerWeb on top of NGINX, it likely leverages NGINX’s robust features and capabilities while adding security enhancements and focusing on secure web server configurations.

BunkerWeb provides several features, among them are:

  • Easy Integration into Existing Environments: BunkerWeb seamlessly integrates with Linux, Docker, Swarm, and Kubernetes, making it simple to incorporate into your existing infrastructure and workflow.
  • Highly Customizable: With BunkerWeb, you have the flexibility to customize and fine-tune its features to meet your specific use case. You can easily enable, disable, and configure different functionalities according to your requirements.
  • Secure by Default: BunkerWeb prioritizes security by providing out-of-the-box and hassle-free minimal security measures for your web services. It is designed to ensure your applications and data are protected without requiring extensive configuration efforts.
  • Free as in “Freedom”: BunkerWeb is licensed under the free AGPLv3 license, offering you the freedom to use, modify, and distribute the software. This license promotes openness and community collaboration.
  • Security features such as:
    • HTTPS Support with Let’s Encrypt Automation: BunkerWeb seamlessly integrates with Let’s Encrypt to automate the process of obtaining and renewing SSL/TLS certificates, ensuring secure communication with HTTPS.
    • State-of-the-Art Web Security Measures: BunkerWeb implements various advanced web security measures, including HTTP security headers to enhance protection, prevention of information leaks, and robust TLS hardening configurations.
    • Integrated ModSecurity WAF with OWASP Core Rule Set: BunkerWeb includes an integrated ModSecurity Web Application Firewall (WAF) that leverages the OWASP Core Rule Set, providing an additional layer of defence against web-based attacks and vulnerabilities.
    • Automatic Behavior-Based Ban: BunkerWeb monitors and detects unusual behaviour from clients and automatically blocks them based on HTTP status codes, helping prevent malicious activities.
    • Connections and Requests Limit: BunkerWeb allows you to set limits on client connections and requests, helping to mitigate potential abuse or resource exhaustion.
    • Bot Blocking with Challenge Response: BunkerWeb offers the ability to block bots by presenting them with challenges to solve, such as cookies, JavaScript execution, captchas, hCaptcha, or reCAPTCHA, effectively filtering out automated malicious activities.
    • Blacklisting Known Bad IPs with External Blacklists and DNSBL: BunkerWeb enables the use of external blacklists and DNS-based blackhole lists (DNSBL) to automatically block connections from known malicious IP addresses.

Now let’s learn how to run Nginx Web Server in Docker Container using BunkerWeb.

#1. Install Docker and Docker Compose

This guide requires you to have Docker Engine and Docker Compose installed. To install Docker, follow the below guide:

After the installation, ensure that docker has been started and enabled:

sudo systemctl enable --now docker

You also need to add your system user to the docker group:

sudo usermod -aG docker $USER
newgrp docker

Verify the docker installation.

$ docker version
Client: Docker Engine - Community
 Version:           23.0.6
 API version:       1.42
 Go version:        go1.19.9
 Git commit:        ef23cbc
 Built:             Fri May  5 21:18:22 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          23.0.6
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.9
  Git commit:       9dbdbd4
  Built:            Fri May  5 21:18:22 2023
  OS/Arch:          linux/amd64
......

You can also install docker-compose using the guide:

Once installed, verify with the command:

$ docker-compose version
Docker Compose version v2.18.0

#2. Provision BunkerWeb Container

When dealing with BunkerWeb, there are several concepts we need to be aware of. These concepts include:

  • Integrations

The primary focus is on seamlessly integrating BunkerWeb into the target environment. The term “integration” is preferred over “installation” since BunkerWeb aims to harmoniously become a part of existing environments. The supported integrations are Docker, Docker autoconf, Swarm, Kubernetes, Linux and Ansible.

  • Settings

Once BunkerWeb is seamlessly integrated into your environment, the next step involves configuring it to effectively serve and safeguard your web applications.

Configuration of BunkerWeb revolves around the utilization of “settings” or “variables.” Each setting is associated with a specific name, such as AUTO_LETS_ENCRYPT or USE_ANTIBOT, for instance. By assigning values to these settings, you can tailor BunkerWeb to meet your specific configuration requirements.

  • Multisite mode

When utilizing BunkerWeb, understanding the concept of multisite mode becomes essential. The primary objective of safeguarding web applications naturally incorporates the notion of “virtual host” or “vhost” (further information available here). This concept enables the seamless hosting of multiple web applications from a single instance or a cluster. By employing multisite mode, BunkerWeb empowers you to efficiently serve and protect multiple web applications simultaneously.

When running BunkerWeb in docker containers, we observe the below architecture:

BunkerWeb docker

The utilization and configuration of the BunkerWeb container revolve around the following components:

  • Environment Variables: BunkerWeb allows you to configure and customize its behaviour using environment variables. These variables provide a flexible way to adapt BunkerWeb to your specific use cases and requirements.
  • Volume: BunkerWeb utilizes volumes to cache critical data and facilitate the mounting of custom configuration files. This enables you to persist important information and easily incorporate your own tailored configuration files into the BunkerWeb container.
  • Networks: BunkerWeb employs networks to expose ports, allowing clients to access the web services served by BunkerWeb. Additionally, networks enable seamless connectivity to upstream web services, ensuring smooth communication between BunkerWeb and other components of your environment.

Now we will begin by creating a network for BunkerWeb:

docker network create bw-net

We also need to create a volume for BunkerWeb. Begin by creating a path on your host:

sudo mkdir  /bw-datastore
sudo chmod 775 -R  /bw-datastore
sudo chown -R $USER:docker  /bw-datastore

For Rhel-based systems, configure SELinux as shown:

sudo chcon -R -t svirt_sandbox_file_t /bw-datastore

Now create a docker volume:

docker volume create --driver local \
     --opt type=none \
     --opt device= /bw-datastore \
     --opt o=bind bw-data

View the volume;

$ docker volume ls
DRIVER    VOLUME NAME
local     bw-data

#3. Run BunkerWeb Docker Container

Now to run and verify that BunkerWeb is working perfectly, we need to deploy and application for the test. For this demo, we can use a sample app then create reverse proxy using Bunkerweb.

Now we will proceed and run the BunkerWeb Docker container. This can be done in two ways:

  • Uisng Docker CLI
  • Using Docker Compose

Option 1: Run BunkerWeb Using Docker CLI

Begin by spinning the demon app with the command:

docker run -d \
       --name myapp \
       --network bw-net \
       nginxdemos/hello:plain-text

Then spin the BunkerWeb container with the command bearing the below syntax:

docker run -d \
       --name mybunker \
       --network bw-net \
       -p 80:8080 \
       -p 443:8443 \
       -v bw-data:/data \
       -e SERVER_NAME=web.geeksforgeeks.org \
       -e USE_REVERSE_PROXY=yes \
       -e REVERSE_PROXY_URL=/ \
       -e REVERSE_PROXY_HOST=http://myapp \
       bunkerity/bunkerweb:1.4.8

In the above command, we have set reverse proxy for the app we deployed earlier on the URL http://myapp.

View if the containers are running:

$ docker ps
CONTAINER ID   IMAGE                         COMMAND                  CREATED         STATUS                            PORTS                                                                                    NAMES
1a4dbded0a42   bunkerity/bunkerweb:1.4.8     "/opt/bunkerweb/help…"   3 seconds ago   Up 2 seconds (health: starting)   80/tcp, 0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp   mybunker
b669d3fa1eb4   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   4 minutes ago   Up 4 minutes                      80/tcp                                                                                   myapp

Option 2: Run BunkerWeb Using Docker Compose

It is also possible to run the BunkerWeb and the test app containers using a single Docker Compose file. First, create the file:

vim docker-compose.yml

In the file, add the lines below, replacing where required:

version: '3'

services:
  mybunker:
    container_name: mybunker
    image: bunkerity/bunkerweb:1.4.8
    ports:
      - 80:8080
      - 443:8443
    volumes:
      - bw-data:/data
    environment:
      - SERVER_NAME=web.geeksforgeeks.org
      - USE_REVERSE_PROXY=yes
      - REVERSE_PROXY_URL=/
      - REVERSE_PROXY_HOST=http://myapp
    networks:
      - bw-net

  myapp:
    container_name: myapp
    image: nginxdemos/hello:plain-text
    networks:
      - bw-net

volumes:
  bw-data:

networks:
  bw-net:
    name: bw-net

Save the file and run the containers with the command:

docker-compose up -d

View if the containers are running:

$ docker-compose ps
NAME                IMAGE                         COMMAND                  SERVICE             CREATED             STATUS                    PORTS
thor-myapp-1        nginxdemos/hello:plain-text   "/docker-entrypoint.…"   myapp               22 seconds ago      Up 21 seconds             80/tcp
thor-mybunker-1     bunkerity/bunkerweb:1.4.8     "/opt/bunkerweb/help…"   mybunker            22 seconds ago      Up 21 seconds (healthy)   80/tcp, 0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp

Test Access to Appication

If the containers are running, we can test if BunkerWeb is handling the requests as desired. We can use cURL as shown:

curl web.geeksforgeeks.org

Sample Output:

Nginx Web Server in Docker Container using BunkerWeb 1

You can also load the page on your browser using the URL //web.geeksforgeeks.org

Nginx Web Server in Docker Container using BunkerWeb

#4. Run BunkerWeb Containers With Multiple Applications

There are scenarios where you have several applications that need a reverse proxy. BunkerWeb is capable of handling the traffic and proxy the requests as required.

  • For Docker CLI

Begin by spinning the apps:

##APP1
docker run -d \
       --name myapp1 \
       --network bw-net \
       nginxdemos/hello:plain-text

##APP2
docker run -d \
       --name myapp2 \
       --network bw-net \
       nginxdemos/hello:plain-text

##APP3
docker run -d \
       --name myapp3 \
       --network bw-net \
       nginxdemos/hello:plain-text

Proceed and spin BunkerWeb:

docker run -d \
       --name mybunker \
       --network bw-net \
       -p 80:8080 \
       -p 443:8443 \
       -v bw-data:/data \
       -e MULTISITE=yes \
       -e "SERVER_NAME=myapp1.geeksforgeeks.org myapp2.geeksforgeeks.org myapp3.geeksforgeeks.org" \
       -e USE_REVERSE_PROXY=yes \
       -e REVERSE_PROXY_URL=/ \
       -e myapp1.geeksforgeeks.org_REVERSE_PROXY_HOST=http://myapp1 \
       -e myapp2.geeksforgeeks.org_REVERSE_PROXY_HOST=http://myapp2 \
       -e myapp3.geeksforgeeks.org_REVERSE_PROXY_HOST=http://myapp3 \
       bunkerity/bunkerweb:1.4.8

View if the containers are running:

$ docker ps
CONTAINER ID   IMAGE                         COMMAND                  CREATED          STATUS                            PORTS                                                                                    NAMES
56cb582c7d5e   bunkerity/bunkerweb:1.4.8     "/opt/bunkerweb/help…"   5 seconds ago    Up 4 seconds (health: starting)   80/tcp, 0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp   mybunker
42d995f8acb6   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   20 seconds ago   Up 19 seconds                     80/tcp                                                                                   myapp3
6ab7df943bf2   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   24 seconds ago   Up 23 seconds                     80/tcp                                                                                   myapp2
4e84d030f8c9   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   28 seconds ago   Up 27 seconds                     80/tcp                                                                                   myapp1
  • Using Docker Compose

You can spin all your apps and BunkerWeb with a single file:

vim docker-compose.yml

Add the lines below to it:

version: '3'

services:
  mybunker:
    container_name: mybunker
    image: bunkerity/bunkerweb:1.4.8
    ports:
      - 80:8080
      - 443:8443
    volumes:
      - bw-data:/data
    environment:
      - MULTISITE=yes
      - SERVER_NAME=myapp1.geeksforgeeks.org myapp2.geeksforgeeks.org myapp3.geeksforgeeks.org
      - USE_REVERSE_PROXY=yes
      - REVERSE_PROXY_URL=/
      - myapp1.geeksforgeeks.org_REVERSE_PROXY_HOST=http://myapp1
      - myapp2.geeksforgeeks.org_REVERSE_PROXY_HOST=http://myapp2
      - myapp3.geeksforgeeks.org_REVERSE_PROXY_HOST=http://myapp3
    networks:
      - bw-net

  myapp1:
    container_name: myapp1
    image: nginxdemos/hello:plain-text
    networks:
      - bw-net

  myapp2:
    container_name: myapp2
    image: nginxdemos/hello:plain-text
    networks:
      - bw-net

  myapp3:
    container_name: myapp3
    image: nginxdemos/hello:plain-text
    networks:
      - bw-net

volumes:
  bw-data:

networks:
  bw-net:
    name: bw-net

Run the containers:

docker-compose up -d

View if the containers are up:

$ docker ps
CONTAINER ID   IMAGE                         COMMAND                  CREATED          STATUS                    PORTS                                                                                    NAMES
385de3ddfa7b   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   21 seconds ago   Up 19 seconds             80/tcp                                                                                   myapp1
0e3f8980f23b   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   21 seconds ago   Up 19 seconds             80/tcp                                                                                   myapp3
25dd1f4be099   nginxdemos/hello:plain-text   "/docker-entrypoint.…"   21 seconds ago   Up 19 seconds             80/tcp                                                                                   myapp2
4c3fdf996b05   bunkerity/bunkerweb:1.4.8     "/opt/bunkerweb/help…"   21 seconds ago   Up 19 seconds (healthy)   80/tcp, 0.0.0.0:80->8080/tcp, :::80->8080/tcp, 0.0.0.0:443->8443/tcp, :::443->8443/tcp   mybunker

Test Access to the Applications

To test if you are able to access the sites, first, modify your /etc/hosts file:

$ sudo vim /etc.hosts
192.168.200.51 myapp1.geeksforgeeks.org myapp2.geeksforgeeks.org myapp3.geeksforgeeks.org

Now you can use cURL as shown below to verify if BunkerWeb is working:

curl myapp1.geeksforgeeks.org 
curl myapp2.geeksforgeeks.org 
curl myapp3.geeksforgeeks.org

Sample Output:

Nginx Web Server in Docker Container using BunkerWeb 2

You can also use a web browser with the required URL for example:

APP1:

Nginx Web Server in Docker Container using BunkerWeb 3

APP2

Nginx Web Server in Docker Container using BunkerWeb 4

APP3

Nginx Web Server in Docker Container using BunkerWeb 5

#5. Configure HTTPS on BunkerWeb

It is also important to secure traffic using HTTPS. BunkerWeb allows you to use Let’s Encrypt, Custom certificate and Self-signed certs when protecting your traffic.

To enable HTTPS, you can use the below environment variables:

Setting Default Description
REDIRECT_HTTP_TO_HTTPS no If set to yes, will redirect every HTTP request to HTTPS even if BunkerWeb is not configured with HTTPS.
AUTO_REDIRECT_HTTP_TO_HTTPS yes If set to yes, will redirect every HTTP request to HTTPS only if BunkerWeb is configured with HTTPS.
HTTPS_PROTOCOLS TLSv1.2 TLSv1.3 This is the list of supported SSL/TLS protocols when HTTPS is enabled.
HTTP2 yes If set to yes, will enable HTTP2 protocol support when using HTTPS.
LISTEN_HTTP yes If set to no, BunkerWeb will not listen for HTTP requests. Useful if you want HTTPS only for example.

To use a desired certificate, you need to declare it in your configuration as an environment variable. This can be done as shown:

  • Let’s Encrypt

BunkerWeb has an automatic Let’s Encrypt certificate generation and renewal. It makes it so easy to get HTTPS working out of the box for public-facing web applications. For this to work, you need to have an FQDN. Below is a list of the environment variables involved:

Setting Default Description
AUTO_LETS_ENCRYPT no if set to yes, HTTPS will be enabled with automatic certificate generation and renewal from Let’s Encrypt.
EMAIL_LETS_ENCRYPT contact@{FIRST_SERVER} This is the email address to be used when generating certificates. Let’s Encrypt will send notifications to that email such as certificate expiration.
USE_LETS_ENCRYPT_STAGING no If set to yes, the staging server of Let’s Encrypt will be used instead of the production one. Useful when doing development tests to avoid being “blocked” due to limits.

  • Custom certificate

This option applies to those who want to use their own certificates. The environment variables used here are:

Setting Default Description
USE_CUSTOM_HTTPS no If set to yes, HTTPS will be enabled with custom certificates. BunkerWeb will also check every day if the custom certificate specified in CUSTOM_HTTPS_CERT is modified and reload NGINX for that case.
CUSTOM_HTTPS_CERT The full path to the certificate. If you have one or more intermediate certificate(s) in your chain of trust, you will need to provide the bundle (more info here).
CUSTOM_HTTPS_KEY The full path to the private key.
  • Self-signed

If you do not have a Fully Qualified Domain name, you can still protect your traffic on BunkerWeb. The related settings are:

Setting Default Description
GENERATE_SELF_SIGNED_SSL no If set to yes, HTTPS will be enabled with automatic self-signed certificate generation and renewal from Let’s Encrypt.
SELF_SIGNED_SSL_EXPIRY 365 This is the number of days for the certificate expiration (-days value used with openssl).
SELF_SIGNED_SSL_SUBJ /CN=myapp.geeksforgeeks.org/ This is the certificate subject to use (-subj value used with openssl).

To test if this works, we can modify our docker-compose file and add the lines in the environment section for BunkerWeb:

$ vim docker-compose.yml
version: '3'

services:
  mybunker:
    container_name: mybunker
    image: bunkerity/bunkerweb:1.4.8
    ports:
      - 80:8080
      - 443:8443
    volumes:
      - bw-data:/data
    environment:
      - SERVER_NAME=web.geeksforgeeks.org
      - USE_REVERSE_PROXY=yes
      - REVERSE_PROXY_URL=/
      - REVERSE_PROXY_HOST=http://myapp
      - AUTO_REDIRECT_HTTP_TO_HTTPS=yes
      - GENERATE_SELF_SIGNED_SSL=yes
      - SELF_SIGNED_SSL_EXPIRY=365
      - SELF_SIGNED_SSL_SUBJ=/CN=web.geeksforgeeks.org/
........

Apply the changes:

docker-compose up -d

Now verify if you are able to access the app using HTTPS:

Nginx Web Server in Docker Container using BunkerWeb 6

Conclusion

That marks the end of this detailed guide on how to run Nginx Web Server in Docker Container using BunkerWeb. This will help solve the networking complexity involved when dealing with complex multi-container setups or external connectivity requirements. I hope this was informative.

See more:

RELATED ARTICLES

Most Popular

Recent Comments