23

node 项目从构建到使用 jenkins + docker + nginx + mysql + redis 自动化部署

 4 years ago
source link: https://juejin.im/post/5dde46b2e51d4554350715f5
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
2019年11月28日阅读 9124

node 项目从构建到使用 jenkins + docker + nginx + mysql + redis 自动化部署

这都2019年末了,你还不会 docker吗? 你 low 爆了,我们作为一枚前端,不能说是要精通使用 docker 完成各种事情,但我觉得必须要学会使用 docker 干下面几件事:

  1. 部署前端应用
  2. 部署nginx
  3. 使用docker-compose部署
  4. 在容器之间建立联系

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


1

安装 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:端口号 就能看到这个界面:

1

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

1

进入 secrets 目录

$ cat initialAdminPassword
复制代码


1

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

1
1

接下来需要安装两个插件

NodeJS Plugin
Publish Over SSH
复制代码


1
1

然后我们滑到最下方

1
1
1
1

开始我们的操作

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
复制代码

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

1
# 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
复制代码

在项目中的使用

1

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 创建项目

1


1


1


1

最后我们就可以愉快的 Build Now

1

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

如有不明白的地方,请大家下方留言,我看到后会及时回复的。如果你认为写的还算是可以,请留个赞表示下支持,谢谢!!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK