我在Windows 7计算机上使用vagrant和docker,VirtualBox作为docker主机VM的提供程序。我有一个使用docker
提供程序定义的vagrant项目,以便vagrant up
将启动mongo
容器。我没有在docker host VM中配置mongo
容器,因为我有时需要mongo
,有时候需要postgres
等。
对于mongo
情况,我正在尝试针对此正在运行的mongo
容器运行一些mongo集合初始化脚本,以使用vagrant设置索引等。 mongo
图片不会运行mongod
以外的任何内容,因此容器的has_ssh
为false
,因此使用配置程序运行这些操作不是一种选择。
我尝试在链接到运行mongodb
的容器的单独容器中运行mongo shell,但为了实现这一点,我需要能够扩展mongo
环境变量({{ 1}}和MONGO_PORT_27017_TCP_ADDR
)命令在容器中运行时。
我一直在尝试使用MONGO_PORT_27017_TCP_PORT
执行此操作,但我无法找到正确解释命令的方法,以便正确扩展这些环境变量。每次尝试都导致vagrant docker-run
命令抱怨主机和端口未提供(环境变量扩展为空)。
我最终希望能够做到的是:
mongo
我可以尝试任何建议或其他方法吗?
Powershell是此Windows系统上的命令行解释器:
mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/db-name" initialize.js
泊坞主机PS C:\Users\hoobajoob\Documents\Eclipse\workspace-sts-luna\project\.environment\vagrant\mongo-provisioner> vagrant docker-run default -- mongo
'$MONGO_PORT_27017_TCP_ADDR:`$MONGO_PORT_27017_TCP_PORT/test' --eval "printjson(db.getCollectionNames())"
==> default: Docker host is required. One will be created if necessary...
default: Docker host VM is already ready.
==> default: Creating the container...
default: Name: mongo-provisioner_default_1449193166_1449193166
default: Image: mongo
default: Cmd: mongo $MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test
default: Link: mongo-container:mongo
default:
default: Container is starting. Output will stream in below...
default:
default: MongoDB shell version: 3.0.7
default: 2015-12-04T01:38:20.037+0000 E QUERY Error: Missing host name in connection string ":/test"
default: at Error (<anonymous>)
default: at connect (src/mongo/shell/mongo.js:160:15)
default: at (connect):1:6 at src/mongo/shell/mongo.js:160
default: exception:
default: connect failed
default:
A Docker command executed by Vagrant didn't complete successfully!
The command run along with the output from the command is shown
below.
Command: "docker" "run" "--name" "mongo-provisioner_default_1449193166_1449193166" "--link" "mongo-container:mongo" "--rm=true" "mongo" "mongo" "$MONGO_POR
T_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test" "--eval" "printjson(db.getCollectionNames())"
Stderr: exception: connect failed
Stdout: MongoDB shell version: 3.0.7
2015-12-04T01:38:20.037+0000 E QUERY Error: Missing host name in connection string ":/test"
at Error (<anonymous>)
at connect (src/mongo/shell/mongo.js:160:15)
at (connect):1:6 at src/mongo/shell/mongo.js:160
:
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.hostname = "docker-host"
config.vm.box_check_update = false
config.ssh.insert_key = false
config.vm.box = "williamyeh/ubuntu-trusty64-docker"
config.vm.network "forwarded_port", guest: 27017, host: 27017
config.vm.synced_folder ".", "/vagrant", disabled: true
end
容器mongod
:
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider "docker" do |docker|
docker.vagrant_vagrantfile = "../docker-host/Vagrantfile"
docker.image = "mongo"
docker.ports = ['27017:27017']
docker.name = 'mongo-container'
end
end
容器mongo shell
(这是我尝试运行Vagrantfile
命令的容器,以便链接到vagrant docker-run
容器的mongo环境变量得到正确扩展):
mongod
答案 0 :(得分:0)
目前,我发现Vagrant的码头提供商在我可以用它执行的码头集装箱操作范围方面相当有限。
我考虑在mongo容器中运行ssh
,这样我就可以在mongo
容器上运行Vagrant的配置程序,这样我就可以让这些脚本以这种方式运行。但是,这需要a)定义自定义图像并重新处理入口点,以便启动ssh
和mongod
,以及b)在docker provider has_ssh=true
中设置Vagrantfile
。
遗憾的是,该选项与当前版本的vagrant不兼容,如果我在docker中将vagrant up
设置为has_ssh
,则当我运行true
时会在我的Windows系统上挂起提供者Vagrantfile
。
所以,对于这个Vagrant新手,我的选择似乎有限。
我目前认为更好的方法可能是完全停止使用两个docker提供程序Vagrantfile
项目,而是在一个docker host {{1}中定义一堆不同的配置程序}}
然后,如果我想启动一个特定的容器,我可以定义并运行一个只运行该容器的配置器(不执行任何mongo初始化)。如果我想运行这些mongo初始化脚本,那么我有一个单独的配置器将执行这些操作,依此类推。
拆除容器需要使用相应的Vagrantfile
命令运行vagrant ssh
。
诉诸于此似乎是一种耻辱,但我没有太多运气试图通过docker rm
初始化mongo。
我完全放弃了使用Vagrant的docker提供程序,主要是因为至少在我的情况下,我发现docker提供程序在支持的docker词汇表中太有限,无法满足我的需求。这个结论是合理的,因为我不是Vagrant或Docker的老手,所以我完全有可能错过了一些东西。
例如,为了初始化mongo数据库,我希望能够使用可能由目标站点上的vagrant docker-run
管理员运行的相同javascript初始化文件来执行此操作,并且这些来自开源树。如果必须构建一个预先配置了这些文件的自定义docker mongo容器,则需要花费太多的开销。
至少在我理解的情况下,流浪的方式是使用mongoDB
配置程序将该文件复制到正在运行的容器,并使用file
配置程序在容器上执行它。 Vagrant的script
和file
配置程序需要在容器上使用SSH才能工作。
但是,在码头工人的土地上似乎是a common recommendation并不是出于各种原因在容器中运行SSH,所以如果我没有,我不想这样做到。
在不创建预配置这些文件的自定义容器的情况下实现此目的的(或一个)docker方法是使用script
和docker cp <container>
以在正在运行的容器上实现此目的。这些都不是由Vagrant的docker provider命令浮出水面的,所以我没有看到我将如何通过docker provider到达那里。
所以,我相信,使用Vagrant的配置程序是完全合理的,但只有在与Docker主机VM(我的情况下是一个VirtualBox盒)进行交互时,才能使用SSH访问权限。任何争议(据我所知)。
我将所有容器生命周期操作 - 创建,启动,停止,重启,rm等 - 移动到docker主机的docker exec <container>
配置上的配置器中。为了执行这些操作,我坚持使用docker cli。
Docker Host VM上的Vagrantfile
配置文件如下所示:
Vagrantfile
... # provisioners
config.vm.provision "host.provision.scripts.mongo", type: "file", source: $mongoProvisionInit, destination: $hostProvisionMongoInit
config.vm.provision "mongo.run", type: "shell", inline: $dockerRun_mongo
config.vm.provision "mongo.provision.scripts", type: "shell", inline: $dockerCp_MongoInit
config.vm.provision "mongo.db.init", type: "shell", inline: $dockerExec_mongoDbInit
config.vm.provision "mongo.stop", type: "shell", inline: $dockerStop_mongo
config.vm.provision "mongo.start", type: "shell", inline: $dockerStart_mongo
config.vm.provision "mongo.restart", type: "shell", inline: $dockerRestart_mongo
config.vm.provision "mongo.rm", type: "shell", inline: $dockerRm_mongo
e
脚本如下所示:
inline
...然后我使用bmuschko:$dockerRun_mongo = <<MONGO
echo '>>> docker run --name mongo-container -p 27017:27017 -d mongo'
docker run --name mongo-container -p 27017:27017 -d mongo
MONGO
$dockerCp_MongoInit = <<MONGO
echo '>>> docker exec mongo-container mkdir /home/vagrant'
docker exec mongo-container mkdir -p /home/vagrant
echo '>>> docker cp ./provision/mongo/initialize.js mongo-container:/home/vagrant/mongo.initialize.js'
docker cp ./provision/mongo/initialize.js mongo-container:/home/vagrant/mongo.initialize.js
MONGO
$dockerExec_mongoDbInit = <<MONGO
echo '>>> docker exec mongo-container mongo mongo db-name /home/vagrant/mongo.initialize.js'
docker exec mongo-container mongo db-name /home/vagrant/mongo.initialize.js
MONGO
$dockerStop_mongo = <<MONGO
echo '>>> docker stop mongo-container'
docker stop mongo-container
MONGO
的vagrant插件将所有这些连接到gradle
。因此,我的开发环境可以通过诸如'com.bmuschko:gradle-vagrant-plugin:2.0'
之类的gradle任务实现自动化,这些任务会在这些不同的配置程序上发出initializeMongoAndRun
命令以完成工作。
这意味着所有参与此项目的开发人员都需要同意在vm中托管docker,即使在Linux系统上也是如此。为了在机器上实现一致的docker和容器体验,这似乎是一种可接受的权衡。
我会关注Vagrant vagrant provision --provision-with
提供商。对于这些类型的用途,它可能会变得更加实用,或者我会弄清楚我失去了什么使它成功。