I'm running my mongodb in virtualbox using vagrant. I'm trying to connect to the database on my host machine using node.js, but I get thrown a strange err when trying to do so. This is the code i'm running.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:6600/test";
MongoClient.connect(url, function(err, db){
if (err){
throw err;
}
console.log("Database created!");
db.close();
});
This is the error that is shown in command line.
C:\Users\Morgan\Desktop\testingGrounds>node createMongoDB.js
C:\Users\Morgan\Desktop\testingGrounds\node_modules\mongodb\lib\mongo_client.js:421
throw err
^
[object Object]
And this is a relevant part of the Vagrantfile.
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# config.vm.network "forwarded_port", guest: 80, host: 8080
# nginx
config.vm.network "forwarded_port", guest: 80, host: 6600
# # development site
config.vm.network "forwarded_port", guest: 3000, host: 6660
# db browser port
config.vm.network "forwarded_port", guest: 7474, host: 6666
# test port
config.vm.network "forwarded_port", guest: 8800, host: 6606
If you are using vagrant for some dev/test running on local, just use a static ip it will simplify your life.
You can remove all the forwarded ports line from your Vagrantfile and replace with:
config.vm.network :private_network, ip: "192.168.33.10"
In the VM, you need to make sure mongo is bound to this IP or 0.0.0.0 so it can listen to all network interfaces, in the /etc/mongod.conf file, make sure to have
bind_ip=0.0.0.0
or
bind_ip=192.168.33.10
In your node code, you will need to replace the url for mongo to mongodb://192.168.33.10:27017/test (assuming mongo is running on port 27017; if you have made a change in your conf file, align here)
Related
I am new to networking and assigning ports and things of that nature. I have been using vagrant for some time and have never had any problems trying to get a test environment up and then accessing it through the host machine browser. The set up for this in my Vagrantfile is this:
# network stuff
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.hostname = "test-box-debian"
Now I am trying to learn a bit about node.js, and every tutorial says I can run npm start and indeed this works fine. I can call wget localhost:3000 (port 3000 being the default in express) and in return get the index.html default page from express.
However when I try and access `192.168.33.10:3000' from the host browser, it doesn't work. I can run netstat and get the following as a result:
sudo netstat -ltpn | grep 3000
tcp6 0 0 :::3000 :::* LISTEN 17238/node
I can see that something doesn't look right but I just don't know enough about ports and networking to know what is wrong and how to fix it.
First, ensure your server is listening to the right IP and that you haven't bound the Express listener elsewhere:
.listen(3000), NOT .listen(3000, '127.0.0.1')
Alternatively, try binding the Express server to your private IP or to the wildcard IP and see if that resolves your connectivity issues:
// Wildcard (All IP's) binding
.listen(3000, '0.0.0.0')
// Specific binding
.listen(3000, '192.168.33.10')
Lastly, port 3000 may not be accessible from the host. If none of the above options in your server code work, try adding the following line to your Vagrantfile:
config.vm.network "forwarded_port", guest: 3000, host: 3000
Make sure you don't have a firewall on your VM blocking the port:
sudo iptables -I INPUT -p tcp --dport 3000 -j ACCEPT
Found the answer over at https://stackoverflow.com/a/28474080/1772120.
If your vagrant setting is like
# network stuff
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.hostname = "test-box-debian"
Then your node app should listen to 192.168.33.10:8000
const http = require('http');
const hostname = '192.168.33.10';
const port = 8000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type','text/plain');
res.end('Hello World\n');
})
server.listen(port, hostname, () => {
console.log('Server running at');
})
I am trying to set up a Node.js app using Vagrant. There is also a Rails app inside that very same Vagrant box, which works OK. Node is using port 3001, so here are the config settings in Vagrantfile:
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "puppetlabs/ubuntu-14.04-32-puppet"
config.vm.provision :shell, path: "bootstrap.sh"
config.vm.network :forwarded_port, host: 4567, guest: 3000
config.vm.network :forwarded_port, host: 5678, guest: 3001
So, I started Node in Vagrant box. This shows that inside the Vagrant box it responds to requests on port 3001:
vagrant#localhost:~$ wget 127.0.0.1:3001
--2014-12-24 06:37:40-- http://127.0.0.1:3001/
Connecting to 127.0.0.1:3001... connected.
HTTP request sent, awaiting response... 200 OK
The guest machine is listening to port 3001:
$ sudo netstat -ltpn | grep 3001
tcp 0 0 127.0.0.1:3001 0.0.0.0:* LISTEN 1422/node
The host is listening to port 5678:
sudo netstat -ltpn | grep 5678
tcp 0 0 0.0.0.0:5678 0.0.0.0:* LISTEN 30966/VBoxHeadless
And yet, I can't connect to the app from the host browser.
What can be the problem?
Updated: Output on vagrant up:
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] -- 3000 => 4567 (adapter 1)
[default] -- 3001 => 5678 (adapter 1)
Got the answer from a colleague.
Turned out, the node server in vagrant was listening to localhost, while it should have been listening to 0.0.0.0:
so this line in www file:
var server = app.listen(app.get('port'), 'localhost', function() {
had to be changed to:
var server = app.listen(app.get('port'), '0.0.0.0', function() {
All's working now.
I have a simple nginx, node.js setup that I want to migrate into the Vagrant, Docker world. I'm not sure how to handle IPs and ports.
My goal is it to see my Hello World in the Browser, best case on port 80, simply by calling my host http://example.com.
UPDATE
I found the solution myself - I created a simple boilerplate here:
https://github.com/ezmilhouse/docker
Feel free to go on from here.
app.js
var app = express();
app.route('*').all(function(req, res) {
res.send('Hello World!');
});
app.listen(2000)
nginx.conf
upstream example.com {
# using the vagrant private network IP (I guess?)
# using the node port
server 192.168.33.10:2000
}
server {
# ports nginx server is listen to
listen 80;
listen 443;
location / {
# upstream proxy
proxy_pass http://example.com;
# ...
}
}
Vagrantfile.proxy
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provision "docker"
# settimg a hostname that matches nginx upstream (I guess?)
config.vm.hostname = "example.com"
# setting a private network IP, node.js and nginx run on this IP (i guess?)
config.vm.network "private_network", ip: "192.168.33.10"
end
Vagrantfile
Vagrant.configure("2") do |config|
config.vm.define "nginx" do |app|
# forward the nginx port (I guess?)
app.vm.network "forwarded_port", guest: 80, host: 80
app.vm.provider "docker" do |d|
d.build_dir = "./docker/nginx"
d.vagrant_vagrantfile = "./Vagrantfile.proxy"
end
end
config.vm.define "node" do |app|
# forward the node port (I guess?)
app.vm.network "forwarded_port", guest: 2000, host: 2000
app.vm.provider "docker" do |d|
d.build_dir = "./docker/node"
d.vagrant_vagrantfile = "./Vagrantfile.proxy"
end
end
end
/nginx/Dockerfile
# ...
EXPOSE ["80"]
/node/Dockerfile
# ...
EXPOSE ["2000"]
Mac OS X /etc/hosts
192.168.33.10 example.com
I was expecting to call http://192.168.33.10 in the browser to see my Hello World via nginx and http://192.168.33.10:2000 to see the node instance. Therefore the host example.com does not work either.
What do I do wrong?
I created the fork and made pull request to your repo.
The main idea: do not use provisioning for docker containers.
More information your can find in this article
My Problem:
I can only access my sites through port 8000, but not 80, which makes me think it is not redirecting 80 to 8000 as it says it should be. I want to simply type local.kujif.com into my browser and it loads the site, which I read was port 80 by default. I am using curl to check it and it returns:
curl 'http://local.kujif.com'
curl: (7) Failed connect to local.kujif.com:80; No error
However if I add :8000 to the url then it works; it returns my index.php which simply prints 'test':
curl 'http://local.kujif.com:8000'
test
My Details:
I am using Laravel Homestead and Vagrant with Oracle VM VirtualBox.
In the Homestead.rb it has the port forwarding. I haven't edited it at all:
config.vm.network "forwarded_port", guest: 80, host: 8000
config.vm.network "forwarded_port", guest: 3306, host: 33060
config.vm.network "forwarded_port", guest: 5432, host: 54320
I also have Microsoft IIS installed for my work stuff. I obviously stop that service whenever I need vagrant to use the localhost.
"vagrant up" shows:
My Homestead.yaml file:
---
ip: "192.168.10.10"
memory: 2048
cpus: 1
authorize: /Users/Tyler/.ssh/id_rsa.pub
keys:
- /Users/Tyler/.ssh/id_rsa
folders:
- map: C:\DEV\Linux
to: /var/www/
sites:
- map: homestead.app
to: /home/vagrant/Code/Laravel/public
- map: local.kujif.com
to: /var/www/kujif
variables:
- key: APP_ENV
value: local
You should continue to use ports above 1024 since they are non-privileged ports, BUT if you do want you can run as port 80 on the Homestead VM, as long as you don't have anything holding on to that port on the host machine. Just tried it and it worked, with a few gotchas. First, you change that line in the .rb file from:
config.vm.network "forwarded_port", guest: 80, host: 8000
to
config.vm.network "forwarded_port", guest: 80, host: 80
When you fire your VM up after saving you will get a warning from vagrant:
==> default: You are trying to forward to privileged ports (ports <= 1024). Most
==> default: operating systems restrict this to only privileged process (typically
==> default: processes running as an administrative user). This is a warning in case
==> default: the port forwarding doesn't work. If any problems occur, please try a
==> default: port higher than 1024.
==> default: Forwarding ports...
default: 80 => 80 (adapter 1)
But it worked for me. Now, to actually get to the VM I had to use it's private IP instead of the localhost name:
http://192.168.10.10/
But sure enough my site was there and everything was working. If you decide to keep it that was you can add that IP address to your hosts file to give it a nice short name.
Hope this helps.
I see there is an accepted answer, but this alternative may also help someone.
If I understand correctly you really dislike the port "8000"!
Have you tried setting a private network?
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
/*other config stuff here */
config.vm.network :private_network, ip: "192.168.33.22"
This way you can simply use that IP address, or edit you hosts file to map the local domain to that IP.
Take a look at the Vagrant docs:Vagrant Private Networks
BTW, You shouldn't need to shutdown your IIS local server as that is running on a totally different IP range. I have Apache running locally while also accessing the VM server. This allows you to use tools like composer (to pull in laravel) on your local if needed.
I'm not sure what the confusion is - this is the way it's supposed to work.
The web server on the VM listens on port 80. Vagrant/VirtualBox forwards that port from 80 (on the VM) to 8000 (on localhost) so that you can access the site at http://localhost:8000.
Port 80 on the VM's domain name is not going to be available - that domain name probably resolves to localhost.
Try the following: dig local.kujif.com (or nslookup or even ping - I don't know what tools are available on Windows) to find out what IP address that name is resolving to. You will probably find that it's 127.0.0.1 (localhost).
You could try using the IP address set in the homestead file instead: http://192.168.10.10/ - this might work, but it will depend on how networking is configured in the VM.
Ideally, you need to set networking to "bridged" in the VM - this will make the VM look (to your network) like any other device on the network. Other networking options in the VM (sorry, I'm not familiar with the options in VirtualBox) will set the VM up with its own network that is not accessible outside the VM - this is why port forwarding is used to expose network services on the VM.
You can disable the default port forwarding completely by adding the following to the Homestead.yaml:
default_ports: false
Or configure however you like by adding something like:
ports:
- send: 80
to: 80
In my Vagrantfile I have the definition of my development machine with a private network ip of 192.168.33.10 and a forwarded port of "guest=80, host=8888", but when a run my vagrant enviroment and I try to run curl -i 192.168.33.10:8888 I get an error saying 'Failed connect to 192.168.33.10:8888; connection refused', but when I try to connect to 192.168.33.10:80 everything it's ok.
My Vagrantfile is:
Vagrant::configure("2") do |config|
config.vm.box = "precise32"
config.vm.define :web do |www|
www.vm.hostname = "apache"
www.ssh.max_tries = 10
www.vm.network :forwarded_port, guest: 80, host: 8888 # Apache port
www.vm.network :private_network, ip: "192.168.33.10"
www.vm.synced_folder "www", "/var/www", :extra => 'dmode=777,fmode=777'
end
end
Why this happens? is vagrant ignoring the forwarded port?
By default Vagrant Boxes use NAT mode, it means that the guests are behind a router (VirtualBox Networking engine between the host and the guest) which maps traffic from and to the virtual machine transparently. The guests are invisible and unreachable from the host.
That's why we need port forwarding. Otherwise services running on guest wont' be accessible.
In your case, you are using Private Network, the guest will be assigned a private IP address that ONLY the host can access, which is 192.168.33.10.
The proper way to access web hosted on the guest is => http://192.168.33.10 from the host.
You have the port forwarding part in the Vagrantfile
www.vm.network :forwarded_port, guest: 80, host: 8888 # Apache port
It is forwarding guest port 80 to your host's 8888. Because you are NOT using NAT mode I am pretty sure it will be ignored. Try to curl -Is http://localhost:8888.
NOTE: even if it still work somehow, you should be accessing web by => http://localhost:8888/ from your host.