资讯专栏INFORMATION COLUMN

Node项目的Gitlab自动部署实践(基于Docker)

oysun / 1014人阅读

摘要:只要的项目有提交,相关就根据来决定是否跑自动部署的命令。项目的自动部署添加执行的注册命令,按照说明进行参数配置。至此,和服务都已经自动部署完成。

准备工作 说明

公司最近准备了一台新的开发服务器,正好用以实践docker的基本应用。docker的好处不再赘述,详情可参考阮一峰的这篇入门。(关于Docker最好的中文介绍,没有之一)。

公司目前主要使用了EggJs + ReactJS的技术组合,并且是前后端分离的。在使用docker以后,大致的部署方式如下:

环境

主机:阿里云

系统:CentOS 7.5

工具

Gitlab-Runner

Docker

Nginx

操作

在新购买的阿里云主机上(域名要准备好,映射到主机的IP上),直接用root用户键入以下命令:

root# yum install gitlab-ci-multi-runner
root# yum install docker
root# yum install nginx

以上三个命令,即已安装好所需的软件环境。余下任务均可交由docker和gitlab-runner完成。

本文略过的内容

gitlab的使用,看这里

Nginx的配置

nginx在安装完成后,需要对配置文件进行修改,添加要代理的端口设置。配置文件一般放在/etc/nginx/conf.d目录下。

在/etc/nginx/nginx.conf中,有这么一段代码:

...

include /etc/nginx/conf.d/*.conf;
...

意思是,所有在/etc/nginx/conf.d目录下的配置文件都会被自动载入。因此在该目录下加入一个配置文件如:service.conf。内容如下:

server {
  listen       80;
  server_name  your.website.com;  // 这里写你配置好的域名

  // api访问路径(http://your.website.com/api/test)
  location /api/test {
    proxy_http_version 1.1;
    client_max_body_size    100m;
    client_body_buffer_size 128k;
    proxy_send_timeout   300;
    proxy_read_timeout   300;
    proxy_buffer_size    4k;
    proxy_buffers     16 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_connect_timeout 30s;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:18001/;  // api的docker转发的内部端口
    proxy_set_header   Host   $host;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  // web访问路径(http://your.website.com/web/test)
  location /web/test {
    alias /data/www/test; // web项目文件放在此目录下,可自行配置为你自己的目录
    index index.html;
  }

  // gitlab访问路径(http://your.website.com/gitlab),
  location /gitlab {
    proxy_http_version 1.1;
    client_max_body_size    100m;
    client_body_buffer_size 128k;
    proxy_send_timeout   300;
    proxy_read_timeout   300;
    proxy_buffer_size    4k;
    proxy_buffers     16 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_connect_timeout 30s;
    proxy_pass http://127.0.0.1:15080/;  // gitlab的docker转发的内部端口
    proxy_set_header   Host   $host;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

conf配置完成后,重启nginx

root# service nginx restart
gitlab的安装和启动(使用Docker)

通过docker方式安装gitlab,比传统方式简单了不止100倍。只需简单两个命令即可开始使用:

安装
root# docker pull gitlab/gitlab-ce   // 这里安装的是ce版

这里没有指定版本,所以默认安装的是最新版。你可以在这里找到自己想要的版本并进行安装:

root# docker pull gitlab/gitlab-ce:11.3.3-ce.0
启动

使用简单一条命令,即可运行并使用gitlab。首先编辑启动脚本gitlab-start.sh,例如放在/srv/docker中:

#! /bin/bash

docker run --name gitlab 
  -d 
  --restart always 
  -p 15022:22   # 暴露给nginx的外部端口,
  -p 15080:80   # 暴露给nginx的外部端口(与上面的nginx配置要一致)
  -p 15433:433  # 暴露给nginx的外部端口,
  -v /srv/gitlab/config:/etc/gitlab   # gitlab的配置文件
  -v /srv/gitlab/logs:/var/log/gitlab  # gitlab的日志文件
  -v /srv/gitlab/data:/opt/lib/gitlab  # gitlab的数据文件
  gitlab/gitlab-ce

使用bash执行该shell文件,gitlab即可启动

root# bash /srv/docker/gitlab-start.sh

现在访问your.website.com/gitlab,应该就可以正常访问gitlab服务了。就是这么简单!

使用Gitlab-Runner自动部署

api项目和web项目的运行方式有所区别,所以runner也有所区别。

api项目 跑在docker容器中,仅需将文件拷贝进docker即可,执行器是shell类型

web项目 打包的静态文件需要docker环境,执行器是docker类型

web项目的自动部署 添加runner

执行runner的注册命令,按照说明进行参数配置

root# gitlab-ci-multi-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
# http://your.website.com/gitlab
Please enter the gitlab-ci token for this runner:
# xxxxxxxx    
Please enter the gitlab-ci description for this runner:
# web-deploy-runner
Please enter the gitlab-ci tags for this runner (comma separated):
# node-web-deploy
Registering runner... succeeded                     runner=avuSXASJ
Please enter the executor: docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine, docker:
# docker
Please enter the default Docker image (e.g. ruby:2.1):
# node:10
Runner registered successfully. Feel free to start it, but if it"s running already the config should be automatically reloaded!

说明

前2个分别是要求输入gitlab的url和对应的token,这两个信息在项目的Settings -> CI/CD -> Runners中有记录

第3个要求输入runner的名称

第4个是要求输入tags,runner通过项目gitlab-ci.yml中的tag标记来决定执行该CI过程。(见下一个步骤)

runner的executor指定是docker,所以最后一个要求输入docker的image,因为是node项目,指定该image为node:10(版本10的node,也可以指定其它版本)

添加完成后,runner就已经在服务中跑起来。只要gitlab的项目有提交,相关runner就根据tags来决定是否跑自动部署的命令。

添加.gitlab-ci.yml

在web项目的根目录下,添加.gitlab-ci.yml文件如下:

stages:
  - deploy

cache:
  key: ${CI_BUILD_REF_NAME}
  paths:
    - node_modules/

before_script:
  - export PATH=/usr/local/bin:$PATH
  - "which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )"
  - eval $(ssh-agent -s)
  - ssh-add <(echo "$SSH_PRIVATE_KEY")
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh
  - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts
  - "[[ -f /.dockerenv ]] && echo -e "Host *
	StrictHostKeyChecking no

" > ~/.ssh/config"

# dev分支构建
dev-deploy:
  stage: build
  tags:
    - node-web-deploy   # 这个是runner的tags内容
  only:
    - dev               # 仅仅dev分支会被对应的runner执行
  script:
    - npm install
    - npm run build     # web项目的打包命令
    - scp -r dist/* root@your.website.com:/data/www/test-dev  # 将打包好的dist拷贝到部署目录


#uat分支构建
uat-deploy:
  stage: build
  tags:
    - node-web-deploy   # 这个是runner的tags内容
  only:
    - uat               # 仅仅uat分支会被对应的runner执行
  script:
    - npm install
    - npm run build     # web项目的打包命令
    - scp -r dist/* root@your.website.com:/data/www/test-uat  # 将打包好的dist拷贝到部署目录

说明

文件中申明了两个部署过程,分别针对dev和uat两个分支,打包好以后拷贝到对应的部署目录(nginx已经映射,看上面的配置文件)

before_script部分,是为scp命令做的准备。因为是在docker内部打包,无法直接拷贝到宿主目录下,所以需要scp命令拷贝。

ssh的设置

如上说明2,因为是在docker内部打包,只能通过scp来拷贝打包好的文件到宿主目录下。因此需要配置SSH。

参考官方例子即可完成此步骤:

1. 生成SSH密钥

官方文档推荐使用ed25519类型的SSH,我仍然用的RSA方式

root# ssh-keygen -o -t rsa -b 4096 -C "root@your.website.com"

按照提示,一路点击Enter即可完成配置。记得:不要添加passphrase

2. 添加项目的Variables

在gitlab的项目设置(Settings -> CI/CD -> Variables)中,添加SSH_PRIVATE_KEY变量,变量的值为上一步生成的SSH密钥对的私钥

root# vi ~/.ssh/id_rsa   // 这里保存的就是私钥,拷贝到SSH_PRIVATE_KEY的value字段中

完成后,继续添加SSH_KNOWN_HOSTS变量,变量的值为以下命令的输出:

root# ssh-keyscan your.website.com
3. SSH免密设置

上面两步骤设置完成后,Runner运行时仍然会报错,原因就在于SSH登录虽然设置完成,但没有设置登录免密。免密登录的要点就在于,要将SSH密钥对的公钥导入到~/.ssh/authorized_keys文件中。

对于本次实践,gitlab-runner和gitlab其实是在同一台服务器上完成的。所以,将PUBLC_KEY导入到本地的authorized_keys文件中即可

root# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

做好以上3部,WEB项目的自动部署就算已经完成了。访问http://your.website.com/web/test 试试看,网页应该已经出来了。

api项目的自动部署 添加runner

执行runner的注册命令,按照说明进行参数配置。(具体说明见:web项目的自动部署)

root# gitlab-ci-multi-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
# http://your.website.com/gitlab
Please enter the gitlab-ci token for this runner:
# xxxxxxxx    
Please enter the gitlab-ci description for this runner:
# api-deploy-runner
Please enter the gitlab-ci tags for this runner (comma separated):
# node-api-deploy
Registering runner... succeeded                     runner=avuSXASJ
Please enter the executor: docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine, docker:
# shell
Runner registered successfully. Feel free to start it, but if it"s running already the config should be automatically reloaded!
添加.gitlab-ci.yml

在api项目的根目录下,添加.gitlab-ci.yml文件如下:

stages:
  - deploy

cache:
  key: ${CI_BUILD_REF_NAME}
  paths:
    - node_modules/

before_script:
  - export PATH=/usr/local/bin:$PATH
  - npm install

# ep-dev分支构建
deploy_dev:
  stage: deploy
  tags:
    - node-api-deploy
  only:
    - dev
  script:
    - sudo docker cp ./ api-test:/home/service
    - sudo docker restart api-test
    
# ep-release分支构建
deploy_uat:
  stage: deploy
  tags:
    - node-api-deploy
  only:
    - uat
  script:
    - sudo docker cp ./ api-test:/home/service
    - sudo docker restart api-test

说明

上面脚本使用了docker命令,将新文件拷贝到docker中并重启docker服务

添加docker服务

上面两部已经配置好了gitlab的CI/CD,CI/CD命令也提到要使用api项目对应的docker服务。这个docker服务需要我们提前打包一个image,docker里要跑的正是api服务所需要的环境。

1. 编辑Dockerfile

在api项目的根目录下,新增Dockerfile(没有后缀名)如下:

FROM node:10

RUN mkdir -p /home/service
WORKDIR /home/service

COPY . /home/service
RUN npm install

EXPOSE 8102

CMD ["npm", "start"]

说明

FROM 指使用的node环境对应的docker image

WORKDIR 指docker环境中的工作目录,执行的RUN命令都在此目录下执行

EXPOSE 指该api服务对外暴露的端口号,多个端口号可以写多个EXPOSE

CMD 则是docker在启动这个image时执行的命令,eggjs项目默认在工作目录下执行npm start

2. 打包docker

在根目录下,执行以下命令即可打包一个image

root# docker build -t lynx/test .

打包完成后,执行docker images即可看到打包完成的docker镜像。

3. 执行docker服务

与gitlab的使用方式类似,先编辑一个启动脚本/srv/docker/start-test.sh,内容如下:

#! /bin/bash

docker run -d --name nr-api-ep-dev 
  -p 18001:8102 
  -v /data/api/test/logs:/home/service/logs 
  lynx/test

使用bash执行该shell文件,node服务即可启动

root# bash /srv/docker/start-test.sh

启动后,执行docker ps可以查看已启动的docker任务列表。


至此,web和api服务都已经自动部署完成。

连接其它docker服务

在api服务中,一定会用到sql或redis等第三方的服务。一种方式是将这个服务安装到宿主环境中,另外一种方式是启动redis的docker服务,将服务请求连接(link)过来,(docker-compose方式本文没有涉及)。

使用redis

本文使用docker方式安装redis,并启动这个服务

root# docker pull redis  // 安装redis
root# docker run -d --name=redis -p 6379:6379 -v /srv/redis/data:/var/lib/redis redis:latest redis-server --appendonly yes  // 启动redis
api(Docker)连接redis(Docker)

如果api服务需要使用到redis,那么将redis的地址定义为127.0.0.1是达不到目的的,因为两个服务目前都是在docker环境中运行。

如上面的api的docker执行命令,加入--link选项

#! /bin/bash

docker run -d --name nr-api-ep-dev 
  -p 18001:8102 
  --link redis:redis 
  -v /data/api/test/logs:/home/service/logs 
  lynx/test

为了提供服务,docker运行中可以使用参数--link。注意,在link了以后api服务中如果要使用redis,服务的地址要改为redis,而不是127.0.0.1或者localhost

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/27593.html

相关文章

  • DockerGitLab CI 在前端工作流上实践分享(一)

    摘要:如今前端工程越来越复杂,打造一个好用的工作流也显得越来越重要。如果用户启动容器时指定了运行的命令,则会覆盖掉指定的命令。个人感觉在项目多协作人数多的情况下,还是很方便的。 showImg(https://segmentfault.com/img/remote/1460000011553749?w=1100&h=225); 如今前端工程越来越复杂,打造一个好用的工作流也显得越来越重要。本...

    wyk1184 评论0 收藏0
  • DockerGitLab CI 在前端工作流上实践分享(一)

    摘要:如今前端工程越来越复杂,打造一个好用的工作流也显得越来越重要。如果用户启动容器时指定了运行的命令,则会覆盖掉指定的命令。个人感觉在项目多协作人数多的情况下,还是很方便的。 showImg(https://segmentfault.com/img/remote/1460000011553749?w=1100&h=225); 如今前端工程越来越复杂,打造一个好用的工作流也显得越来越重要。本...

    godruoyi 评论0 收藏0
  • GitLab CI/CD 在 Node.js 项目实践

    摘要:近期在按照业务划分项目时,我们组被分了好多的项目过来,大量的是基于的,也是我们组持续在使用的语言。部署环境强依赖本地,因为需要在本地建立仓库的临时目录,并经过多次的方式完成部署上线的操作。 近期在按照业务划分项目时,我们组被分了好多的项目过来,大量的是基于 Node.js 的,也是我们组持续在使用的语言。 现有流程中的一些问题 在维护多个项目的时候,会暴露出一些问题: 如何有效的使用...

    Profeel 评论0 收藏0
  • Docker + Jenkins + webhooks 自动部署基础实践

    摘要:自动部署基础实践熟悉的基本操作实现本地后自动构建部署服务此实践用于优化自己在实际工作中的工作流在本地开发到服务器登录云服务器或者简化流程后本地开发云服务器自动构建部署本实践将结合技术来实现云服务器对各种环境的切换与部署。 Docker + Jenkins + webhooks 自动部署基础实践 熟悉 jenkins 的基本操作 ☑️ 实现本地 git push 后 jenkins 自...

    Charlie_Jade 评论0 收藏0
  • Kubernetes如何加速UCloud内部代码部署CI/CD流程

    摘要:内部长期使用来管理代码。审核通过并且成功后,触发静态测试单元测试镜像构建镜像部署集成测试等测试通过后,创建一个从到的,由负责人进行审核。从图中我们可以看到,部分是一个单元测试,预发布部署,集成测试,,提交代码的循环过程。UCloud内部长期使用 Gitlab 来管理代码。虽然Gitlab作为一套开源平台已很优秀,但我们对于其能为CI/CD提供的敏捷性并不十分满意,内部实践中的代码发布周期仍需...

    gougoujiang 评论0 收藏0

发表评论

0条评论

oysun

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<