【问题标题】:Docker build & run only in first vagrant upDocker 仅在第一次 vagrant up 时构建和运行
【发布时间】:2017-08-21 19:57:19
【问题描述】:

问题:有没有一种方法可以让我只在第一次创建 vagrant 机器时构建和运行 docker 映像?

问题:运行vagrant provision 时出现错误提示docker: Error response from daemon: Conflict. The container name "/jenkins" is already in use by container <snip>

附加信息:我跑了vagrant provision,因为我在plugins.txt文件中添加了另一个插件,以便在设置jenkins机器时自动安装。

我以这种方式创建了构建脚本,以使 vagrant 机器构建尽可能快,并且 docker 镜像尽可能小(这里仍然需要工作)。还因为我想删除 Jenkins 设置 GUI,并创建了一个默认管理员帐户。

流浪文件:

Vagrant.require_version ">= 1.5"

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

    config.vbguest.auto_update = false

    config.vm.provider :virtualbox do |v|
        v.customize [
            "modifyvm", :id,
            "--memory", 1024,
            "--natdnshostresolver1", "on",
            "--cpus", 2,
        ]
    end

    config.vm.box = "ubuntu/trusty64"
    config.vm.hostname = "dev-jenkins-site"

    # Forward jenkins port.
    config.vm.network "forwarded_port", guest: 8080, host: 8080

    config.vm.network :private_network, ip: "192.168.34.56"

    jenkins_dir = "/var/jenkins_home"

    # Run Dockerfile.
    config.vm.provision "docker"

    # Restart jenkins container, in case it was stopped (which is possible from a 'vagrant halt').
    #   This won't run if this after the docker build & run provision (below) when using 'vagrant provision' because it
    #   returns an error and exits before this can run.
    config.vm.provision "shell",
      inline: "docker restart jenkins",
      run: "always"

    # Only need to build the image and container one time.
    #   Using '--restart always' doesn't work when the container is stopped from 'vagrant halt'.
    config.vm.provision "shell",
      inline: "cd /vagrant && make jenkins && docker run -d --name jenkins -p 80:8080 -p 50000:50000 -v #{jenkins_dir}:#{jenkins_dir} draven/jenkins",
      run: "once"

    # Files on your local machine
    config.vm.synced_folder "./jenkins_home", jenkins_dir
    config.vm.synced_folder ".", "/vagrant"
end

Dockerfile:

FROM jenkins/jenkins:latest

COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt

ENV JENKINS_USER admin
ENV JENKINS_PASS admin

# Skip initial setup
ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false

COPY default-user.groovy /usr/share/jenkins/ref/init.groovy.d/

VOLUME /var/jenkins_home

生成文件:

SHELL:=/bin/bash

jenkins:
    cd docker-image && docker build -t draven/jenkins .

【问题讨论】:

    标签: docker jenkins vagrant


    【解决方案1】:

    如果没有另外的指示,Vagrant Provision 总是运行所有的 Provisioner。

    一种解决方案是通过首先删除同名容器(如果存在)来使您的 docker 配置程序具有幂等性:

    config.vm.provision "shell",
      run: "once",
      inline: <<-SHELL
        cd /vagrant \
        && docker ps -a -f "name=jenkins" \
        && docker rm jenkins;
        make jenkins \
        && docker run -d \
            --name jenkins \
            -p 80:8080 -p 50000:50000 \
            -v #{jenkins_dir}:#{jenkins_dir} \                   
            draven/jenkins
      SHELL
    

    【讨论】:

    • 这应该对我有用,因为我的 jenkins_home/ 文件夹没有被删除。 docker ps -a -f "name=jenkins" 有必要吗?如果是这样,为什么?并且不能在控制台显示内容吗?
    • -a 不仅适用于所有正在运行的容器,-f 用于直接使用 docker 过滤,但您也可以使用| grep jenkins。如果您不需要输出,您可以将 stdout(和或 stderr)重定向到 /dev/null(检查此answer)。
    • 对不起,我想我的问题不清楚。 docker ps -a -f "name=jenkins" 是否需要用docker rm jenkins 停止容器?在我看来,我可以单独使用docker rm jenkins,因为它不依赖于docker ps 输出。
    • 如果使用 `docker ps -a -f "name=jenkins" && docker rm jenkins`,只有在上一个命令成功的情况下,您才会删除 jenkins 容器(所以仅当存在具有该名称的容器时)否则docker rm 可能在不存在名为 jenkins 的容器时返回 false(1)。但是您也可以将docker rm 的结果重定向到 /dev/null 并始终运行下一个命令。我个人更喜欢第一种方法。
    猜你喜欢
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 2016-09-04
    • 2016-07-06
    • 1970-01-01
    相关资源
    最近更新 更多