如果您想了解使用PM2在Docker上部署Node.jsWeb应用和pm2-docker的知识,那么本篇文章将是您的不二之选。我们将深入剖析使用PM2在Docker上部署Node.jsWeb应用的各个
如果您想了解使用 PM2 在 Docker 上部署 Node.js Web 应用和pm2-docker的知识,那么本篇文章将是您的不二之选。我们将深入剖析使用 PM2 在 Docker 上部署 Node.js Web 应用的各个方面,并为您解答pm2-docker的疑在这篇文章中,我们将为您介绍使用 PM2 在 Docker 上部署 Node.js Web 应用的相关知识,同时也会详细的解释pm2-docker的运用方法,并给出实际的案例分析,希望能帮助到您!
本文目录一览:- 使用 PM2 在 Docker 上部署 Node.js Web 应用(pm2-docker)
- Docker - 入门(二),docker&nodeJs制作镜像与本地部署
- Docker+Jenkins+Nodejs+Git+Webhook自动部署
- docker-node-pm2-sails.js启动传递环境参数
- Docker: 编写 dockerfile 启动 node.js 应用
使用 PM2 在 Docker 上部署 Node.js Web 应用(pm2-docker)
背景
本文介绍 PM2 在 Docker 上部署 Node.js Web 应用。
- PM2 是守护进程管理器,它将帮助您管理和保持 Nodejs 应用程序 24/7 在线。
- Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker 允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。
一,项目初始化
新建项目 docker-nodejs-pm2-demo
,目录结构说明如下:
.
|-- Dockerfile # Docker 构建配置
|-- README.md
|-- app.js # Nodejs 应用入口
|-- ecosystem.config.js # pm2 配置文件
复制
二,Nodejs 应用
Nodejs
Web 应用入口 app.js
文件内容。点击查看
const http = require(''http'');
http.createServer((request, response) => {
response.writeHead(200, {''Content-Type'': ''text/plain''});
response.end(''Docker-nodejs-pm2-demo, Hello World!'');
}).listen(8080);
复制
三,PM2 配置
PM2
配置文件 ecosystem.config.js
内容。点击查看
module.exports = {
apps : [{
name: "docker-nodejs-pm2-demo",
script: "./app.js",
instances: 1,
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
},
exec_mode: ''cluster'',
combine_logs: true,
out_file: ''/dev/null''
}]
}
复制
四,Dockerfile
Docker
配置文件 Dockerfile
内容。点击查看
FROM keymetrics/pm2
# 暴露端口
EXPOSE 8080
WORKDIR /data/release/docker-nodejs-pm2-demo
# 创建目录
RUN mkdir -p /data/release/docker-nodejs-pm2-demo
# 复制源码
COPY . /data/release/docker-nodejs-pm2-demo
# 容器启动时,启动应用服务
CMD ["pm2-runtime", "ecosystem.config.js", "--only", "docker-nodejs-pm2-demo"]
复制
五,Docker 部署应用
5.1. 获取源代码
文章中的示列源码托管到 Github
,可直接克隆使用。点击查看
# clone 项目
$ git clone https://github.com/yorkiyu/docker-nodejs-pm2-demo.git
# 进入项目目录
$ cd docker-nodejs-pm2-demo
# 构建镜像
$ docker build -t docker-nodejs-pm2-demo:2 .
# 查看镜像
$ docker images
复制

5.2. 启动容器
# 启动容器,指定容器中的端口 8080 与宿主机的端口 8080 绑定
$ docker run -d -p 8080:8080 docker-nodejs-pm2-demo:2
# 查看容器
$ docker ps
复制

5.3. 进入容器
# 进入容器
$ docker exec -it 61288ea7784f sh
# 在容器中查看 pm2 进程
$ pm2 ls
复制

5.4. 访问应用
使用 curl
访问 Nodejs
Web 应用。点击查看 curl 教程
$ curl -v http://127.0.0.1:8080
复制

