我正在尝试使用 2 个 Docker 容器建立一个原始的 CI/CD 管道——我将它们称为 jenkins 和 node-app。我的目标是让 jenkins 容器在提交到 GitHub 存储库时运行作业(已完成)。该作业应在 node-app 容器上运行 deploy.sh
脚本。因此,当开发人员向 GitHub 提交时,jenkins 会接收该提交,然后启动包括自动化测试(将来)的工作,然后在 node-app 上进行部署.
jenkins 容器正在使用最新的镜像 ( Dockerfile) 。
node-app容器的 Dockerfile 是:
FROM node:latest
EXPOSE 80
WORKDIR /usr/src/final-exercise
ADD . /usr/src/final-exercise
RUN apt-get update -y
RUN apt-get install -y nodejs npm
RUN cd /src/final-exercise; npm install
CMD ["node", "/usr/src/final-exercise/app.js"]
jenkins 和 node-app 使用 Docker Compose 链接,并且 docker-compose.yml
文件包含(已更新,感谢 @碱):
node-app:
container_name: node-app
build: .
ports:
- 80:80
links:
- jenkins
jenkins:
container_name: jenkins
image: jenkins
ports:
- 8080:8080
volumes:
- /home/ec2-user/final-exercise:/var/jenkins
容器是使用 docker-compose up -d 构建的,并按预期启动。 docker ps 产量(更新):
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69e52b216d48 finalexercise_node-app "node /usr/src/final-" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp node-app
5f7e779e5fbd jenkins "/bin/tini -- /usr/lo" 3 hours ago Up 3 hours 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins
我可以从 node-app ping jenkins,反之亦然。
这可能吗?如果不是,我在这里犯了一个架构错误吗?
提前非常感谢您,非常感谢!
编辑:
我偶然发现了 nsenter 并使用 this 轻松进入容器的 shell和 this 。然而,这些都假设源(在他们的例子中是主机,在我的例子中是jenkins容器)安装了Docker,以便找到目标容器的PID。我可以从主机 nsenter
进入 node-app,但 jenkins 仍然没有运气。
最佳答案
node-app:
build: .
ports:
- 80:80
links:
- finalexercise_jenkins_1
jenkins:
image: jenkins
ports:
- 8080:8080
volumes:
- /home/ec2-user/final-exercise:/var/jenkins
尝试上面的方法。您正在按图像名称链接,但必须使用容器名称。 在您的情况下,由于您没有明确指定容器名称,因此它会像这样自动生成
finalexercise : folder where your docker-compose.yml is located
node-app : container configs tag
1 : you only have one container with the prefix finalexercise_node-app. If you built a second one, then its name will be finalexercise_node-app_2
yml 文件的设置:
node-app:
build: .
container_name: my-node-app
ports:
- 80:80
links:
- my-jenkins
jenkins:
image: jenkins
container_name: my-jenkins
ports:
- 8080:8080
volumes:
- /home/ec2-user/final-exercise:/var/jenkins
当然,您也可以为节点应用程序指定容器名称,这样您就可以使用一些常量进行通信。
更新
为了进行测试,请登录到 jenkins 容器的 bash 终端
docker exec -it my-jenkins bash
然后尝试 ping my-node-app,甚至 telnet 特定端口。
ping my-node-app:80
或者你可以
telnet my-node-app 80
更新
您想要做的事情可以通过 exec
轻松完成 command 。
您可以从您的主机执行此操作(尝试一下以确保它正常工作)
docker exec -i <container_name> ./deploy.sh
如果上述方法有效,那么您的问题将委托(delegate)从容器执行相同的命令。事实上你不能这样做,因为发出命令的容器(jenkins)无权访问主机的 docker 安装(它不仅识别命令,而且控制你需要访问的容器)。
我没有使用过它们,但我知道两种解决方案
- 使用这个官方guide访问主机的 docker 守护进程并从容器发出 docker 命令,就像从主机执行此操作一样。
- 将 docker 二进制文件和套接字挂载到容器中,以便容器充当主机(每个命令都将由主机的 docker 守护进程执行,因为它是共享的)。
这个thread来自 SO 给出了关于这个问题的更多见解。
关于jenkins - Docker - 从一个链接容器向另一个容器发出命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34687421/