Understanding Docker Network Configuration: The Impact of Choosing the Right Mode

Introduction: What is Docker?

Docker is a technology that uses “containers” to easily run applications. Containers are designed to package software and its dependencies into a single bundle, ensuring that the application behaves the same in different environments. This means you can run applications without worrying about differences between environments, such as development, testing, or production.

Why Choose Docker?

In this case, due to the low access to the CMS site hosted on a cloud service, I decided to move it to a home server. For this migration, I chose Docker as it simplifies the process of setting up and managing applications.

Reasons for Using Docker

Previously, tasks such as backups and restores were performed manually, but Docker significantly reduces the effort involved. Docker is a technology that isolates the application’s environment into a container, making it easily replicable.

For example, when migrating a Drupal website to a home server, Docker allows you to run it easily in any environment.

Setting Up the Environment

The current environment is built on Ubuntu 24.04. Docker is already installed, and tasks are carried out via SSH from other PCs within the LAN. Next, we’ll proceed with the steps to run Drupal using Docker.

Try the Latest Drupal 11 with Docker

This time, let’s build a website using the latest Drupal 11. Released in August 2024, Drupal 11 is based on the latest PHP 8.3. This version offers more flexible and powerful extensions and is built on Alpine Linux 3.20.

Let’s go through the steps to set up Drupal 11 using Docker.

Step 1: Obtain the Drupal 11 Image

To get the Docker image for Drupal 11, execute the following command. This will download the latest Drupal 11.0.1 version.

docker pull drupal:11

With this command, the latest Drupal image will be downloaded from the official Docker Hub. The image already includes PHP 8.3 and the necessary extensions, so it’s ready to use.

Step 2: Verify the Image

Next, verify that the image has been downloaded correctly.

docker images

If you see drupal:11 listed, the download was successful.

Step 3: Create and Start the Drupal Container

Using the downloaded Drupal image, create and start a container. The following command maps port 80 to allow external access.

docker run \
--name drupal11 \
-p 80:80 \
-d drupal:11

This command specifies the following options:

  • --name drupal11: Assigns the name “drupal11” to the container.
  • -p 80:80: Maps port 80 of the container to port 80 on the host, allowing access to the container from a browser.
  • -d drupal:11: Runs the Drupal 11 image in detached mode, allowing it to run in the background.

Step 4: Confirm the Container is Running

To confirm that the container is running correctly, execute the following command:

docker ps

If “drupal11” appears in the list of running containers, the container is functioning properly.

About the Dockerfile for Drupal 11

The Docker image for Drupal 11 uses the latest PHP 8.3 and is based on Alpine Linux 3.20, making it lightweight and efficient. Additionally, it allows for easy dependency management using Composer. Specifically, the following PHP extensions are installed:

  • gd (for image processing)
  • opcache (for performance optimization)
  • pdo_mysql and pdo_pgsql (for database connections)

The Dockerfile also includes recommended opcache settings to enhance performance, optimizing memory usage and caching.

https://github.com/docker-library/drupal

#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#

# https://www.drupal.org/docs/system-requirements/php-requirements
FROM php:8.3-fpm-alpine3.20

# install the PHP extensions we need
RUN set -eux; \
	\
	apk add --no-cache --virtual .build-deps \
		coreutils \
		freetype-dev \
		libjpeg-turbo-dev \
		libpng-dev \
		libwebp-dev \
		libzip-dev \
# postgresql-dev is needed for https://bugs.alpinelinux.org/issues/3642
		postgresql-dev \
	; \
	\
	docker-php-ext-configure gd \
		--with-freetype \
		--with-jpeg=/usr/include \
		--with-webp \
	; \
	\
	docker-php-ext-install -j "$(nproc)" \
		gd \
		opcache \
		pdo_mysql \
		pdo_pgsql \
		zip \
	; \
	\
	runDeps="$( \
		scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
			| tr ',' '\n' \
			| sort -u \
			| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
	)"; \
	apk add --no-network --virtual .drupal-phpexts-rundeps $runDeps; \
	apk del --no-network .build-deps

# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
		echo 'opcache.memory_consumption=128'; \
		echo 'opcache.interned_strings_buffer=8'; \
		echo 'opcache.max_accelerated_files=4000'; \
		echo 'opcache.revalidate_freq=60'; \
	} > /usr/local/etc/php/conf.d/opcache-recommended.ini

COPY --from=composer:2 /usr/bin/composer /usr/local/bin/

# 2024-08-08: https://www.drupal.org/project/drupal/releases/11.0.1
ENV DRUPAL_VERSION 11.0.1

# https://github.com/docker-library/drupal/pull/259
# https://github.com/moby/buildkit/issues/4503
# https://github.com/composer/composer/issues/11839
# https://github.com/composer/composer/issues/11854
# https://github.com/composer/composer/blob/94fe2945456df51e122a492b8d14ac4b54c1d2ce/src/Composer/Console/Application.php#L217-L218
ENV COMPOSER_ALLOW_SUPERUSER 1

WORKDIR /opt/drupal
RUN set -eux; \
	export COMPOSER_HOME="$(mktemp -d)"; \
	composer create-project --no-interaction "drupal/recommended-project:$DRUPAL_VERSION" ./; \
# https://github.com/docker-library/drupal/pull/266#issuecomment-2273985526
	composer check-platform-reqs; \
	chown -R www-data:www-data web/sites web/modules web/themes; \
	rmdir /var/www/html; \
	ln -sf /opt/drupal/web /var/www/html; \
	# delete composer cache
	rm -rf "$COMPOSER_HOME"

ENV PATH=${PATH}:/opt/drupal/vendor/bin

# vim:set ft=dockerfile:

Step 5: Check the Network

Now that we have confirmed the Drupal container is running correctly, let’s check the network settings. To find out which IP address the container is using, run the following command:

ip a

This command will display the current IP address of your PC. In this case, the IP address identified is 192.168.0.10.

Step 6: Access from Other PCs

Next, use another PC within the LAN to access the Drupal container via a browser. Enter the following URL into the browser’s address bar:

http://192.168.0.10

If the Drupal installation screen appears in the browser, the container is functioning properly.

Database Details Omitted This Time

Normally, Drupal requires a database such as MySQL, but since the primary goal here is to verify the network functionality, the database setup will be omitted in this explanation. The focus is on confirming that the container is running correctly and the network is functioning as expected.

The diagram below illustrates the relationship between the ports assigned to the host and the container.

Explanation of Each Network Mode

Port Assignment between Host and Container

First, the diagram above shows the relationship between the ports assigned to the host and the container.

Diagram Explanation: The host contains multiple containers, each using different ports to communicate with the external environment. For example, even if the port inside the container is 80, it may be mapped to different ports on the host, such as 8080 or 5000. This allows multiple containers to run simultaneously without any port number conflicts.

  • Container 1: 8080:80 (maps port 8080 on the host to port 80 inside the container)
  • Container 2: 5000:80 (maps port 5000 on the host to port 80 inside the container)
  • Container 3: 80:80 (maps port 80 on the host to port 80 inside the container)

This port mapping allows multiple web servers or services to run concurrently on the same host.

Docker Network Modes

Next, let’s explain the network modes in Docker. When Docker is installed, three default networks are automatically created. These are used for different purposes depending on the configuration. You can check the list of networks using the following command:

docker network ls

The displayed networks will look like the following.

NETWORK ID NAME DRIVER SCOPE
4776e45bdad4 bridge bridge local
3557a34a50be host host local
16f8888fed53 none null local

Details of Network Modes

bridge:

Overview: This is Docker’s default network mode. Containers communicate with the host and other containers via a virtual interface called docker0. Any newly created container will use this mode unless specified otherwise.

Features: By setting up port forwarding between the host and the container, external access to the container is made possible. For example, port mapping like 8080:80 maps the host’s port to the container.

