百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

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

toqiye 2024-09-04 20:06 14 浏览 0 评论

概述

这都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

...

常用指令

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

了解流程

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

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

进入 secrets 目录

$ cat initialAdminPassword

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

接下来需要安装两个插件

NodeJS Plugin
Publish Over SSH

然后我们滑到最下方

开始我们的操作

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

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

# 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

在项目中的使用

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

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

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

结尾

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

相关推荐

在Vue中使用JSX,很easy的

?此账号为华为云开发者社区官方运营账号,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态本文分享自华为云社区《在Vue中如何使用JSX,就这么简单!【建议收藏】》,...

深度学习走进死胡同了?

人工智能真正的前路究竟在何方?今天的话题很大,咱们先从浅显的环节入手。深度学习“教父”、在世科学家中的翘楚GeoffreyHinton曾在2016年多伦多召开的一场AI大会上坦言,“放射...

“信息引导”超全总结,让你的设计有理有据

讲信息引导方式的有很多,而本文主要从“是否会打扰用户”的维度,分两个类型举例分析了其中的设计以及原理。上一篇讲了信息引导的策略层:可切入的场景和机制《系统性地教你:如何设计产品的信息引导?》。这篇就总...

Blazor 全屏按钮/全屏服务 (BootstrapBlazor组件库)

Blazor简介Blazor是一个使用.NET生成的交互式客户端WebUI的框架。和前端同学所熟知的Vue、React、Angular有巨大差异。其最大的特色是使用C#代码(理论...

一起学Vue:UI框架(element-ui)

目标使用Vue+ElementUI构建一个非常简单CRUD应用程序,以便您更好地了解它的工作方式。效果页面比如我们要实现这样列表、新增、编辑三个页面:列表页面新增页面编辑页面安装element我们使用...

在Vue.js + Element UI的表格中优雅地实现图片放大功能

引言在Web应用中,表格常常用于展示数据集,而图片则是数据可视化的重要组成部分。为了提升用户体验,我们通常需要允许用户在不跳转页面的情况下,直接从表格中查看图片的原始尺寸。本文将引导你通过Vue.js...

Element-ui简单使用

什么是Element-ui?根据官网的说法,Element-ui,是一套为开发者、设计师和产品经理准备的基于Vue2.0的由饿了么公司出品的桌面端组件库。官网:https://element.ele...

极致舒适的Vue弹窗使用方案

一个Hook让你体验极致舒适的Dialog使用方式!Dialog地狱为啥是地狱?因为凡是有Dialog出现的页面,其代码绝对优雅不起来!因为一旦你在也个组件中引入Dialog,就最少需要额外维护一个v...

VUE3+ts开发弹出框插件

1.插件页面代码取消确认˂...

十分钟,让你学会Vue的这些巧妙冷技巧

前言写了两年的Vue,期间学习到好几个提高开发效率和性能的技巧,现在把这些技巧用文章的形式总结下来。1.巧用$attrs和$listeners$attrs用于记录从父组件传入子组件的所有不被prop...

element的嵌套dialog,在打开第二个dialog的时候会被遮罩层遮住

在一个弹出层的内容区做处理打开另一个弹出层时,第二个弹出层会被遮罩层遮住。对于确实需要嵌套Dialog的场景,提供了append-to-body属性。将内层Dialog的该属性设置为true...

无代码平台之自定义组件

无代码平台就是一个一个的组件当成积木,通过拖拉拽的方式搭建起来,构建自己的应用。前端有前端组件,如果不够自己增加组件,后端有后端的组件,如果不够自己增加组件,用统一的组件间传参、组件穿透、前后端穿透等...

Tailwindcss 入门

是什么?Tailwindcss是一个功能类优先的CSS框架,通过flex,pt-4,text-center和rotate-90这种原子类组合快速构建网站,而不需要离开你的HTML。...

推荐一款比flex更强大的CSS布局——Grid布局

flex布局是一维布局Grid布局是二维布局flex布局一次只能处理一个维度上的元素布局,一行或者一列Grid布局是将容器划分成了“行”和“列”,产生了一个个的网格。Grid基础display...

前端入门——css 网格轨道详细介绍

上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...

取消回复欢迎 发表评论: