networking – tsmx https://tsmx.net pragmatic IT Thu, 17 Mar 2022 20:19:03 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 https://tsmx.net/wp-content/uploads/2020/09/cropped-tsmx-klein_transparent-2-32x32.png networking – tsmx https://tsmx.net 32 32 Connecting from a Docker container to a local MongoDB https://tsmx.net/docker-local-mongodb/ Fri, 14 Jan 2022 22:18:03 +0000 https://tsmx.net/?p=1484 Read more]]> A quick guide demonstrating how to connect to a local MongoDB instance from a Docker container.

Docker containers run in an isolated environment including separate virtual networks by default. Although you can run your MongoDB in a container connected to such a virtual network, e.g. by using docker-compose, there may be situations where you want to use a local MongoDB instance and connect to it from a container.

The Docker bridge network

To establish networking connections between the host and containers, a Docker bridge network can be used. A standard one called bridge is always present and generated by default. You can inspect it using the docker network inspect bridge command.

$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "73cb0c87fb64f19c76e3367e80b2da2d104a67603882ca539ce2cf70bdf97c4f",
        "Created": "2022-01-14T20:53:38.577610832+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Notice that this network has a Gateway with the IP 172.17.0.1. This we will use to connect from the container to our MongoDB running on the host.

According to the Docker docs on networking the default bridge network should not be used for production scenarios but is fine for any dev/test environment. In this article we will continue using the default bridge.

Connecting to your local MongoDB from Docker

For connecting to your local MongoDB instance from a Container you must first allow to accept connections from the Docker bridge gateway. To do so, simply add the respective gateway IP in the MongoDB config file /etc/mongod.conf under bindIp in the network interface section.

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1,172.17.0.1

Note that binding to 0.0.0.0 would also do the trick but is not recommended due to security reasons.

Second, you should choose a hostname to access the database. Let’s use mongoservice for that. In your containerized app, use this hostname in the connection string, like so…

mongodb://mongoservice:27017/mydb

To introduce the mongoservice hostname in the containers virtual network and bind it to our local host where MongoDB is running, simply use the --add-host option of docker run with the bridge networks gateway IP we discovered earlier.

docker run --add-host=mongoservice:172.17.0.1 repository/image-name

Having this in place, your Docker container now can communicate with the host using the alias mongoservice and your are good to go in connecting to the local MongoDB 🙂

Tip: using the identical hostname alias for MongoDB locally

To avoid inconsistencies and configuration changes between running your app in the local dev environment and the Docker container, simply add an entry for the used hostname mongoservice to your /etc/hosts.

127.0.0.1   localhost localhost.localdomain
::1         localhost localhost.localdomain
127.0.0.1   mongoservice

Now you can use the exactly same connection string also in your local dev environment.

Troubleshooting: MongoDB isn’t starting up any more

After adding the Docker bridge gateway IP to MongoDB’s configuration like described before you may face an issue when trying to start MongoDB. Although everything was fine before.

$ systemctl start mongod
Job for mongod.service failed because the control process exited with error code.
See "systemctl status mongod.service" and "journalctl -xeu mongod.service" for details.
$ systemctl status mongod
× mongod.service - MongoDB Database Server
     Loaded: loaded (/usr/lib/systemd/system/mongod.service; enabled; vendor preset: disabled)
     Active: failed (Result: exit-code) since Thu 2022-03-17 21:08:18 CET; 36s ago
       Docs: https://docs.mongodb.org/manual
    Process: 16629 ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb (code=exited, status=0/SUCCESS)
    Process: 16630 ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb (code=exited, status=0/SUCCESS)
    Process: 16631 ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb (code=exited, status=0/SUCCESS)
    Process: 16632 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=48)

Mar 17 21:08:18 fedora systemd[1]: Starting MongoDB Database Server...
Mar 17 21:08:18 fedora mongod[16632]: about to fork child process, waiting until server is ready for connections.
Mar 17 21:08:18 fedora mongod[16634]: forked process: 16634
Mar 17 21:08:18 fedora mongod[16632]: ERROR: child process failed, exited with 48
Mar 17 21:08:18 fedora mongod[16632]: To see additional information in this output, start without the "--fork" option.
Mar 17 21:08:18 fedora systemd[1]: mongod.service: Control process exited, code=exited, status=48/n/a
Mar 17 21:08:18 fedora systemd[1]: mongod.service: Failed with result 'exit-code'.
Mar 17 21:08:18 fedora systemd[1]: Failed to start MongoDB Database Server.

If this is the case, it is very likely that Docker is not running! Make sure to start Docker before MongoDB. Otherwise MongoDB will fail to start because the Docker bridge gateway isn’t available and it cannot bind to it.

$ systemctl start docker
$ systemctl start mongod

If you want to start MongoDB without having Docker running, then you’ll need to remove or comment out the gateway’s IP in /etc/mongod.conf.

Happy coding 🙂

Useful links

]]>