参考
- [1] Docker部署nodejs应用并使用PM2作为守护进程
- [2] PM2 Documentation
- [3] Docker Documentation
Docker - 入门(二),docker&nodeJs制作镜像与本地部署
在熟悉docker基本命令与运作逻辑后,尝试实战。
目标:制作一个nodejs服务镜像,并使用nginx反向代理,在本地跑通。
本次项目配置与工具构成:
- node后端:使用阿里的 Egg.js 脚手架
- db:mongodb
- nginx
-
NoSqlBooster for MongoDB
,一个mongodb可视化工具 -
postman
一个可以发起网络请求的工具,用于测试
注:本机操作系统为 macOS
本文主讲docker部分,其余知识面仅描述部分
准备工作:
- docker镜像:nginx:latest、node:10.15.3、mongo:latest
- docker-compose可用
- Egg.js脚手架初始化后端项目,命名为
egg-center
项目配置
Egg.js
安装egg-mongoose
库,以便连接mongodb。
数据库配置,修改./config/config.default.js
config.mongoose = {
clients: {
center: {
url: ''mongodb://你本地的内网ip:27017/example'',
options: {
dbName: ''center'', // 数据库名,自己取
user: '''', // 连接数据库的账号,默认为空
pass: '''', // 连接数据库的账号,默认为空
}
}
}
}
接下来写一个后台用户管理系统
在 ./app/controller 下新增对应的控制器、在./app/model下新增对应的表结构。
然后写几个简单的接口,修改:./app/router.js,定义路由:
''use strict''
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller } = app
router.get(''/'', controller.home.index)
/* 新增用户 */
router.post(''/api/admin/user'', controller.admin.user.create)
/* 用户列表 */
router.get(''/api/admin/user'', controller.admin.user.index)
...略
}
本地启动服务测试: npm run dev
本地使用 postman
调通接口,造些测试数据。
修改package.json
"start": "egg-scripts start --deamon --title=egg-server-egg-center",
修改为:
"start": "egg-scripts start --title=egg-server-egg-center",
删除出--deamon
,我们是在docker里跑项目,所以需要node服务跑在docker前台。
配置Dockerfile
Egg.js根目录(./)下新增文件:
-
Dockerfile
// Egg.js镜像制作的配置文件 -
docker-compose.yml
// Egg.js和nginx容器的配置 -
mongodb-compose.yml
// mongodb容器的配置 -
nginx.conf
// nginx配置文件
我们本次部署不使用jenkins,采用较为简单的部署方式。
解释下为什么要把mongodb的配置单独写:
1.绝大部分情况,数据库都是不关闭的,而业务服务器和nginx是会随着版本迭代等影响重启,所以将mongodb的配置单独拎出来
2.业务服务会依赖mongodb启动,若写在同一个docker-compose文件里会出现异步问题,即mongodb还未完全启动至ready状态,node服务已经启动连接数据库报错了。
接下来看文件内容。
Dockerfile:
FROM node:10.15.3 # 使用node:10.15.3镜像
RUN mkdir -p /egg-center # 在容器中新建目录文件夹 egg-center
WORKDIR /egg-center # 将 /egg-center 设置为默认工作目录
COPY package.json /egg-center/package.json
RUN yarn --production # 先copy package.json文件至容器,并安装依赖
COPY . /egg-center # 再copy代码至容器。也可以部分先后直接copy整个代码
EXPOSE 7006 # 暴露7006端口
docker-compose.yml:
version: ''3''
services:
nginx:
image: nginx:latest # 使用nginx:latest镜像
ports:
- 8080:8080 # 宿主机端口:容器端口
volumes:
- "/Users/liaoxinyu/JsProject/eggJsProject/server/egg-center/nginx.conf:/etc/nginx/conf.d/nginx.conf" # 挂载nginx配置文件
egg-center:
build:
context: . # 以Dockerfile文件配置 build
ports:
- 7006:7006 # 宿主机端口:容器端口,用于nginx转发
command: ["npm", "start"] # 启动服务
配置mongodb容器,修改mongodb-compose.yml:
version: ''3''
services:
mongodb:
image: mongo:latest # 使用mongo:latest镜像
ports:
- 27017:27017 # 宿主机端口:容器端口
volumes:
- "/Users/liaoxinyu/db/mongodb/data:/data/db/" # 挂载数据库目录至本地,若不挂载,容器关闭后数据丢失。
修改nginx.conf:
upstream api {
server 10.10.1.31:7006;
} # 后端服务容器 端口:ip
server {
listen 8080; # 监听8080端口,docker-compose里做的映射
server_name localhost; # 本地配置就直接用localhost了,线上的话改成域名或公网ip
location /api {
# /api前缀的请求,全部转发至Egg.js服务
proxy_pass http://api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
# 可写多个location,转发至不同的服务或静态资源路由
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
启动项目:
1.先启动数据库:docker-compose -f mongodb-compose.yml up
2.数据库完全启动后,启动Egg.js服务与nginx:docker-compose up
验证:
1.使用 NoSqlBooster for MongoDB
连接数据库,配置很简单,配置ip:port
,查看数据库内容
2.使用 postman
请求 http://localhost:8080/api/admin/user
,这里发的请求是直接发到nginx代理的8080上。 由nginx转发至业务服务端口7006。
线上服务器就直接请求域名了,且不对外公开业务服务器的公网ip:端口。
结束
附:使用nginx - docker镜像部署服务器,配置https,附带java后端部署例子
Docker+Jenkins+Nodejs+Git+Webhook自动部署
1.准备环境
- 一台有网络的Linux 服务器
- Docker rpm安装包,依赖包 libcgroup
- jdk1.7 OR 1.8环境下载
- Jenkins WAR包下载
- NodeJs 源码包下载
依赖下载地址:
- https://pkgs.org/download/
- https://mirrors.aliyun.com/centos/7/os/x86_64/Packages/
2.安装Docker
rpm -ivh libcgroup-0.40.rc1-23.el6.x86_64.rpm
rpm -ivh docker-engine-1.7.1-1.el6.x86_64.rpm
3.编写Dockerfile
FROM ubuntu
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
RUN mv /usr/local/jdk1.8.0_171 /usr/local/java
ADD apache-tomcat-8.5.30.tar.gz /usr/local/
RUN mv /usr/local/apache-tomcat-8.5.30 /usr/local/tomcat
COPY jenkins.war /usr/local/tomcat/webapps/
ADD node-v8.11.1.tar.gz /root/
RUN apt-get update
RUN apt-get install -y python git ssh gcc g++ make
RUN /root/node-v8.11.1/configure && make -C /root/node-v8.11.1/ && make install -C /root/node-v8.11.1/ && rm -rf /root/node-v8.11.1/
ENV JAVA_HOME /usr/local/java
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 8080 3000 22
ENTRYPOINT ["java","-jar","/usr/local/tomcat/webapps/jenkins.war"]
(这里就不对Dockerfile和语法做解释了,可以自行查阅资料)
本来是要用tomcat启动的,但容器启动后tomcat没启动,试了很多种方法都不行,最后只能改成java -jar
将Dockerfile与所有的软件包放在一起然后执行命令
docker build -t jenkins ./
-t jenkins为镜像的TAG,''./''为Dockerfile与软件包的路径,最后看到Successfully说明成功
(Docker基础镜像中有jenkins的镜像,直接执行docker pull jenkins
就可以了,我为什么要用WAR包安装,是因为jenkins镜像的登陆用户为jenkins,登陆到容器后没有权限很多事情都做不了)
4.运行镜像
这时候运行docker images
应该就会有一个叫jenkins的镜像
执行命令
docker run -d -p 8080:8080 -p 50000:50000 -p 3000:3000 -p 50001:22 -v /var/jenkins_home:/root/.jenkins/ --name jenkins_node jenkins
(3000端口是自己设置的nodejs程序端口)
run 运行docker镜像,-d 以后台守护进程运行 ,-p 将容器端口开放(服务器端口:容器端口) , -v 挂载分区(服务器分区:容器分区) --name 指定容器名称,最后的jenkins为镜像包名
如果出现这种问题,重启docker服务,在尝试启动容器,如问题未能解决就将防火墙端口开放,然后重启docker服务
以Centos7为例
firewall-cmd --zone=public --add-port=50001/tcp --permanent
firewall-cmd --reload
systemctl restart docker
docker start jenkins_node
防火墙对docker的影响很大,在防火墙开启的情况下会遇到很多奇怪的错误,而且这些错误基本上查不到决绝办法,能查到的只有与你遇到的问题无关的,但这些问题基本上都是与连接有关的,比如连不上主机或找不到主机,解析不了网址之类的,如果在防火墙开启的情况下遇到这类问题就先检查防火墙,然后重启docker服务和容器
5.jenkins配置
jenkins安装
- 打开浏览器并输入:"服务器地址:8080"访问,出现如下页面
- 将服务器"/var/jenkins_home/secrets/initialAdminPassword"文件的内容复制到输入框,点击继续
- 点击左边的推荐安装,等待安装完成
- 设置Admin user
jenkins插件安装配置
- 点击 系统管理 --> 插件管理
- 选择 “可选插件”
- 右上角搜索SSH,--> 选择Publish Over SSH -->点击 直接安装
- 等待安装完成
- 安装成功后,点击 系统管理 --> 插件管理
-
拉到最下面找到 "Publish over SSH" , 设置服务器的SSH信息
- 到服务器执行
docker exec -it jenkins_node bash
登陆到容器 - 重置用户密码
passwd
- 安装一个编辑器
apt-get install -y vim
- 安装完之后
vim /etc/ssh/sshd_config
编辑ssh配置文件 - 找到
PermitRootLogin prohibit-password
改为PermitRootLogin yes
保存文件 - 重新启动ssh
service ssh restart
- 设置ssh开机自启动
update-rc.d ssh defaults
- 生成ssh秘钥
ssh-keygen -t rsa
什么都不要输直接回车直到完成就好 - 切换到ssh秘钥目录
cd ~/.ssh/
会有两个文件''id_rsa''(秘钥)和''id_rs a.pub''(公钥)文件 - 将公钥复制
cp id_rsa.pub authorized_keys
- 复制id_rsa(秘钥)文件中的内容
-
到jenkins ‘Publish over SSH’ 设置找到SSH Servers 点击 "增加 --> 高级"
- Name : ssh server名称随意设置
- Hostname : 服务器ip地址
- Username : 容器用户名
- 选中 Use password authentication, or use a different key
- Passphrase / Password : 容器用户密码
- Key : 将刚刚复制的id_rsa(秘钥)内容粘贴到这里
- Port : 设置成镜像运行命令中将22端口映射为50001的端口
- 点击Test Configuration出现Success成功
- 如果出现下图请检查authorized_keys文件名称或内容是否正确,和复制的私钥内容是否正确,docker容器ssh是否运行。
- 如果出现下图就到宿主机开放50001端口
- 保存
- 到服务器执行
6.jenkins项目配置
- 首页,点击左上角”新建”
- General: 只填 项目名称即可
- 源码管理: 填写Git信息
Repository URL : 填写项目git地址
Credentials : 如果有用户名密码,点击add添加用户信息,输入用户名密码如果出现图中CAfile错误就到容器中执行
git config --global http.sslverify false
关闭https证书检测,然后回到页面将Repository URL中的地址剪切并重新粘贴 - 构建环境选中‘Send files or execute commands over SSH before the build starts’
Remote directory : 执行此命令的文件夹位置,一般为"./",意思是在项目目录
Exec command :所执行的构建命令,例如"npm start" - 保存,返回首页,并构建刚刚创建的项目
7.自动部署
- jenkins --> 首页 --> 用户
- 设置 --> 点击 "show API Token"
- 复制API Token内容
- 返回首页 --> (自己的项目) --> 配置 --> 构建触发器 --> 选择 "触发远程构建" -->粘贴"API Token"内容到"身份验证令牌"
-
登陆git平台,找到你的项目,选择管理,选择webhook
- URL 中 node 请替换为你在jenkins上创建的项目名称
- token为复制的 API Token内容
- 此时你git push,会发现jenkins并没有自动构建,是因为jenkins的安全策略导致的,还需要如下设置。
jenkins首页,选择 系统管理-->Configure Global Security(系统设置下面那个) 进行如下设置
docker-node-pm2-sails.js启动传递环境参数
docker-node-pm2-sails.js启动传递环境参数
[TOC]
流程:docker run->DockerFile ->docker_start.sh
docker run
docker run -e NODE_ENV=test -d -p 1337:1337 noncar:0.1
DockerFile
#FROM 设置镜像
FROM node:8-alpine
# 设置镜像作者
MAINTAINER xumy
# 创建目录
RUN mkdir -p /app/csp
# 安装npm模块
ADD package.json /app/csp/package.json
# 安装npm模块
WORKDIR /app/csp
# 使用淘宝的npm镜像
RUN npm install --production -d --registry=http://registry.npm.taobao.org
# 再装pm2
RUN npm install -g pm2 --registry=https://registry.npm.taobao.org
# 添加源代码
ADD . /app/csp/
# 设置环境变量
ENV NODE_ENV test
# 用环境变量启动
CMD /bin/sh ./docker_start.sh $NODE_ENV
docker_start.sh
#!/bin/sh
echo $NODE_ENV
pm2-docker start pm2.json --env $NODE_ENV
sails.js 代码
config.connections.js
mongo: {
adapter: ''sails-mongo'',
host: ''10.11.1.161'', // defaults to `localhost` if omitted
port: 27017, // defaults to 27017 if omitted
database: ''cs'' // or omit if not relevant
},
devmongo: {
adapter: ''sails-mongo'',
host: ''10.2.108.59'', // defaults to `localhost` if omitted
port: 27017, // defaults to 27017 if omitted
database: ''cs'' // or omit if not relevant
},
testmongo: {
adapter: ''sails-mongo'',
host: ''10.1.110.74'', // defaults to `localhost` if omitted
port: 27017, // defaults to 27017 if omitted
database: ''cs'' // or omit if not relevant
}
config.models.js
//默认本机
connection: ''mongo
config.env
包括dev.js/prod.js/test.js
config.env.test.js
models: {
connection: ''testmongo''
},
启动验证
# 启动
docker run -e NODE_ENV=test -d -p 1337:1337 noncar:0.1
# 日志
docker logs -f cf
Docker: 编写 dockerfile 启动 node.js 应用
编写 Dockerfile
以 express
自动创建的目录为例,目录结构如下:
├── /bin
│ └── www
├── /node_modules
├── /public
├── /routes
├── /views
├── package-lock.json
├── package.json
├── ecosystem.config.js
├── app.js
└── Dockerfile
在项目目录下新建 Dockerfile
文件
FROM node:10.15
MAINTAINER sunhengzhe@foxmail.com
COPY . /app/
WORKDIR /app
RUN npm install pm2 -g
EXPOSE 8003
CMD ["pm2-runtime", "ecosystem.config.js"]
-
FROM
指定基础镜像为 node 的 10.15 版本(node 官方版本可 在此查看) -
MAINTAINER
说明镜像的维护者 -
COPY
命令将宿主机的文件拷贝到镜像中,格式为COPY [--chown=<user>:<group>] <源路径>... <目标路径>
,这里将项目目录下的所有文件都拷贝到镜像中的/app
目录下。如果目标路径不存在,docker 将自动创建。 -
WORKDIR
用来指定工作目录,即是CMD
执行所在的目录。 -
RUN
命令用来执行 shell 命令,这里用来安装pm2
-
EXPOSE
命令用来 声明 运行时容器提供服务端口,但要注意运行时并不会开启这个端口的服务。这个命令主要是帮助使用者理解这个镜像服务的守护端口,以方便配置映射;另外在使用随机端口映射时,会自动随机映射EXPOSE
的端口 -
CMD
是默认的容器主进程的启动命令
构建镜像
在项目目录下执行
docker build -t express-app:v1 .
如果构建成功,查看镜像列表
docker images
应该会输出镜像 express-app:v1
运行容器
docker run -d -p 8003:3000 --name="express-app" express-app:v1
docker run
是 docker create
和 docker start
两个命令的简写。
-
-d
即--detach
,代表让容器后台运行。 -
-p
指定宿主机和容器的端口映射,左边为宿主机的端口,右边为容器的端口,也就是说访问宿主机的 8003 端口,会映射到容器内的 3000 端口。 -
--name
设置容器别名,如果不指定,docker 会随机生成一个名字,比如tender_swirles
之类的。
执行
docker ps
正常展示如下
添加 -a
参数可以查看所有已启动容器。
进入容器
如果要进入容器进行操作,执行下面命令
docker exec -it express-app bash
-i
与 -t
一般结合使用,-i
启动交互模式,-t
指定需要分配终端,可以自行尝试不传其中一个的效果。
与 exec
类似的还有 attach
命令,命令为 docker attach express-app
,但从这个 stdin 中 exit,会导致容器的停止,所以推荐使用 exec
命令。
关闭操作
停止容器
docker stop express-app
删除容器
docker rm express-app
如果删除时容器还在运行,需要加上 -f
参数
删除镜像
docker rmi express-app:v1
今天关于使用 PM2 在 Docker 上部署 Node.js Web 应用和pm2-docker的介绍到此结束,谢谢您的阅读,有关Docker - 入门(二),docker&nodeJs制作镜像与本地部署、Docker+Jenkins+Nodejs+Git+Webhook自动部署、docker-node-pm2-sails.js启动传递环境参数、Docker: 编写 dockerfile 启动 node.js 应用等更多相关知识的信息可以在本站进行查询。
本文标签: