使用Docker自动化Angular和Nginx

这是从前一段时间开始的,我们必须重新构建持续的交付管道,以使其更具功能性,而不是将所有东西捆绑在一起。 由于我们执行了许多并行构建功能以及专门与管道ssh绑定到部署服务器并触发伪自动拉取和部署的部署方法,因此我们陷入了许多Jenkins管道的困境。

我们的旧管道就是这样

  1. 建立NPM
  2. 测试源代码
  3. 构建生产版本
  4. 压缩并上传到s3
  5. ssh进入服务器拉并解压

阅读本文的许多人会发现此交付周期中的一些问题。 即4&5。这意味着我们依靠4个故障点

  1. 如果包装没有正确压缩怎么办?
  2. 如果网络丢弃数据包或完全丢弃该怎么办?
  3. 如果ssh失败怎么办?
  4. 如果下载和解压缩失败怎么办?

有人可能会说,好的,为什么不雇用特定的开发工程师并完成工作并让他们维护它。 好吧,我们是一家初创公司,所以我们尝试自己做一切,谁不喜欢挑战。

因此,我们开始了新的发布周期,并希望一劳永逸地解决这个问题。 我们还想借此机会删除服务器上所需的任何要求和维护,例如证书更新和nginx配置,因此我们开始使用docker。


我将假设,如果您正在阅读本文,您已经拥有詹金斯。 我们还提供了Blue Ocean插件(如果您自己关注此插件,则需要此插件)。 如果没有,请转到Jenkins>管理插件> blue ocean。 安装所有必需的蓝色海洋。 我们全神贯注地安装了标题中所有带有名称的内容。

连接到Github

确保您的蓝海连接到您的GitHub帐户(我以GitHub为例,还有其他集成),还将您的管道配置为每5分钟轮询一次(或者您希望默认为长时间不进行轮询,所以手动单击)扫描和进度)

准备代码库

我们需要在这里准备代码库。 您可以进入并使用可视管道编辑器来创建管道,但是我们发现将一个名为Jenkinsfile的文件插入项目的根目录已足够并且容易得多。

Jenkins文件的内容(在下面说明)

 管道{代理任何工具{nodejs“ 815Node”}}环境{注册表='dockerhubusername / dockerhubusername'RegistryCredential ='dockerhubcredentials'}阶段{stage('INSTALL PACKAGES'){步骤{sh“ npm install”}} stage('TEST' { dockerImageBuild = docker.build注册表+“:latest”}}} stage(“ DEPLOY DOCKER”){步骤{脚本{docker {with.Registry(“,RegistryCredential){dockerImageBuild.push()}}}} stage(” DEPLOY& ACTIVATE“){步骤{回显'这部分会因设置而异'}}}} 

这将处理詹金斯部分中的流水线。 我将解释每个部分。

  1. 代理,我们使用任何代理,但您可以定义要建立的特定代理。 我们尝试使用docker容器进行构建,但这只会增加更多的开销。
  2. 工具,这是我们用来代替代理的工具,我们特别需要内置的Jenkins nodejs配置。 可以在Jenkins>全局工具配置> Nodejs中设置。 下图应说明815Node引用的来源。

3.环境,请确保HOME变量维护您的工作目录,因为这可能会导致错误。 注册表是您的Docker Hub存储库username/repo存储库约定始终保留的地方。 注册表凭据是对登录名的全局引用,可以在Jenkins>凭据(左侧菜单)>全局>添加凭据中设置

4.阶段,这些管道中详细介绍了每个阶段

其余的内容应该可以从上面的Jenkinsfile中很好地读取,并且可以轻松地与您要执行的操作交互。 请不要使用全局npm软件包, node_modules/.bin请尝试使用node_modules/.bin文件夹中的项目,否则您将遇到权限错误。

请注意,您可能会从Groovy中看到错误

可以通过转到Jenkins>管理Jenkins>处理中脚本批准来解决其中的一些错误。 这是运行此Jenkinsfile的照片。


Docker文件

正如您从Jenkinsfile中注意到的那样,我们正在编译我们的angular应用的正式版,这会将构建默认添加到dist文件夹中。 如果您使用其他dist文件夹,请根据需要更新代码。

我们还拆分了一个nginx.conf文件,可以在下面找到它

nginx.conf

 服务器{收听80; 
server_name your_specific_domain_name.com;
返回301 https:// $ server_name $ request_uri;
}服务器{听443;
server_name your_specific_domain_name.com;
根/ var / www /;
索引index.html;
ssl on;
ssl_certificate /var/certificates/specific.domain.name.com.crt
ssl_certificate_key /var/certificates/specific.domain.name.com.key;
位置/ {try_files $ uri /index.html; }}

您会注意到我们已经添加了SSL证书,而docker将会在构建docker时复制这些证书。 另外,特定于度的路由(例如try_files)将所有内容都路由到index.html。

Docker文件

 从nginx:stableCOPY ./dist/ / var / www 
COPY ./certificates/ / var / certificates
复制./nginx.conf /etc/nginx/conf.d/default.conf

这就对了。 它是如此简单。 因此,请确保您使用的是SSL,请确保您的密钥和证书位于项目根目录中的一个名为“证书”的文件夹中,或者根据需要进行修改。

使用以下命令进行构建

docker build -t username/repository .

使用它运行它(您既需要使ssl正常工作,又需要端口80重定向到https)

docker run -d -p 80:80 username/repository && docker run -d -p 443:443 username/repository


为什么

我们拥有专用服务器和云的混合结构。 我们确实使用了S3,尽管它同样起作用,但我们还是希望对文件的传递进行更多控制,并希望通过服务器捕获社交媒体共享并以不同的方式呈现(有关此内容的另一个故事即将推出)。 我们发现拥有一个可以控制到服务器级别的实例比静态交付更为重要。 我们仍然使用云文件进行部署以提供我们的静态文件,但这更适合我们的范例。

部署

我们使用构建的软件进行部署,该软件是Ubuntu映像的一部分,我们在与中央“ Hive”通信的计算机之间分发,然后,我们的构建过程进行通信,以告知服务器下载并运行这些构建。 我们计划将这一过程作为一个开源映像发布,但是目前它是非常alpha版本,因此被忽略了。