Node 项目从构建到使用 Jenkins 与 Docker 实现自动化部署


这都 2019 年末了,你还不会 Docker 吗? 你 low 爆了,我们作为一枚前端,不能说是要精通使用 Docker 完成各种事情,但我觉得必须要学会使用 Docker 干下面几件事:
  • 部署前端应用
  • 部署 Nginx
  • 使用 docker-compose 部署
  • 在容器之间建立联系


Docker 可理解为跑在宿主机上的非常精简、小巧、高度浓缩的虚拟机。 它可以将容器里的进程安稳的在宿主机上运行,之前有很多关于 Docker 的文章,在这我就不做过多的介绍了,接下来我们通过项目来了解并使用 Docker。

Egg.js ?

在这里我使用 Egg.js 来为大家实操一下项目的部署流程。有人会问 Egg.js 是什么? 我只能回答这是一款专业级的 Node 框架。作为一个有梦想的前端,我们有必要去学习一种后端语言,而作为前端 Node 的学习成本相对来说比较低的。 Egg.js 这个框架在 Node 现有框架中也是比较优秀的,如有需要,大家可以自行学习,我们今天的学习主要还是项目的部署流程,在这我就不给大家做过多的介绍。如有需要,请查阅官方文档

开始前的准备

Docker 与 docker-compose 的安装我就不给大家介绍了。在之前的文章中是有的,也比较详细,作为一位开发人员,我认为这点事情难不倒大家。

初始化项目

$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i

创建需要的文件

我们需要在项目根目录创建我们所需要的文件:
$ touch Dockerfile
$ touch docker-compose.yml
$ setup.sh

目录结构

egg-project
├── package.json
├── setup.sh(新建)
├── Dockerfile(新建)
├── docker-compose.yml(新建)
├── app
|   ├── router.js
│   ├── controller
│   |   └── home.js
│   ├── service(可选)
│   |   └── user.js
│   ├── middleware(可选)
│   |   └── response_time.js
│   ├── schedule(可选)
│   |   └── my_task.js

...

常用指令

在开始之前我们要学习下常用的一些指令,看下方:
1.png

了解流程

2.png

安装 Jenkins

在安装 Jenkins 我选择了使用 docker-compose。

docker-compose 是一个用来把 Docker 自动化的东西 。

有了 docker-compose 你可以把所有繁复的 Docker 操作全都一条命令,自动化的完成。

首先我们需要在服务器上创建一个目录机构(具体结构个人自行创建):
/home/jenkins
 - docker-compose.yml
 - jenkins-home

接下来我们来编写 docker-compose.yml 安装 Jenkins:
version: '3'                                    # 指定 docker-compose.yml 文件的写法格式
services:                                       # 多个容器集合
docker_jenkins: 
user: root                                  # 为了避免一些权限问题 在这我使用了root
restart: always                             # 重启方式
image: jenkins/jenkins:lts                  # 指定服务所使用的镜像 在这里我选择了 LTS(长期支持)
container_name: jenkins                     # 容器名称
ports:                                      # 对外暴露的端口定义
  - '8080:8080'
  - '50000:50000'
volumes:                                    # 卷挂载路径
  - /home/jenkins/jenkins_home/:/var/jenkins_home   # 这是我们一开始创建的目录挂载到容器内的 jenkins_home 目录
  - /var/run/docker.sock:/var/run/docker.sock
  - /usr/bin/docker:/usr/bin/docker                 # 这是为了我们可以在容器内使用 Docker 命令
  - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose     # 同样的这是为了使用 docker-compose命令

我们需要进入到 Jenkins 目录下执行:
$ docker-compose up -d

配置:

不出意外你现在可以打开你的服务器地址 http://xxxxxxx: 端口号就能看到这个界面:
3.png

打开你所创建的 Jenkins 目录进入到 jenkins-home:
/home/jenkins/jenkins-home

4.png

进入 secrets 目录:
$ cat initialAdminPassword

5.png

然后把里面的文本复制出来填到管理员密码中:
6.png

7.png

接下来需要安装两个插件:
NodeJS Plugin
Publish Over SSH

8.png

9.png

然后我们滑到最下方:
10.png

11.png

12.png

13.png

开始我们的操作

Dockerfile

我们在开始阶段的时候学过一些常用指令,大家应该一眼就可以看得懂这些命令。 加油!!
FROM node:10.0-alpine             # 镜像版本

# 设置时区
RUN apk --update add tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& apk del tzdata

# 创建 app 目录
RUN mkdir -p /usr/src/node-app/egg-santak

# 设置工作目录
WORKDIR /usr/src/node-app/egg-santak

# 拷贝 package.json 文件到工作目录
# !!重要:package.json 需要单独添加。
# Docker 在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。
# 如果 package.json 和源代码一起添加到镜像,则每次修改源码都需要重新安装 npm 模块,这样木有必要。
# 所以,正确的顺序是:添加 package.json;安装 npm 模块;添加源代码。
COPY package.json /usr/src/node-app/egg-santak/package.json

# 安装 npm 依赖(使用淘宝的镜像源)
# 如果使用的境外服务器,无需使用淘宝的镜像源,即改为 `RUN npm i`。
RUN npm i --registry=https://registry.npm.taobao.org

# 拷贝所有源代码到工作目录
COPY . /usr/src/node-app/egg-santak

# 暴露容器端口
EXPOSE 7001

# 启动 Node 应用
CMD npm start

在服务器中创建我们所需要挂载的数据卷

14.png

# nginx
$ mkdir -p nginx/conf.d nginx/logs

# mysql
$ mkdir mysql

# redis
$ mkdir redis

然后进入 nginx/conf.d 文件夹中,创建一个后缀为 conf 的文件:
$ cd nginx/conf.d
$ touch default.conf
$ vim default.conf

写入以下内容:
server {
listen 80;
listen [::]:80;
server_tokens off;

root /var/www/html;
index index.html index.htm;

# 修改为自己的域名
server_name api.lovelp.xin;

# 访问 / 路径时执行反向代理
location / {
# 这里 nodejs 是 node 容器名
proxy_pass http://nodejs:7001;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
# 后端的 Web 服务器可以通过 X-Forwarded-For 获取用户真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 允许客户端请求的最大单文件字节数
client_max_body_size 15M;
# 缓冲区代理缓冲用户端请求的最大字节数
client_body_buffer_size 128k;
}


docker-compose.yml

version: '3'

services:
santak_redis:
image: redis:3                  # 指定服务镜像
container_name: santak_redis    # 容器名称
restart: always                 # 重启方式
hostname: redis
command: redis-server /usr/local/etc/redis/redis.conf --requirepass 123456  --appendonly yes
volumes:                        # 挂载数据卷
  - /root/redis/redis.conf:/usr/local/etc/redis/redis.conf
ports:                          # 映射端口
  - "6379:6379"     
networks:                       # 加入指定网络
  - app-network

santak_nginx:
image: nginx:stable-alpine      # 指定服务镜像
container_name: santak_nginx    # 容器名称
restart: always                 # 重启方式
ports:                          # 映射端口
  - "80:80"
volumes:                        # 挂载数据卷
  - /etc/localtime:/etc/localtime
  - /root/nginx/conf.d:/etc/nginx/conf.d
  - /root/nginx/logs:/var/log/nginx
depends_on:                     # 启动顺序
  - nodejs
networks:                       # 加入指定网络
  - app-network

santak_mysql:
image: mysql:5.7
container_name: santak_mysql
restart: always
ports:                          # 映射端口
  - "3306:3306"
environment:
  - MYSQL_ROOT_PASSWORD=root
  - MYSQL_USER=lovelp           # 创建 lovelp 用户
  - MYSQL_PASSWORD=mm123321     # 设置 lovelp 用户的密码
  - MYSQL_DATABASE=santak       # 创建初始数据库
  - TZ=Asia/Shanghai            # 设置时区
volumes:                        # 挂载数据卷
  - /root/mysql:/var/lib/mysql  # 为了数据持久化
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
networks:                       # 加入指定网络
  - app-network 

nodejs:
build:                          # 这里指的是我们刚刚撸的 Dockerfile 文件
  context: .                    
  dockerfile: Dockerfile
image: nodejs                   # 镜像名称
container_name: nodejs          # 容器名称
restart: always                 # 重启方式
depends_on:                     # 启动顺序
  - santak_redis
  - santak_mysql
links:                          # 容器连接
  - santak_redis:santak_redis
  - santak_mysql:santak_mysql
networks:                       # 加入指定网络
  - app-network

volumes:
certbot-etc:
certbot-var:

networks:  # 实现通信
app-network:
driver: bridge

在项目中的使用

15.png

setup.sh

#!/usr/bin/env bash
#image_version=`date +%Y%m%d%H%M`;

# 关闭容器
docker-compose stop || true;
# 删除容器
docker-compose down || true;
# 构建镜像
docker-compose build;
# 启动并后台运行
docker-compose up -d;
# 查看日志
docker logs nodejs;
# 对空间进行自动清理
docker system prune -a -f

Jenkins 创建项目

16.png

17.png

18.png

19.png

最后我们就可以愉快的 Build Now 了:
20.png

在这里我选择的是手动构建。其实 Jenkins 有很多可配置项,比如自动化构建啥的,兴趣使然,大家自行摸索,谢谢大家。

原文链接:https://juejin.im/post/5dde46b2e51d4554350715f5

0 个评论

要回复文章请先登录注册