All the problems originated from using Docker Compose to start the npm container. I found that the tutorials I found online could be accessed through the docker0 gateway, but the containers orchestrated by Docker Compose are not in the same subnet, making it impossible to access the docker0 gateway. This is due to my lack of knowledge and experience in practice.
Host and Bridge Modes in Docker Networking#
To use Docker, it is necessary to have an understanding of the two basic networking modes in Docker, so that you know how to troubleshoot when errors occur.
Host Mode#
In host mode, if the host
mode is used in Docker, the container behaves like an application running directly on the host machine. It does not require port mapping configuration because it is an application under the host machine, and it uses the ports directly on the host machine. The advantage of this mode is that whether it is accessing the container from the host machine, accessing the host machine from the container, or accessing one container from another, it can be done directly through localhost:port
or 127.0.0.1:port
. In simple terms, the host
mode can be considered to have no concept of container networking, and because direct access does not require traffic forwarding, it is the fastest way in terms of networking. The disadvantage is also very obvious, that is, there is no isolation between the host machine and the container network, so attention should be paid to port conflicts and other issues related to port usage. Isn't the purpose of Docker to have container applications without network isolation?
Bridge Mode#
In NAT mode, if the network mode is not specified when creating a Docker container, the default mode is bridge
mode, which automatically creates a network named appname_default
. The advantage of this mode is that the host machine and the container network are isolated, and they can access each other through the docker0
gateway. Because NAT
is used, different container applications can have freely configured networks, such as some applications in one subnet and others in another subnet. The disadvantage is that NAT
requires traffic forwarding, so the network performance is slightly worse. Access from the host machine to the container and from one container to another is relatively simple, but accessing the host machine from the container is more complicated.
There is no absolute advantage or disadvantage between the two modes, it depends on the specific use case.
Two Network Mode Configurations for NPM#
If you are running containers using the docker
command line, you can directly use the docker0
gateway, such as 172.17.0.1:port
, to access other containers.
If you are starting containers using a Docker Compose configuration file, I believe you will encounter the same network issue as me, which is that you cannot access other containers using 172.13.0.1:port
, and you cannot access the host machine either. This is fatal for npm because it renders npm meaningless.
host
Mode in Docker Compose#
Using the host
mode is the simplest way to configure npm. If you are running a small number of containers and there are no port conflicts, and you don't need to pay much attention to the details, then this mode is the best. All you need to do is add the line network_mode: "host"
to the container application in each docker-compose.yml
file. This way, you can directly fill in localhost
or 127.0.0.1
in the hostname/IP
field in the npm configuration to access other containers and host machine applications.
bridge
Mode in Docker Compose#
There are two ways to communicate in the bridge
mode:
- Building an internal network using Docker command line
The advantage is that you don't need to modify the configuration file, but the disadvantage is that you need to add the network of each container to the subnet every time you stop the container.- Create a network:
$ docker network create npm
- Add other containers to the network:
$ docker network connect npm <container_name>
- Check which containers and IP addresses are in the
npm
network:$ docker network inspect npm
- You can access containers using their names. For example, if there is a container named
alist
in the network, you can access it from thenpm
container usingping alist
. Thehostname/IP
field in npm can also use the container names.
- Create a network:
- Configuring the network in
docker-compose.yml
For example, thedocker-compose.yml
fornpm
:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
networks:
- npm
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
npm:
driver: bridge
The docker-compose.yml
for alist
:
version: '3.3'
services:
alist:
restart: always
volumes:
- '.data/alist:/opt/alist/data'
networks:
- npm
ports:
- '5244:5244'
environment:
- PUID=0
- PGID=0
- UMASK=022
container_name: alist
image: 'xhofe/alist-aria2:latest'
networks:
npm:
driver: bridge
If the npm
network has already been created using other commands, it can be linked externally:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
networks:
- npm
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
npm:
external: true
link
Mode in Docker Compose#
I haven't used it much, so please refer to the official documentation.
Enjoy!#
Docker is great, as long as you know how to play with it.
Reference: [Docker Networking Official Documentation](Networking in Compose | Docker Docs)