公司最近准备了一台新的开发服务器,正好用以实践docker的基本应用。docker的好处再也不赘述,详情可参考阮一峰的这篇入门。(关于Docker最好的中文介绍,没有之一)。html
公司目前主要使用了EggJs + ReactJS的技术组合,而且是先后端分离的。在使用docker之后,大体的部署方式以下:node
在新购买的阿里云主机上(域名要准备好,映射到主机的IP上),直接用root用户键入如下命令:nginx
root# yum install gitlab-ci-multi-runner root# yum install docker root# yum install nginx
以上三个命令,即已安装好所需的软件环境。余下任务都可交由docker和gitlab-runner完成。git
nginx在安装完成后,须要对配置文件进行修改,添加要代理的端口设置。配置文件通常放在/etc/nginx/conf.d目录下。web
在/etc/nginx/nginx.conf中,有这么一段代码:redis
... include /etc/nginx/conf.d/*.conf; ...
意思是,全部在/etc/nginx/conf.d目录下的配置文件都会被自动载入。所以在该目录下加入一个配置文件如:service.conf。内容以下:sql
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配置完成后,重启nginxdocker
root# service nginx restart
经过docker方式安装gitlab,比传统方式简单了不止100倍。只需简单两个命令便可开始使用:shell
root# docker pull gitlab/gitlab-ce // 这里安装的是ce版
这里没有指定版本,因此默认安装的是最新版。你能够在这里找到本身想要的版本并进行安装:npm
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服务了。就是这么简单!
api项目和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!
说明
添加完成后,runner就已经在服务中跑起来。只要gitlab的项目有提交,相关runner就根据tags来决定是否跑自动部署的命令。
在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 *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.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拷贝到部署目录
说明
如上说明2,由于是在docker内部打包,只能经过scp来拷贝打包好的文件到宿主目录下。所以须要配置SSH。
参考官方例子便可完成此步骤:
官方文档推荐使用ed25519类型的SSH,我仍然用的RSA方式
root# ssh-keygen -o -t rsa -b 4096 -C "root@your.website.com"
按照提示,一路点击Enter便可完成配置。记得:不要添加passphrase。
在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
上面两步骤设置完成后,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 试试看,网页应该已经出来了。
执行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!
在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
说明
上面两部已经配置好了gitlab的CI/CD,CI/CD命令也提到要使用api项目对应的docker服务。这个docker服务须要咱们提早打包一个image,docker里要跑的正是api服务所须要的环境。
在api项目的根目录下,新增Dockerfile(没有后缀名)以下:
FROM node:10 RUN mkdir -p /home/service WORKDIR /home/service COPY . /home/service RUN npm install EXPOSE 8102 CMD ["npm", "start"]
说明
在根目录下,执行如下命令便可打包一个image
root# docker build -t lynx/test .
打包完成后,执行docker images便可看到打包完成的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服务都已经自动部署完成。
在api服务中,必定会用到sql或redis等第三方的服务。一种方式是将这个服务安装到宿主环境中,另一种方式是启动redis的docker服务,将服务请求链接(link)过来,(docker-compose方式本文没有涉及)。
本文使用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服务须要使用到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