写点什么

【docker 总结】第七篇 - nodejs 项目部署

作者:Brave
  • 2021 年 12 月 19 日
  • 本文字数:8355 字

    阅读完需:约 27 分钟

node 项目部署


项目介绍

  • nodeapp 是一个用 Docker 搭建的本地 Node.js 应用开发与运行环境。

服务分类

  • db:使用 mariadb 作为应用的数据库(mariadb 开源版 MySql)

  • node:启动 node 服务

  • web:使用 nginx 作为应用的 web 服务器

app 目录结构

├── docker-compose.yml└── images    ├── nginx    │   └── config    │       └── default.conf    └── node        ├── Dockerfile        └── web            ├── package.json            ├── public            │   └── index.html            └── server.js
复制代码


创建项目


根据以上目录结构和服务的规划,创建项目

BravedeMacBook-Pro:~ brave$ mkdir docker-demoBravedeMacBook-Pro:~ brave$ cd docker-demoBravedeMacBook-Pro:docker-demo brave$ mkdir nodeappBravedeMacBook-Pro:docker-demo brave$ cd nodeapp/BravedeMacBook-Pro:nodeapp brave$ mkdir imagesBravedeMacBook-Pro:nodeapp brave$ touch docker-compose.ymlBravedeMacBook-Pro:nodeapp brave$ lsdocker-compose.yml	images
复制代码

docker-compose.yml 的命名是固定死的,每当执行 docker compose up 时,会去当前目录下找到 docker-compose.yml 文件去启动


镜像的种类

  • node 镜像(自己写)

  • nginx 镜像(直接用)

  • mysql 镜像(直接用)

BravedeMacBook-Pro:nodeapp brave$ cd imagesBravedeMacBook-Pro:images brave$ mkdir node   // node 镜像BravedeMacBook-Pro:images brave$ mkdir nginx	// 放 nginx 配置文件BravedeMacBook-Pro:images brave$ tree.|____nginx|____node   
复制代码

node 目录中创建 web 文件夹

BravedeMacBook-Pro:images brave$ cd nodeBravedeMacBook-Pro:node brave$ mkdir webBravedeMacBook-Pro:node brave$ cd web/
复制代码

前提:安装 node

BravedeMacBook-Pro:web brave$ npm -v6.14.6
复制代码

初始化 node 项目

BravedeMacBook-Pro:web brave$ npm init -yWrote to /Users/brave/docker-demo/nodeapp/images/node/web/package.json:
{ "name": "web", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC"}
╭───────────────────────────────────────────────────────────────╮ │ │ │ New major version of npm available! 6.14.6 → 8.3.0 │ │ Changelog: https://github.com/npm/cli/releases/tag/v8.3.0 │ │ Run npm install -g npm to update! │ │ │ ╰───────────────────────────────────────────────────────────────╯
复制代码

创建 server.js

vi server.js
let http = require('http');var mysql = require('mysql');var connection = mysql.createConnection({ host : 'db', user : 'root', password : '123456', database : 'nodeapp'});
connection.connect();http.createServer(function(req, res){ connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) { if (error) throw error; console.log('The solution is: ', results[0].solution); res.end("solution:" + results[0].solution) });}).listen(3000, function(){ console.log('node server started at port 3000');});
复制代码


安装 mysql

https://www.npmjs.com/package/mysql

// mysql 生产依赖BravedeMacBook-Pro:web brave$ npm install mysql -Snpm notice created a lockfile as package-lock.json. You should commit this file.npm WARN web@1.0.0 No descriptionnpm WARN web@1.0.0 No repository field.
+ mysql@2.18.1added 11 packages from 15 contributors and audited 11 packages in 14.514sfound 0 vulnerabilities
复制代码


添加 node 服务启动脚本:

vi package.json
{ "name": "web", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node server.js" // 启动脚本 }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "mysql": "^2.18.1" }}
复制代码

创建 public 目录,查看 nodeapp 项目目录结构:

BravedeMacBook-Pro:web brave$ mkdir publicBravedeMacBook-Pro:web brave$ cd public/
BravedeMacBook-Pro:public brave$ echo index.html > index.htmlBravedeMacBook-Pro:public brave$ lsindex.html
BravedeMacBook-Pro:public brave$ pwd/Users/brave/docker-demo/nodeapp/images/node/web/public
BravedeMacBook-Pro:public brave$ cd ..BravedeMacBook-Pro:web brave$ cd ..BravedeMacBook-Pro:node brave$ cd ..BravedeMacBook-Pro:images brave$ cd ..BravedeMacBook-Pro:nodeapp brave$ tree.|____docker-compose.yml|____images| |____nginx| |____node| | |____web| | | |____package.json| | | |____package-lock.json| | | |____public| | | | |____index.html| | | |____server.js
复制代码


访问静态页面,进入 public 目录

访问服务,进入 server.js 处理


服务写好了,我们需要将这个 node 服务制作成为一个镜像(mysql 和 nginx 使用现成的镜像就可以)


制作镜像

创建 DockerFile 文件

BravedeMacBook-Pro:nodeapp brave$ lsdocker-compose.yml	imagesBravedeMacBook-Pro:nodeapp brave$ cd images/BravedeMacBook-Pro:images brave$ cd node/BravedeMacBook-Pro:node brave$ vi Dockerfile
// DockerfileFrom node // 基于 node 镜像创建新镜像MAINTAINER Brave // 指定维护者COPY web /web // 拷贝项目:将当前项目中的 web 目录拷贝到镜像中// 注意文件拷贝规则:当/web 不存在时,会将web拷贝过去,如果存在/web 会将 web 放到/web 目录下WORKDIR /web // 指定工作目录为 webRUN npm install // 在编译镜像时执行的命令:安装依赖CMD npm start // 在运行容器时执行的命令:启动 node 服务 (docker run 时执行)
复制代码

回到 nodeapp 目录层级下,编写 docker-compose.yml

依赖关系:先启动 db 服务,再启动 node 服务,再启动 web 服务;

BravedeMacBook-Pro:node brave$ cd ..BravedeMacBook-Pro:images brave$ cd ..BravedeMacBook-Pro:nodeapp brave$ vi docker-compose.yml
// docker-compose.ymlversion: "2" // 版本号,注意冒号后面需要有一个空格,否则执行会报错services: // 声明服务 db: // db 服务 image: mariadb // 指定 db 服务使用的镜像 environment: // 设置环境变量 MYSQL_ROOT_PASSWORD: "123456" MYSQL_DATABASE: "nodeapp" MYSQL_USER: "root" MYSQL_PASSWORD: "123456" volumes: // 指定 db 服务使用的数据卷 - dbdata:/var/lib/mysql // 将容器的 /var/lib/mysql 映射到 宿主机的 dbdata 目录 node: // node 服务 build: // 需要构建镜像 镜像如果存在就不会编译了 需要加 --build context: "./images/node" // 指定构建的上下文,构建时,基于哪个文件夹作为上下文目录 dockerfile: Dockerfile // 会去找 ./images/node/Dockerfile 文件 depends_on: // 依赖的容器 - db web: image: nginx ports: - "8080:80" depends_on: // 依赖的容器 - node volumes: - "./images/nginx/conf.d:/etc/nginx/conf.d" // nginx 配置文件 - "./images/node/web/public:/public" // 静态文件volumes: // 声明数据卷 dbdata: driver: local
复制代码

编写 nginx 配置文件 conf.d/default.conf,配置静态/动态请求的处理规则

BravedeMacBook-Pro:nodeapp brave$ lsdocker-compose.yml	imagesBravedeMacBook-Pro:nodeapp brave$ cd images/BravedeMacBook-Pro:images brave$ cd nginx/BravedeMacBook-Pro:nginx brave$ mkdir conf.dBravedeMacBook-Pro:nginx brave$ cd conf.d/BravedeMacBook-Pro:conf.d brave$ vi default.conf
// default.confserver { listen 80; server_name localhost http://127.0.0.1; // 静态 location / { root /public; // 注意:nginx 容器的 /public 目录已经映射到宿主机的 ./images/node/web/public index index.html; } // 动态 location /api { // 以 /api 开头的请求 proxy_pass http://127.0.0.1:3000; // 为什么写http://node:3000 不行 }}
复制代码

查看当前目录结构:

BravedeMacBook-Pro:nodeapp brave$ tree.|____docker-compose.yml|____images| |____nginx| | |____conf.d| | | |____default.conf| |____node| | |____Dockerfile| | |____web| | | |____package.json| | | |____package-lock.json| | | |____public| | | | |____index.html| | | |____server.js| | | |____node_modules
复制代码

启动 docker compose:会先下载镜像,编译镜像,

docker compose updocker compose up --build  // 重新 build 否则修改不会生效
复制代码

备注:修改镜像后,需要重新编译才能生效

关闭防火墙,防火墙配置变更后需要重启 docker


centos:

systemctl stop firewalld.servicesystemctl disable firewalld.service
复制代码


BravedeMacBook-Pro:nodeapp brave$ docker compose up --build[+] Building 1.2s (9/9) FINISHED                                                                                                                                                    => [internal] load build definition from Dockerfile                                                                                                                          0.0s => => transferring dockerfile: 31B                                                                                                                                           0.0s => [internal] load .dockerignore                                                                                                                                             0.0s => => transferring context: 2B                                                                                                                                               0.0s => [internal] load metadata for docker.io/library/node:latest                                                                                                                1.0s => [internal] load build context                                                                                                                                             0.0s => => transferring context: 11.01kB                                                                                                                                          0.0s => [1/4] FROM docker.io/library/node@sha256:13621aa823b6b92572d19c08a75f7b1a061633089f37873f8b5bedb5e900e657                                                                 0.0s => CACHED [2/4] COPY web /web                                                                                                                                                0.0s => CACHED [3/4] WORKDIR /web                                                                                                                                                 0.0s => CACHED [4/4] RUN npm install                                                                                                                                              0.0s => exporting to image                                                                                                                                                        0.0s => => exporting layers                                                                                                                                                       0.0s => => writing image sha256:d0959f1669b0d14025f002e95fda0c78fb42fda35cfe6b7d9d32b889589b1e2c                                                                                  0.0s => => naming to docker.io/library/nodeapp_node                                                                                                                               0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them[+] Running 3/0 ⠿ Container nodeapp-web-1 Created 0.0s ⠿ Container nodeapp-db-1 Created 0.0s ⠿ Container nodeapp-node-1 Created 0.0sAttaching to nodeapp-db-1, nodeapp-node-1, nodeapp-web-1nodeapp-db-1 | 2021-12-15 12:20:07+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.6.5+maria~focal started.nodeapp-web-1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configurationnodeapp-web-1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/nodeapp-web-1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.shnodeapp-web-1 | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.confnodeapp-web-1 | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged versionnodeapp-web-1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.shnodeapp-web-1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.shnodeapp-web-1 | /docker-entrypoint.sh: Configuration complete; ready for start upnodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: using the "epoll" event methodnodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: nginx/1.21.4nodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) nodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: OS: Linux 5.10.76-linuxkitnodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576nodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: start worker processesnodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: start worker process 31nodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: start worker process 32nodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: start worker process 33nodeapp-web-1 | 2021/12/15 12:20:08 [notice] 1#1: start worker process 34nodeapp-db-1 | 2021-12-15 12:20:08+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'nodeapp-db-1 | 2021-12-15 12:20:08+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.6.5+maria~focal started.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] mariadbd (server 10.6.5-MariaDB-1:10.6.5+maria~focal) starting as process 1 ...nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Compressed tables use zlib 1.2.11nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Number of pools: 1nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Using crc32 + pclmulqdq instructionsnodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] mariadbd: O_TMPFILE is not supported on /tmp (disabling future attempts)nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Using Linux native AIOnodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Initializing buffer pool, total size = 134217728, chunk size = 134217728nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Completed initialization of buffer poolnodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: 128 rollback segments are active.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Creating shared tablespace for temporary tablesnodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: 10.6.5 started; log sequence number 42683; transaction id 14nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] Plugin 'FEEDBACK' is disabled.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_poolnodeapp-db-1 | 2021-12-15 12:20:08 0 [Warning] You need to use --log-bin to make --expire-logs-days or --binlog-expire-logs-seconds work.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] Server socket created on IP: '0.0.0.0'.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] Server socket created on IP: '::'.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] InnoDB: Buffer pool(s) load completed at 211215 12:20:08nodeapp-db-1 | 2021-12-15 12:20:08 0 [Warning] 'proxies_priv' entry '@% root@4fcb1b050b06' ignored in --skip-name-resolve mode.nodeapp-db-1 | 2021-12-15 12:20:08 0 [Note] mariadbd: ready for connections.nodeapp-db-1 | Version: '10.6.5-MariaDB-1:10.6.5+maria~focal' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distributionnodeapp-node-1 | nodeapp-node-1 | > web@1.0.0 startnodeapp-node-1 | > node server.jsnodeapp-node-1 | nodeapp-node-1 | node server started at port 3000
复制代码


测试动态,静态资源访问,链路是否通常(nginx->node->mysql):


动态:

// 通过 nginx 访问 node 服务BravedeMacBook-Pro:nodeapp brave$ curl http://localhost:8080/apisolution:2
复制代码

日志:

nodeapp-node-1  | The solution is:  2nodeapp-web-1   | 172.28.0.1 - - [15/Dec/2021:13:19:18 +0000] "GET /api HTTP/1.1" 200 20 "-" "curl/7.64.1" "-"
复制代码


访问静态资源 index.html:

、BravedeMacBook-Pro:nodeapp brave$ curl http://localhost:8080/index.htmlindex.html
复制代码

日志

nodeapp-web-1   | 172.28.0.1 - - [15/Dec/2021:13:20:48 +0000] "GET /index.html HTTP/1.1" 200 11 "-" "curl/7.64.1" "-"
复制代码


用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【docker 总结】第七篇 - nodejs项目部署