docker - Dockerfile 和 Jenkinsfile - COPY 存储库
问题描述
我正在尝试在 Jenkinsfile 中克隆我所有的 git 存储库:
stage('Clone git') {
steps {sh 'mkdir repo1'
sh 'cd repo1'
dir ('repo1') {
git ([url : 'https://github.../repo1.git', branch : 'develop', credentialsId : '***'])}
sh 'mkdir repo2'
sh 'cd repo2'
dir ('repo2') {
git ([url : 'https://github.../repo2.git', branch : 'develop', credentialsId : '***'])}
}
}
stage('Build Docker') {
steps {sh 'cd ..'
sh 'docker build -t myimage .'
sh 'docker run myimage'
}
然后在我的 Dockerfile 我有这个:
FROM node:12.2.0-alpine
COPY . /myapp
WORKDIR /myapp
RUN apk update
FROM gradle:6.3-jdk11 AS build
COPY --chown=gradle:gradle . /repo1
WORKDIR /repo1
RUN gradle build --no-daemon
WORKDIR /repo2
RUN npm install
RUN ng serve
请帮助我理解,如果我以正确的方式进行操作,特别是COPY命令。
我认为,它是这样工作的:首先它将 git repos 克隆到 repo1 和 repo2 文件夹。
然后在Dockerfile中,它将在 myapp 文件夹中创建一个布局,它将复制 myapp 文件夹下的两个 repo 文件夹。
问题是,我需要运行这两个服务 - 在 repo1 中它是后端,需要构建 gradle,这就是为什么我将 gradle 复制到 repo1 文件夹,不确定我是否应该在 COPY 中使用 myapp/repo1。
而repo2是前端,我认为不需要复制任何东西,只需选择WORKDIR repo2并运行服务器即可。
所以问题是,COPY 是否足够。/myapp第一步,它会复制那里的每个 repo 文件夹,还是只是将 docker 映像复制到 myapp 文件夹,我需要分别复制所有创建的文件夹?
解决方案
当使用单个 Dockerfile 时,只能创建一个 docker 映像,因此如果您希望这两个服务都运行,您需要分别构建和运行它们(可能带有-d
分离模式的标志)。
在同一个容器中使用多个应用程序 - docker docs:
容器的主要运行进程是 Dockerfile 末尾的 ENTRYPOINT 和/或 CMD。通常建议您通过每个容器使用一项服务来分隔关注区域。该服务可能会分叉成多个进程(例如,Apache Web 服务器启动多个工作进程)。拥有多个进程是可以的,但要从 Docker 中获得最大收益,请避免一个容器负责整个应用程序的多个方面。您可以使用用户定义的网络和共享卷连接多个容器。
您可以创建一个脚本以在容器启动时运行,例如:
#!/bin/bash
# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_first_process: $status"
exit $status
fi
# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_second_process: $status"
exit $status
fi
# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container exits with an error
# if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds
while sleep 60; do
ps aux |grep my_first_process |grep -q -v grep
PROCESS_1_STATUS=$?
ps aux |grep my_second_process |grep -q -v grep
PROCESS_2_STATUS=$?
# If the greps above find anything, they exit with 0 status
# If they are not both 0, then something is wrong
if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
echo "One of the processes has already exited."
exit 1
fi
done
然后让你的 CMD 命令像这样运行脚本:
CMD ./my_wrapper_script.sh
Docker 在其文档中列出的另一个选项包括使用supervisord
which 应该使用适当的配置处理您打算在容器中运行的所有主要进程,这里是如何配置它。请记住,它是要安装在您的容器或基础映像上的另一个软件包。
此外,因为节点不只是从默认目录静态地提供网站文件,您需要使用node
命令并指向应该定义节点网络服务器以提供文件(如 express 或 http)的父 JS 文件,请参阅此示例。虽然如果你想使用生产网络服务器,你最好构建你的项目并使用像 nginx 或 apache http 这样的商业网络服务器,但你为他们构建项目(可能在 Dockerfile 中)将它们放在他们尊重的目录中并启动网络服务器进程,这是一个例子
推荐阅读
- python - 机器学习 - 寻找最好的汽车转售
- r - R dplyr 收集从宽到长的多列多个值
- c# - 如何在没有 ASP.NET 身份的情况下对 web api ASP.NET Framework 进行谷歌身份验证?
- ios - iOS - 状态栏中的效果
- ubuntu - E: 无法纠正问题,您持有破损的包裹
- python - 程序不会访问存储为 .txt 的登录名和密码,并允许使用 Tkinter 登录注册用户
- php - 从 jQuery/AJAX 和 PHP 文件返回特定数据
- javascript - .eslintrc.js 中的 env.es6=true 和 parserOptions.ecmaVersion=6 有什么区别?
- javascript - 了解箭头函数参数
- c - chroot() 和 clone() 不能正常工作