开发 兼容 docker 的启动方式

This commit is contained in:
Suwings 2020-03-04 15:22:09 +08:00
parent 0e47254753
commit e6f0fad283
3 changed files with 295 additions and 31 deletions

View File

@ -10,8 +10,9 @@ const path = require('path')
const properties = require("properties");
const fs = require('fs');
const Docker = require('dockerode');
var CODE_CONSOLE = MCSERVER.localProperty.console_encode;
const CODE_CONSOLE = MCSERVER.localProperty.console_encode;
class ServerProcess extends EventEmitter {
@ -90,50 +91,136 @@ class ServerProcess extends EventEmitter {
//使用 Docker 命令启动
dockerStart() {
//命令模板与准备数据
let dockerCommand = this.dataModel.dockerConfig.dockerCommand;
// let dockerCommand = this.dataModel.dockerConfig.dockerCommand;
// let processCwd = process.cwd();
let stdCwd = path.resolve(this.dataModel.cwd).replace(/\\/igm, "/");
//命令模板渲染
if (this.dataModel.highCommande.trim() != "")
dockerCommand = dockerCommand.replace(/\$\{commande\}/igm, this.dataModel.highCommande);
else
dockerCommand = dockerCommand.replace(/\$\{commande\}/igm, this.templateStart(true));
//加入镜像名
dockerCommand = dockerCommand.replace(/\$\{imagename\}/igm,
this.dataModel.dockerConfig.dockerImageName);
//加入端口限制
dockerCommand = dockerCommand.replace(/\$\{ports\}/igm,
this.dataModel.dockerConfig.dockerPorts ? "-p " + this.dataModel.dockerConfig.dockerPorts : "");
//加入服务端绝对路径
dockerCommand = dockerCommand.replace(/\$\{serverpath\}/igm,
tools.CharReplaceTemp(stdCwd, " "));
//加入最大内存限制
dockerCommand = dockerCommand.replace(/\$\{xmx\}/igm,
this.dataModel.dockerConfig.dockerXmx ? "-m " + this.dataModel.dockerConfig.dockerXmx : "");
// if (this.dataModel.highCommande.trim() != "")
// dockerCommand = dockerCommand.replace(/\$\{commande\}/igm, this.dataModel.highCommande);
// else
// dockerCommand = dockerCommand.replace(/\$\{commande\}/igm, this.templateStart(true));
// //加入镜像名
// dockerCommand = dockerCommand.replace(/\$\{imagename\}/igm,
// this.dataModel.dockerConfig.dockerImageName);
// //加入端口限制
// dockerCommand = dockerCommand.replace(/\$\{ports\}/igm,
// this.dataModel.dockerConfig.dockerPorts ? "-p " + this.dataModel.dockerConfig.dockerPorts : "");
// //加入服务端绝对路径
// dockerCommand = dockerCommand.replace(/\$\{serverpath\}/igm,
// tools.CharReplaceTemp(stdCwd, " "));
// //加入最大内存限制
// dockerCommand = dockerCommand.replace(/\$\{xmx\}/igm,
// this.dataModel.dockerConfig.dockerXmx ? "-m " + this.dataModel.dockerConfig.dockerXmx : "");
//格式替换
let dockerCommandPart = dockerCommand.replace(/ /igm, " ").split(" ");
// let dockerCommandPart = dockerCommand.replace(/ /igm, " ").split(" ");
//分割的参数全部渲染
// for (let k in dockerCommandPart) { }
let execDockerCommande = [];
for (let i = 1; i < dockerCommandPart.length; i++) {
if (dockerCommandPart[i].trim() != "") execDockerCommande.push(tools.TempReplaceChar(dockerCommandPart[i], " "));
// let execDockerCommande = [];
// for (let i = 1; i < dockerCommandPart.length; i++) {
// if (dockerCommandPart[i].trim() != "") execDockerCommande.push(tools.TempReplaceChar(dockerCommandPart[i], " "));
// }
// 暂时使用 MCSMERVER.log 目前已弃用,下版本 log4js
// MCSERVER.infoLog('Minecraft Server start (Docker)', this.dataModel.name);
// MCSERVER.log('端实例 [' + this.dataModel.name + '] 启动 Docker 容器:');
// MCSERVER.log('-------------------------------');
// MCSERVER.log('启动命令: ' + dockerCommandPart[0] + " " + execDockerCommande.join(" "));
// MCSERVER.log('根:' + stdCwd);
// MCSERVER.log('-------------------------------');
// this.process = childProcess.spawn(dockerCommandPart[0], execDockerCommande, this.ProcessConfig);
// this.send(this.dataModel.highCommande || this.templateStart(true));
// 采用 Docker API 进行启动与监控
// 启动命令解析
let startCommande = "";
if (this.dataModel.highCommande.trim() != "")
startCommande = this.dataModel.highCommande;
else
startCommande = this.templateStart(true);
const startCommandeArray = startCommande.split(" ");
// 端口解析
let portmap = this.dataModel.dockerConfig.dockerPorts;
portmap = portmap.split(":");
if (portmap.length != 2) {
throw new Error("不支持的多端口操作方法");
}
// 绑定内部暴露端口
const protocol = "tcp";
const ExposedPortsObj = {};
ExposedPortsObj[portmap[0] + "/" + protocol] = {};
//暂时使用 MCSMERVER.log 目前已弃用,下版本 log4js
MCSERVER.infoLog('Minecraft Server start (Docker)', this.dataModel.name);
MCSERVER.log('端实例 [' + this.dataModel.name + '] 启动 Docker 容器:');
MCSERVER.log('-------------------------------');
MCSERVER.log('启动命令: ' + dockerCommandPart[0] + " " + execDockerCommande.join(" "));
MCSERVER.log('根:' + stdCwd);
MCSERVER.log('-------------------------------');
// 绑定内部暴露端口与其对应的宿主机端口
const PortBindingsObj = {};
PortBindingsObj[portmap[0] + "/" + protocol] = [{
HostPort: portmap[1] + ""
}];
this.process = childProcess.spawn(dockerCommandPart[0], execDockerCommande, this.ProcessConfig);
console.log("正在使用虚拟化技术启动进程:\n", startCommandeArray, " Port:", portmap)
console.log("Pwd:", stdCwd, "端口参数:", ExposedPortsObj, PortBindingsObj)
this.send(this.dataModel.highCommande || this.templateStart(true));
// 模拟一个正常的 Process
this.process = new EventEmitter();
// 基于镜像启动虚拟化容器
const docker = new Docker();
let auxContainer = null;
docker.createContainer({
Image: this.dataModel.dockerConfig.dockerImageName,
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Tty: false,
Cmd: startCommandeArray,
OpenStdin: true,
StdinOnce: false,
ExposedPorts: ExposedPortsObj,
HostConfig: {
Binds: [
stdCwd + ":/mcsd/"
],
Memory: this.dataModel.dockerConfig.dockerXmx * 1024 * 1024 * 1024,
PortBindings: PortBindingsObj,
}
}).then((container) => {
auxContainer = container;
return auxContainer.start();
}).then(() => {
// 链接容器的输入输出流
auxContainer.attach({
stream: true,
stdin: true,
stdout: true
}, (err, stream) => {
if (err) throw err;
// 赋值进程容器
this.process.dockerContainer = auxContainer;
// 模拟 pid
this.process.pid = 1;
// 对接普通进程的输入输出流
this.process.stdin = stream;
this.process.stdout = stream;
this.process.stderr = stream;
// 模拟进程杀死功能
this.process.kill = (() => {
docker.getContainer(auxContainer.id).kill().then(() => {
docker.getContainer(auxContainer.id).remove().then(() => {
console.log('this.process.kill')
return;
});
});
});
// 进程事件传递
stream.on('exit', (e) => this.process.emit('exit', e));
stream.on('error', (e) => this.process.emit('error', e));
console.log("\nDEBUG Docker process start:", this.process);
});
});
}
//统一服务端开启

176
package-lock.json generated
View File

@ -18,11 +18,27 @@
"resolved": "http://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
"integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/async-limiter/download/async-limiter-1.0.1.tgz",
"integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"bl": {
"version": "1.2.2",
"resolved": "https://registry.npm.taobao.org/bl/download/bl-1.2.2.tgz?cache=0&sync_timestamp=1568859021404&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbl%2Fdownload%2Fbl-1.2.2.tgz",
@ -80,11 +96,21 @@
"resolved": "https://registry.npm.taobao.org/buffer-fill/download/buffer-fill-1.0.0.tgz",
"integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz",
"integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8="
},
"bytes": {
"version": "3.0.0",
"resolved": "http://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
"chownr": {
"version": "1.1.4",
"resolved": "https://registry.npm.taobao.org/chownr/download/chownr-1.1.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchownr%2Fdownload%2Fchownr-1.1.4.tgz",
"integrity": "sha1-b8nXtC0ypYNZYzdmbn0ICE2izGs="
},
"colors": {
"version": "1.1.2",
"resolved": "http://registry.npm.taobao.org/colors/download/colors-1.1.2.tgz",
@ -145,6 +171,29 @@
"vary": "~1.1.2"
}
},
"concat-stream": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/concat-stream/download/concat-stream-2.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconcat-stream%2Fdownload%2Fconcat-stream-2.0.0.tgz",
"integrity": "sha1-QUz1r3kKSMYKub5FJ9VtXkETPLE=",
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.0.2",
"typedarray": "^0.0.6"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
"integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"connect": {
"version": "3.6.5",
"resolved": "http://registry.npm.taobao.org/connect/download/connect-3.6.5.tgz",
@ -236,6 +285,52 @@
"resolved": "http://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"docker-modem": {
"version": "2.1.1",
"resolved": "https://registry.npm.taobao.org/docker-modem/download/docker-modem-2.1.1.tgz",
"integrity": "sha1-wtNzULRVduoaqZAjR7eyjKuTPqI=",
"requires": {
"debug": "^4.1.1",
"readable-stream": "^3.5.0",
"split-ca": "^1.0.1",
"ssh2": "^0.8.7"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.1.1.tgz",
"integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=",
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz",
"integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
"integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"dockerode": {
"version": "3.1.0",
"resolved": "https://registry.npm.taobao.org/dockerode/download/dockerode-3.1.0.tgz",
"integrity": "sha1-hbl6HqHEgjHtMpdIJxJ7e4CyryA=",
"requires": {
"concat-stream": "~2.0.0",
"docker-modem": "^2.1.0",
"tar-fs": "~2.0.0"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "http://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
@ -759,6 +854,29 @@
"resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.1.0.tgz",
"integrity": "sha512-zq6fLdGQixb9VZfT/tLgU+LzoedJyTbcf1I/TKETFeUVoWIfcs5HNr+SJSvQJLXRlEZjB1gpILTrxamxAdCcgA=="
},
"split-ca": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/split-ca/download/split-ca-1.0.1.tgz",
"integrity": "sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY="
},
"ssh2": {
"version": "0.8.8",
"resolved": "https://registry.npm.taobao.org/ssh2/download/ssh2-0.8.8.tgz",
"integrity": "sha1-HZgV4of672I64rfbMuZ02tvvRmQ=",
"requires": {
"ssh2-streams": "~0.4.9"
}
},
"ssh2-streams": {
"version": "0.4.9",
"resolved": "https://registry.npm.taobao.org/ssh2-streams/download/ssh2-streams-0.4.9.tgz",
"integrity": "sha1-09khVUEAAUN9JxGdnAI7MDy+Iwk=",
"requires": {
"asn1": "~0.2.0",
"bcrypt-pbkdf": "^1.0.2",
"streamsearch": "~0.1.2"
}
},
"stat-mode": {
"version": "0.2.2",
"resolved": "https://registry.npm.taobao.org/stat-mode/download/stat-mode-0.2.2.tgz",
@ -774,6 +892,11 @@
"resolved": "https://registry.npm.taobao.org/streamifier/download/streamifier-0.1.1.tgz",
"integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8="
},
"streamsearch": {
"version": "0.1.2",
"resolved": "https://registry.npm.taobao.org/streamsearch/download/streamsearch-0.1.2.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.1.1.tgz",
@ -782,6 +905,49 @@
"safe-buffer": "~5.1.0"
}
},
"tar-fs": {
"version": "2.0.0",
"resolved": "https://registry.npm.taobao.org/tar-fs/download/tar-fs-2.0.0.tgz",
"integrity": "sha1-Z3cA/AyLM3p4vuNiP9wjXyHXr60=",
"requires": {
"chownr": "^1.1.1",
"mkdirp": "^0.5.1",
"pump": "^3.0.0",
"tar-stream": "^2.0.0"
},
"dependencies": {
"bl": {
"version": "3.0.0",
"resolved": "https://registry.npm.taobao.org/bl/download/bl-3.0.0.tgz?cache=0&sync_timestamp=1568859021404&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbl%2Fdownload%2Fbl-3.0.0.tgz",
"integrity": "sha1-NhHsAFef0YVhdUNgsh6feEUA/4g=",
"requires": {
"readable-stream": "^3.0.1"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
"integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"tar-stream": {
"version": "2.1.0",
"resolved": "https://registry.npm.taobao.org/tar-stream/download/tar-stream-2.1.0.tgz",
"integrity": "sha1-0aqjZh8Fs4tazJtwIO/cpReaLMM=",
"requires": {
"bl": "^3.0.0",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
}
}
}
},
"tar-stream": {
"version": "1.6.2",
"resolved": "https://registry.npm.taobao.org/tar-stream/download/tar-stream-1.6.2.tgz",
@ -801,6 +967,11 @@
"resolved": "https://registry.npm.taobao.org/to-buffer/download/to-buffer-1.1.1.tgz",
"integrity": "sha1-STvUj2LXxD/N7TE6A9ytsuEhOoA="
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npm.taobao.org/tweetnacl/download/tweetnacl-0.14.5.tgz?cache=0&sync_timestamp=1581365004105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftweetnacl%2Fdownload%2Ftweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"type-is": {
"version": "1.6.15",
"resolved": "http://registry.npm.taobao.org/type-is/download/type-is-1.6.15.tgz",
@ -810,6 +981,11 @@
"mime-types": "~2.1.15"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
"uid-safe": {
"version": "2.1.5",
"resolved": "http://registry.npm.taobao.org/uid-safe/download/uid-safe-2.1.5.tgz",

View File

@ -27,6 +27,7 @@
"compression": "^1.7.2",
"connect": "^3.6.2",
"cookie-parser": "^1.4.3",
"dockerode": "^3.1.0",
"express": "^4.15.3",
"express-session": "^1.15.3",
"express-ws": "^4.0.0",