Ir al contenido principal

Port forwarding with Docker Toolbox

Though most of the computing resources, as Docker containers, run now in the Cloud, soon or later the modern programmer needs to deploy some stuff in its local computer.

In that scenario, chances are that you had to install the Docker Toolbox, the legacy solution for older Mac and Windows systems, instead of just installing the new Docker Desktop. One of those scenarios is that in which your computer hardware or software doesn't support hypervisor frameworks (older Intel processors not supporting virtualization technology, for instance)

So you've downloaded and successfully installed Docker Toolbox and now you have a cool VirtualBox machine running in local. Everything seems promising, so you code a simple  HTTP server that greets you with an original "Hello World!" when you make an HTTP GET request to the port 80. You've tested it in your local machine and it works!, so you decide to create a container and put your server on it to run it locally.

Since you're a clever guy, first thing you do is changing your code to avoid container problems by setting not just the port (80) but also the address (0.0.0.0) in which the future contained server will listen to. Again you test it and it keeps running as before, so your next step is creating a docker image by writing a suitable Dockerfile and running the command docker build.

Great, now you have a docker image in your local server ready to be run, so you do it by typing:

docker run -p 8080:80/tcp \
--name myHttpServer --detach httpServer:1.0

That command is deploying and running a new container from an image called httpSever in its version 1.0. The new container is being identified by the name myHttpServer and the container TCP port 80 is being forwarded to your local machine TCP port 8080. Lastly, the container console output is being dettached from your local console. 

To check that everything is ok, you run a docker container ls command to see that the just locally deployed container is happily running. So you try to make an HTTP GET request to your localhost address (127.0.0.1) but not to the port 80 but 8080, since you specified that port forwarding in the docker run command ( -p 8080:80/tcp). 

Surprisingly, you get a connection refused message. Why?

Port forwarding in VirtualBox

All the previous steps are correct, and you'll find them in most of the 1-minute tutorials all around Internet.  The fact is that most of these tutorials refers to Docker Desktop instead Docker Toolbox. This last is fully based on a VirtualBox machine, and some virtual machine rules apply, one of them being that you must explicitly forward those guest (ie your virtual machine) ports you wanted to make reachable to your host (ie your local computer) ports. Since your Docker server, and therefore your container, runs on that virtual machine, you must create a rule for forwarding the guest port 80 to the host port 8080, ie, you must replicate the same port forwarding that you defined with your docker run -p 8080:80/tcp argument.

To create a port forwarding rule on VirtualBox, follow these steps:
  1. Go to the virtual machine Configuration and then click on Network Configuration
  2. Got to Adapter 1 (it must be conected to NAT) and click on Advanced and then on Port forwarding
  3. Add a new port forwarding rule. Host and guest addresses must be left blank, while guest port must match that port in which you software listens (in this case port 80, the second one you specified in the forwarding rule of the comand docker run -p 8080:80/tcp ...) whereas host port must match that port you specified as first one in the forwarding rule of your docker run command (port 8080 in the command docker run -p 8080:80/tcp ...)
Double-check that the Virtual machine port forwarding rule matches the docker run command port forwarding rule. Once the container restarted, an HTTP GET request to 127.0.0.1:8080 should work.

Comentarios

Entradas populares de este blog

Linting C# in Visual Studio Code

Though very usual in programming environments as Javascript/Typescript, linting , or analyzing code for enforcing a set of coding style rules, is not usually present in the .NET based environments. Rule enforcing is really useful when working on team shared codebases in order to keep them coherent, what in last term reduces both development times and coding errors. A linting example Maybe a practical example would be helpful for explaining what  linting  is to the newcomers (feel free to go on if you aren't). Let's imagine you are a new member in a C# development team that has well established set of coding style rules. Instead (or apart) of putting them in a document, they've adopted a tool that checks these rules during the code building process. Your first code is such ambitious as this: namespace HelloWorld {      using System;      public class Program      {           public static void Main(string[] args)           {                Console

ESlint: Ignore unused underscore variables

Some naming conventions promote the use of the underscore character (" _ ") for those variables that must be declared but are not being used. One common case is that in which a function signature contains some variables that will not be used, as for instance the Express error handlers: app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!'); }); In the above example only the arguments err and res are being used, though all four must be defined in the handler signature. Thus, following the naming convention of using underscores for those unused variables, we could recode it as: app.use(function(err, _, res, __) { console.error(err.stack); res.status(500).send('Something broke!'); }); Though it makes the function more readable, it comes with a problem if using ESlint: it will blame by declaring unused variables. error '_' is defined but never used error '__' is define

Using Bitbucket app passwords with git on MacOS (OSX)

Learn how Bitbucket passwords are stored by git on MacOS.