Question

I'm having difficulty trying to get a simple node app running inside a docker container hosted using vagrant.

This page explains the basic approach: https://www.vagrantup.com/blog/feature-preview-vagrant-1-6-docker-dev-environments.html

What I am unable to do is access the node app from my machine - in theory I believe I should be able to see my "hello world" style node/express app at localhost:8181...

Below is what I have so far:

Vagrantfile:

Vagrant.configure("2") do |config|

  config.vm.provider "docker" do |d|

    d.build_dir = "."

    d.ports = ["8080:5000"]

    # Is this necessary if EXPOSE is used in Dockerfile?
    d.expose = ["5000"]

    d.remains_running = true

    d.volumes = ["/shared"]

  end

  config.vm.network "forwarded_port", guest: 8080, host: 8181

  config.vm.synced_folder "~/Documents/shared", "/shared"

end

Dockerfile:

# DOCKER-VERSION 0.8.0

FROM centos:6.4

RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

RUN yum install -y npm ImageMagick

ADD . /app

# Not necessary because node_modules are bundled
# RUN cd /app; npm install

EXPOSE 5000

CMD ["node", "/app/index.js"]

I've followed the documentation as closely as possible but just can't seem to achieve what I'm after. Any ideas?

Note: node app is working when running normally ie $ node index and accessed at localhost:5000

Thanks in advance

EDIT:

index.js:

var express = require('express'),
    http = require('http');

var app = express();

var port = 5000;

app.get('/', function(req, res) {
    res.send('Hello World');
});

var server = http.createServer(app);

server.on('listening', function() {
    console.log('Express server listening on port ' + port);
});

server.listen(port, '0.0.0.0');

setInterval(function(){
    console.log('running');
}, 5000);

package.json:

{
  "name": "vagrant-docker-node",
  "version": "0.0.0",
  "dependencies": {
    "express": "^4.1.0"
  },
  "main": "index.js"
}
Was it helpful?

Solution

I actually ran into the same issue. Not sure if it's intended behavior or bug but setting forwarded_port in a Vagrantfile with a Docker provider does nothing on the host boot2docker machine.

Unless I'm missing something, you have to either provide your own host machine with another Vagrantfile opening the correct ports or modify the one provided by Vagrant.


Approach 1: Provide your own host machine (based on boot2docker)

Here's the base Vagrantfile for the boot2docker host: boot2docker Vagrantfile. You need to edit a copy of this Vagrantfile and set your forwarded ports here.

Then, in your Docker app Vagrantfile, modify as follow:

config.vm.provider "docker" do |d|
  # Specify here the path to the updated host Vagrantfile
  d.vagrant_vagrantfile = "../boot2docker/Vagrantfile"

  ... # edited out for clarity
end

Make sure you point to your updated host machine. Here I set it to an upper level shared directory because if you want to share this machine between multiple Docker apps with seperate Vagrantfiles, you'll have to point to the same host Vagrantfile (otherwise it'll try to spin up new host VMs).


Approach 2: Update Vagrant's host machine

You can also update the Vagrantfile automatically used by Vagrant which is located in %VAGRANT_HOME%/data/docker-host/Vagrantfile. Modify the file to open your ports.

Then do a vagrant global-status to get the ID of the host machine and vagrant reload machineId to restart the machine which will trigger the port re-open and update.


I'm not sure if there's a better or sanctionned way to do this but that's the only way I could have the ports forwarded all the way from Docker container to physical machine.

OTHER TIPS

Shouldn't you forward the exposed port 5000 from Docker to your host, using Vagrant?

    config.vm.network "forwarded_port", guest: 5000, host: 8181

(to get your app reachable on port 8181 from your host browser, for example)

Instead of:

config.vm.network "forwarded_port", guest: 8080, host: 8181



Flows/redirects summary:

Docker container    Vagrant VM     Your computer
 :8080       =>     :5000    =>    :8181

  1. What's your host OS (the one you execute the "vagrant" command on)? If it's non-Linux (e.g. OSX or Windows) then your Docker container will be riding on top of a Linux VM (usually TinyCore Linux inside VirtualBox), and the port forwarding will be done from inside that VirtualBox into the Docker container.
  2. You should see evidence of port forwarding taking effect by looking for listening TCP sockets using "netstat -tlpn" (on Linux) or "netstat -an" (on OSX)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top