host:

Overview: The container directly uses the host’s network. Since the container does not have its own network stack, network overhead is reduced, improving performance.

Features: In this mode, the container shares the same IP address as the host, so port mapping is unnecessary. However, because the host and container fully share the network, this can increase security risks.

none:

Overview: In this mode, no network is assigned to the container. It is suitable for applications that do not require network connections or when using a custom network.

Features: The container cannot communicate with other containers or the outside world, creating a fully isolated environment.

As you can see, each network mode has its specific use cases, and it is important to choose the right one depending on your goals. Next, we will confirm communication between containers and with external systems using these network modes.

What is the Bridge Network?

The bridge network is the default network mode used in Docker. In this mode, containers communicate with the host and other containers using a virtual network called a “bridge.” Specifically, containers communicate over the same network through a virtual interface called docker0.

Role of the Bridge Network

The Bridge network connects multiple containers within a single network, allowing each container to have its own IP address. Within this network, containers can communicate with each other, and when communicating with the host machine or external networks, port forwarding is used for the connection.

For example, consider the following scenario:

Container 1 is running a web server, and Container 2 is running a database.

If both containers are on the same Bridge network, Container 1 can directly connect to Container 2 to access the database.

When accessing from the outside, communication is handled by mapping a specific port on the host machine (e.g., 8080) to the container’s port (e.g., 80).

Operational Image of the Bridge Network

Diagram: The following diagram provides a simple illustration of how the Bridge network operates.

  • Virtual Bridge (docker0): This acts like a virtual switch between containers and the host, enabling communication between containers and between the host and containers.
  • Container IP Address: Each container is assigned a unique internal IP address via docker0, allowing communication within the same network.

Features of the Bridge Network

  • Simple communication between containers: Using the bridge mode, containers can easily communicate with each other by using their IP addresses.
  • Communication with external networks: To allow access to a container from external PCs or networks, you need to map the host’s port to the container’s port. This process is called “port forwarding.”

Example: By specifying 8080:80, accessing port 8080 on the host will connect to port 80 in the container.

In this way, the Bridge network provides a convenient mode that isolates containers while allowing flexible communication within the network. It is especially useful when running multiple containers simultaneously or when you want to control access from the host.

What is the Host Network?

The host mode is a network mode where the container directly uses the network stack of the host PC. In this mode, the container is not assigned its own IP address and instead uses the host’s IP address and ports. As a result, the host and the container share the same network space.

Role of the Host Network

In host mode, since the container directly uses the host’s network resources, there is no network isolation between the container and the host. This means that the container shares the same IP address as the host, leading to the following behavior:

  • The container does not have its own IP address because it uses the host’s IP address directly.
  • Services within the container are accessed using the host PC’s port numbers, so port forwarding is not required for external connections.

Operational Image of the Host Network

Diagram: The following diagram illustrates how the host network operates.

Features of the Host Network

  • No need for port mapping: Since the container directly uses the host’s network ports, there is no need to configure port forwarding. For example, a service running on port 80 on the host is automatically reflected in the container as well.
  • Shares the same network as the host: In host mode, the container shares the same IP address as the host and is not assigned a separate IP address.
  • Improved performance: Since there is no network virtualization, the overhead for communication is reduced, resulting in improved performance. However, as the container shares the same network stack as the host, there may be increased security risks.

When using the host network mode, the container also uses the same IP address as the host. This means that if the host’s IP address is 10.0.0.5, the container will also share this IP address.

Specifically, since the container and the host share the same network namespace, the container is not assigned a new IP address. Therefore, from the perspective of external networks or other devices, the host and the container appear to be using the same IP address (in this case, 10.0.0.5).

Because services inside the container use the host’s ports directly, for example, if a web server is running on port 80 of the host, accessing 10.0.0.5:80 from the outside will connect to the web server inside the container.

In summary, when using host mode:

  • The container shares the host’s IP address (10.0.0.5).
  • Port mapping is not required (the host’s ports are used directly).
  • The container and host are treated as the same entity from a network perspective.

When using host network mode with multiple containers, all containers share the same IP address as the host. This means that if the host’s IP address is 10.0.0.5, even with multiple containers, they will all use the same IP address of 10.0.0.5.

However, caution is needed regarding port conflicts. In host mode, since the container and the host share the same network namespace, the same port cannot be used by multiple containers simultaneously. For example, if Container A is using port 80, an error will occur if Container B tries to use port 80 as well due to a conflict.

When using multiple containers in host mode, you should consider the following:

  • The same port cannot be used by multiple containers: To avoid port conflicts, each container must use different ports.
  • Pay attention to port management: It’s important to carefully manage which ports are being used by each container.

If services are operated on different ports, multiple containers can be run without any issues, even in host mode.

What is the None Network?

As the name suggests, the none network mode creates a state where the container is not assigned any network interface at all. In this mode, the container cannot communicate with external networks, other containers, or even the host.

Role of the None Network

This mode is used when external communication is not necessary, or when network connectivity should be restricted. It is effective, for example, for applications where security is a top priority or for test environments that should be isolated from network influence.

Operational Image of the None Network

In none mode, the container is completely disconnected from external connections. Normally, a container is assigned a virtual network interface, but in none mode, such an interface does not exist.

Features of the None Network

  • Complete disconnection from network communication: The container cannot communicate with the host or other containers.
  • Security: It can be used when you want to completely block external access or for specific testing purposes.
  • Use cases: Ideal for tests that must not be affected by network interactions or for applications that do not require external access, such as data processing tasks.

As you can see, the none mode is used in special situations where network communication is entirely unnecessary. While it is not commonly used for standard applications, it is extremely useful for specific purposes.

Checking the Container’s IP Address

Next, let’s check which IP address the container is using. In this step, you will learn how an IP address is assigned to a container when it is using Bridge mode.

Check the Details of the Bridge Network

To verify the status of the Bridge network that the container is using, enter the following command:

docker network inspect bridge

This command will display information about the containers connected to the Bridge network, including the IP address assigned to each container.

Example output:

"Containers": {
"a1b2c3d4e5f6": {
"Name": "my_container",
"IPv4Address": "172.17.0.2/16"
}
}

As shown, the IPv4 address 172.17.0.2 is assigned. This is the internal IP address of the container.

Verify Communication with the Container (ping command)

Next, to check if this IP address is functioning correctly, use the ping command from the host PC to the container.

ping 172.17.0.2

Example output:

PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.040 ms

This result indicates that communication between the host PC and the container is functioning correctly. The ping command confirms that the host PC and the container can communicate within the same network.

Why Browser Access is Possible

The reason you were able to access the container via a browser earlier is that the communication setup is working correctly. If a web server is configured in the container, you can access it from the host or other PCs using the IP address confirmed by the ping command.

Enter the Container and Check the Network Status

Next, let’s enter the container and check its actual network status. In this example, the container is named “my_drupal,” but when you are using your own container, it is recommended to give it an appropriate name.

Entering the Container

First, use the following command to enter the container:

docker exec -it my_drupal bash

This will allow you to enter the container and execute commands directly.

Check the Network Interface

Once inside the container, you’ll want to check the network interface status using the ip command, but by default, this command is not installed.

Example error message:

bash: ip: command not found

So, first, install the necessary package:

apt-get update
apt-get install iproute2

After installation, you can check the network status with the following command:

ip a

Example output:

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
6: eth0@if7: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever

Here, you can see that the eth0 interface is enabled inside the container, and the IP address 172.17.0.2 is assigned to it.

Verify Communication with the Ping Command

To check whether communication from the container to the outside world is possible, use the ping command. However, by default, the ping command is also not installed, so you will need to install it:

apt-get install iputils-ping

Then, by sending a ping to Google’s DNS server, you can verify the internet connection:

ping 8.8.8.8

Example output:

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=55 time=10.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=55 time=11.1 ms

Stopping and Removing the Container

Finally, once your tasks are complete, stop the container and remove any unnecessary volumes to reset the network state:

docker stop my_drupal
docker system prune
docker volume prune

When the container is stopped, the virtual interface veth is also automatically removed.

Starting a Container in Host Mode

Next, let’s start a Drupal container in host mode. In this mode, the container directly uses the host’s network. As a result, port assignment is unnecessary, and the container shares the same IP address as the host.

Starting the Container in Host Mode

First, use the following command to start the container in host mode. In this example, the container is named “drupal11”:

docker run --name drupal11 --network host -d drupal:11

Key Points:

  • By using the --network host option, the container shares the same network as the host and is not assigned a unique IP address.
  • Therefore, when accessing the container from outside, the host’s IP address and ports are used as is.

Verifying Host Mode

To verify that the container is running in host mode, use the following command:

docker network inspect host

In host mode, the docker network inspect command will not show a specific IP address for the container. This is because the container is using the same network namespace as the host.

Comparison with Bridge Mode

Host mode has the advantage of improved performance because the host and container share the same network completely. However, from a security perspective, if you want to isolate the container from the host, bridge mode is more appropriate.

Reasons to Choose Bridge Mode:

  • In bridge mode, each container is assigned its own IP address, isolating the host and containers.
  • As a result, security is enhanced, and it is easier to manage communication between containers and the host.

Operating the Container and Migrating Data

Once you’ve confirmed that the Drupal container is running in host mode, the next step is to back up the data within the container and transfer it to the host. For example, by backing up the Drupal site’s database and configuration files, you can easily restore the site in other environments.

Summary: Understanding Docker Networks Makes a Difference

Docker is a very powerful tool, but understanding network settings correctly can significantly impact both performance and security. By choosing the right network mode, you can efficiently manage containers, improve performance, and mitigate security risks. Let’s briefly review the three primary network modes Docker provides by default and how they are useful in different scenarios.

  1. Bridge Network: Best for General UseFeatures:
    • This is the default network mode set up when Docker is installed, and it’s typically the first network mode that beginners encounter.
    • Each container is assigned its own internal IP address and communicates via a virtual bridge (docker0).
    Common challenges for beginners:
    • Port forwarding must be configured. If this is forgotten, the container won’t be accessible from the outside.
    When to use it:
    • Ideal for deploying general web applications. It allows communication between the host and containers, as well as between containers, while maintaining moderate isolation.
    • It’s simple for beginners, and with external access properly configured, it can handle most cases.
  2. Host Network: A Performance-Focused ChoiceFeatures:
    • The container uses the host’s network stack directly, eliminating network overhead and improving performance.
    Common challenges for beginners:
    • There is a risk of reduced security. Since the host and container share the same IP address and ports, port conflicts can occur.
    When to use it:
    • Suitable for applications requiring high-speed network processing or in scenarios where performance is the top priority.
    • However, due to the security risks, it should be used cautiously, especially for public-facing servers.
  3. None Network: Complete Network IsolationFeatures:
    • This mode does not provide any network connection. The container cannot communicate with the host or other containers.
    Common challenges for beginners:
    • Its use is limited to cases where external connectivity is not required.
    When to use it:
    • Ideal for environments where security is the highest priority or for containers that perform standalone tasks without using a network.
    • Useful when you need to run a container in complete isolation to prevent network-based attacks.

Leveraging Custom Networks

In Docker, it’s also possible to create custom networks in addition to the default network modes. For example, in a microservices environment where multiple containers need to work together, creating a custom network can optimize communication between services.

The Importance of Understanding Networks

For those just starting with Docker, network settings may feel a bit challenging. However, once you learn to select the right network mode, it can make a significant difference in your application’s performance and security. As you deepen your understanding of networks, you’ll be able to confidently handle more complex configurations.

Go beyond just getting things to work—by mastering Docker networks, you can set yourself apart from other Docker users!