Adding new exposed ports to existing docker container (Windows/WSL 2)
A couple of days ago I was setting up a development environment for an open source project. There were requirements and guides for getting everything done... but not one for Windows. I use Docker for almost everything so no big deal there: just started new Ubuntu container.
After an hour of installing and downloading 3rd party things and fixing scripts that didn’t work for some reason I was ready to make those little changes I wanted to get done. Everything was working fine and tests were passing but I hadn’t tested actual application. Then it hit me. I just started a container without exposing any ports. So I couldn’t access the application from host (Windows).
I already knew that there aren’t any commands to change the exposed ports after the container is started. After little bit googling I found two options. Either save the container as image and start a new one from that image with exposed ports (lame) or stop docker and alter configuration files. So I started to search where docker files are saved when used with WSL 2.
Finding the files was the hardest part. Even find
command did not succeed. A couple of minutes in the web told me that all the data is in /mnt/wsl
. The two files needed for this operation are /mnt/wsl/docker-desktop-data/data/docker/containers/<container-id>/hostconfig.json
and /mnt/wsl/docker-desktop-data/data/docker/containers/<container-id>/config.v2.json
/mnt/wsl/docker-desktop-data/data/docker
cannot be accessed if docker daemon is shutdown. Config files will be overwritten when docker exits. So container directory must be open when closing docker and files must be edited after docker is shutdown completely.
In thehostconfig.json
there is a configuration block that needs to be edited: PortBindings
. For example opening port 3000 should look like this:
PortBindings":{"3000/tcp":[{"HostIp":"","HostPort":"3000"}]}
In theconfig.v2.json
there are two configuration blocks which need editing: ExposedPorts
andPorts
. First one is just object from port/protocol to object and second one is mapping from container port/protocol to list of host interface and port pairs.
//Inside config block
"ExposedPorts":{"3000/tcp":{}}//Inside NetworkSettings block
"Ports":{"3000/tcp":[{"HostIp":"0.0.0.0","HostPort":"3000"}]}
After the files were edited, I just started docker, container and dev environment in a container. And voilà!