👷 更新docker镜像构建&文档

This commit is contained in:
chaos-zhu 2024-07-29 13:56:41 +08:00
parent ac7f4eb509
commit f2115ccf20
22 changed files with 72 additions and 198 deletions

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
node_modules
doc_images

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM node:20.16-alpine3.20
WORKDIR /easynode
COPY . .
RUN yarn
WORKDIR /easynode/web
RUN yarn build
RUN mv dist/* ../server/app/static
WORKDIR /easynode/server
ENV HOST 0.0.0.0
EXPOSE 8082
CMD [ "npm", "start" ]

6
Q&A.md
View File

@ -25,7 +25,7 @@ PubkeyAcceptedAlgorithms +ssh-rsa
```shell ```shell
vi /etc/selinux/config vi /etc/selinux/config
SELINUX=enforcing SELINUX=enforcing
// 修改为禁用 # 修改为禁用
SELINUX=disabled SELINUX=disabled
``` ```
@ -35,4 +35,6 @@ SELINUX=disabled
## 客户端服务启动成功,无法连接? ## 客户端服务启动成功,无法连接?
> 端口未开放:`iptables -I INPUT -s 0.0.0.0/0 -p tcp --dport 22022 -j ACCEPT` 或者 `rm -rf /etc/iptables && reboot` > 1. 检查防火墙配置
> 2. iptables端口未开放`iptables -I INPUT -s 0.0.0.0/0 -p tcp --dport 22022 -j ACCEPT` 或者 `rm -rf /etc/iptables && reboot`

View File

@ -1,20 +1,19 @@
# EasyNode v2.0 # EasyNode v2.0
> 一个功能完善的Linux服务器SSH终端面板.
> [!WARNING] > [!WARNING]
> 初次部署EasyNode登录系统后务必记得修改默认账户密码 `admin/admin` > 初次部署EasyNode登录系统后务必记得修改默认账户密码 `admin/admin`
> [!WARNING] > [!WARNING]
> 强烈建议使用 **iptables****fail2ban** 等安全服务限制IP访问谨慎暴露面板服务到公网。 > 强烈建议使用 **iptables****fail2ban** 等安全服务限制IP访问谨慎暴露面板服务到公网。
> [!NOTE]
> 客户端信息监控与webssh功能都将以`该服务器作为中转`。中国大陆连接建议使用香港、新加坡、日本、韩国等地区的低延迟服务器来安装服务端
<!-- - [功能简介](#功能简介) - [功能简介](#功能简介)
- [安装指南](#安装指南) - [安装指南](#安装指南)
- [服务端安装](#服务端安装) - [服务端安装](#服务端安装)
- [Docker镜像](#docker镜像) - [Docker镜像](#docker镜像)
- [一键脚本](#一键脚本) - [一键脚本](#一键脚本[暂未编写])
- [手动部署](#手动部署)
- [客户端安装](#客户端安装) - [客户端安装](#客户端安装)
- [X86架构](#x86架构) - [X86架构](#x86架构)
- [ARM架构](#arm架构) - [ARM架构](#arm架构)
@ -30,18 +29,13 @@
## 功能简介 ## 功能简介
> 多服务器管理; 通过`websocket实时更新`服务器基本信息: **系统、公网IP、CPU、内存、硬盘、网卡**等 > 一个多功能webssh终端; 通过ws实时更新服务器基本信息: **系统、公网IP、CPU、内存、硬盘、网卡**等
![服务器面板](./images/v1.2-1.png) ![服务器面板](./doc_images/v2.0-1.jpg)
> 基于浏览器解决`SSH&SFTP跨端`烦恼——**Web SSH**&**Web SFTP** > 基于浏览器解决`SSH&SFTP跨端`烦恼——**Web SSH**&**Web SFTP**
![终端&sftp](./doc_images/v2.0-2.jpg)
![websftp功能](./images/v1.2-2.png)
> 在线编辑文件
![edit](./images/v1.2-3.png)
## 安装指南 ## 安装指南
@ -51,29 +45,14 @@
- 占用端口8082(http端口)、22022(客户端端口) - 占用端口8082(http端口)、22022(客户端端口)
- 建议使用**境外服务器**(最好延迟低)安装服务端客户端信息监控与webssh功能都将以`该服务器作为跳板机`
#### Docker镜像 #### Docker镜像
> 注意网速统计功能可能受限docker网络将使用host模式(与宿主机共享端口,占用: 8082、22022)
- 如果你是第一次运行先创建一个volume用于保存数据
```shell ```shell
docker volume create --name easynode-server docker run -d --net=host --name=easynode-server -v $PWD/easynode/db:/easynode/server/app/db chaoszhu/easynode
``` ```
```shell
docker run -d --net=host --name=easynode-server -v easynode-server:/easynode-server/app/storage/ chaoszhu/easynode:v1.2.1
```
- 如果你想清除容器与数据
```shell
docker rm -f easynode-server && docker volume remove easynode-server
```
访问http://yourip:8082 访问http://yourip:8082
#### 一键脚本 <!-- #### 一键脚本
- **依赖Linux基础命令工具curl wget git zip tar如未安装请先安装** - **依赖Linux基础命令工具curl wget git zip tar如未安装请先安装**
@ -84,7 +63,7 @@ docker rm -f easynode-server && docker volume remove easynode-server
- 运行环境:[Node.js](https://nodejs.org/en/download/) **v14+** - 运行环境:[Node.js](https://nodejs.org/en/download/) **v14+**
```shell ```shell
wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.2/easynode-server-install.sh | bash wget -qO- --no-check-certificate https://raw.githubusercontent.com/chaos-zhu/easynode/v1.2/easynode-server-install.sh | bash
``` ```
访问http://yourip:8082 访问http://yourip:8082
@ -92,18 +71,7 @@ wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubuserconte
- 查看日志:`pm2 log easynode-server` - 查看日志:`pm2 log easynode-server`
- 启动服务:`pm2 start easynode-server` - 启动服务:`pm2 start easynode-server`
- 停止服务:`pm2 stop easynode-server` - 停止服务:`pm2 stop easynode-server`
- 删除服务:`pm2 delete easynode-server` - 删除服务:`pm2 delete easynode-server` -->
#### 手动部署
1. 安装Node.js
2. 安装pm2、安装yarn
3. 拉取代码git clone https://github.com/chaos-zhu/easynode.git
4. 安装依赖yarn
5. 启动服务pm2 start server/app/main.js --name easynode-server
6. 访问http://yourip:8082
- 默认登录密码admin(首次部署完成后请及时修改).
--- ---
@ -114,19 +82,19 @@ wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubuserconte
#### X86架构 #### X86架构
```shell ```shell
wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.2/easynode-client-install-x86.sh | bash wget -qO- --no-check-certificate https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.2/easynode-client-install-x86.sh | bash
``` ```
#### ARM架构 #### ARM架构
```shell ```shell
wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.1/easynode-client-install-arm.sh | bash wget -qO- --no-check-certificate https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.1/easynode-client-install-arm.sh | bash
``` ```
> 卸载 > 卸载
```shell ```shell
wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.2/easynode-client-uninstall.sh | bash wget -qO- --no-check-certificate https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.2/easynode-client-uninstall.sh | bash
``` ```
> 查看客户端状态:`systemctl status easynode-client` > 查看客户端状态:`systemctl status easynode-client`
@ -139,19 +107,7 @@ wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubuserconte
## 升级指南 ## 升级指南
2.0版本无论前后端均作了大量的重构工作1.0版本**不支持**无感升级到2.0版本 2.0版本无论前后端均作了大量的重构工作1.0版本**不支持**升级到2.0版本
### 服务端
> v1.1对所有的敏感信息全部加密所有的v1.0为加密的信息全部失效. 主要影响已存储的ssh密钥.
>
> **还原客户端列表:** 先备份`app\config\storage\host-list.json`, 使用一键脚本或者手动部署的同志安装好使用备份文件覆盖`\app\storage`下的同名文件即可。
>
> 由于加密文件调整使用docker镜像的v1.1一键脚本自己从镜像里把备份抠出来再重新构建镜像.
### 客户端
> v1.2未对客户端包进行改动,客户端无需重复安装. 不会备份的在面板重新添加客户端机器即可.
### 版本日志 ### 版本日志
@ -159,11 +115,7 @@ wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubuserconte
## 安全与说明 ## 安全与说明
> 本人非专业后端,此服务全凭兴趣开发. 由于知识受限,并不能保证没有漏洞的存在,重要生产服务器最好不要使用此服务!!! > 本人非专业后端,此服务全凭兴趣开发. 由于知识受限,并不能保证没有漏洞的存在,所以请务必使用`iptables`限制ip访问该服务且不要轻易暴露此服务在公网。
> 所有服务器信息相关接口已做`jwt鉴权`, 安全信息均使用加密传输与储存!
> webssh功能需要的密钥信息全部保存在服务端服务器的`app\storage\ssh-record.json`中. 在保存ssh密钥信息到服务器储存与传输过程皆已加密`不过最好还是套https使用`
## 开发 ## 开发
@ -182,4 +134,4 @@ wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubuserconte
## License ## License
[MIT](LICENSE). Copyright (c). --> [MIT](LICENSE). Copyright (c).

BIN
doc_images/v2.0-1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

BIN
doc_images/v2.0-2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View File

@ -42,8 +42,8 @@ echo "***********************创建文件PATH***********************"
mkdir -p ${FILE_PATH} mkdir -p ${FILE_PATH}
echo "***********************下载开始***********************" echo "***********************下载开始***********************"
DOWNLOAD_FILE_URL="https://ghproxy.com/https://github.com/chaos-zhu/easynode/releases/download/v1.1/easynode-client-arm" DOWNLOAD_FILE_URL="https://mirror.ghproxy.com/https://github.com/chaos-zhu/easynode/releases/download/v1.1/easynode-client-arm"
DOWNLOAD_SERVICE_URL="https://ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.1/client/easynode-client.service" DOWNLOAD_SERVICE_URL="https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.1/client/easynode-client.service"
# -O 指定路径和文件名(这里是二进制文件, 不需要扩展名) # -O 指定路径和文件名(这里是二进制文件, 不需要扩展名)
wget -O ${FILE_PATH}/${SERVER_NAME} --no-check-certificate --no-cache ${DOWNLOAD_FILE_URL} wget -O ${FILE_PATH}/${SERVER_NAME} --no-check-certificate --no-cache ${DOWNLOAD_FILE_URL}

View File

@ -42,8 +42,8 @@ echo "***********************创建文件PATH***********************"
mkdir -p ${FILE_PATH} mkdir -p ${FILE_PATH}
echo "***********************下载开始***********************" echo "***********************下载开始***********************"
DOWNLOAD_FILE_URL="https://ghproxy.com/https://github.com/chaos-zhu/easynode/releases/download/v1.1/easynode-client-x86" DOWNLOAD_FILE_URL="https://mirror.ghproxy.com/https://github.com/chaos-zhu/easynode/releases/download/v1.1/easynode-client-x86"
DOWNLOAD_SERVICE_URL="https://ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.1/client/easynode-client.service" DOWNLOAD_SERVICE_URL="https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/v1.1/client/easynode-client.service"
# -O 指定路径和文件名(这里是二进制文件, 不需要扩展名) # -O 指定路径和文件名(这里是二进制文件, 不需要扩展名)
wget -O ${FILE_PATH}/${SERVER_NAME} --no-check-certificate --no-cache ${DOWNLOAD_FILE_URL} wget -O ${FILE_PATH}/${SERVER_NAME} --no-check-certificate --no-cache ${DOWNLOAD_FILE_URL}

View File

@ -1,74 +0,0 @@
#!/bin/bash
if [ "$(id -u)" != "0" ] ; then
echo "***********************请切换到root再尝试执行***********************"
exit 1
fi
echo "***********************检测node环境***********************"
node -v
if [ $? != 0 ]
then
echo "未安装node运行环境"
exit 1
fi
echo "已安装"
echo "***********************检测pm2守护进程***********************"
pm2 list
if [ $? != 0 ]
then
echo "未安装pm2,正在安装..."
npm i -g pm2
fi
echo "已安装"
echo "***********************开始下载EasyNode***********************"
DOWNLOAD_FILE_URL="https://ghproxy.com/https://github.com/chaos-zhu/easynode/releases/download/v1.2.1/easynode-server.zip"
SERVER_NAME=easynode-server
SERVER_ZIP=easynode-server.zip
FILE_PATH=/root
wget -O ${FILE_PATH}/${SERVER_ZIP} --no-check-certificate --no-cache ${DOWNLOAD_FILE_URL}
if [ $? != 0 ]
then
echo "下载EasyNode.zip失败,请检查网络环境或稍后再试"
exit 1
fi
echo "下载成功"
echo '***********************开始解压***********************'
unzip -o -d ${FILE_PATH}/${SERVER_NAME} ${SERVER_ZIP}
if [ $? != 0 ]
then
echo "解压失败, 请确保已安装zip、tar基础工具"
exit 1
fi
echo "解压成功"
cd ${FILE_PATH}/${SERVER_NAME} || exit
echo '***********************开始安装依赖***********************'
yarn -v
if [ $? != 0 ]
then
echo "未安装yarn管理工具,正在安装..."
npm i -g yarn
fi
yarn
if [ $? != 0 ]
then
echo "yarn安装失败请检测网络环境. 使用大陆vps请执行以下命令设置镜像源再重新运行该脚本npm config set registry https://registry.npm.taobao.org
"
fi
echo "依赖安装成功"
echo '启动服务'
pm2 start ${FILE_PATH}/${SERVER_NAME}/app/main.js --name easynode-server
echo '查看日志请输入: pm2 log easynode-server'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,6 +1,6 @@
{ {
"name": "easynode", "name": "easynode",
"version": "1.0.0", "version": "2.0.0",
"description": "web ssh", "description": "web ssh",
"private": true, "private": true,
"workspaces": [ "workspaces": [

View File

@ -1,13 +0,0 @@
FROM node:16.15.0-alpine3.14
ARG TARGET_DIR=/easynode-server
WORKDIR ${TARGET_DIR}
RUN yarn config set registry https://registry.npm.taobao.org
COPY package.json ${TARGET_DIR}
COPY yarn.lock ${TARGET_DIR}
RUN yarn
COPY . ${TARGET_DIR}
ENV HOST 0.0.0.0
EXPOSE 8082
EXPOSE 8083
EXPOSE 22022
CMD ["npm", "run", "server"]

View File

@ -2,15 +2,6 @@
- 基于Koa - 基于Koa
## docker
<!-- 修改版本号 -->
- 构建镜像docker build -t chaoszhu/easynode:v1.1 .
- 推送镜像docker push chaoszhu/easynode:v1.1
> `docker run -d --net=host easynode-server`
<!-- > `docker run -d -p 8888:8082 -p 22022:22022 easynode-server` -->
## 遇到的问题 ## 遇到的问题
> MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 input listeners added to [Socket]. Use emitter.setMaxListeners() to increase limit > MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 input listeners added to [Socket]. Use emitter.setMaxListeners() to increase limit

View File

@ -11,7 +11,7 @@
"scripts": { "scripts": {
"local": "cross-env EXEC_ENV=local nodemon ./app/index.js", "local": "cross-env EXEC_ENV=local nodemon ./app/index.js",
"prod": "cross-env EXEC_ENV=production nodemon ./app/index.js", "prod": "cross-env EXEC_ENV=production nodemon ./app/index.js",
"start": "node ./app/index.js", "start": "node ./index.js",
"pkgwin": "pkg . -t node20-win-x64", "pkgwin": "pkg . -t node20-win-x64",
"pkglinux:x86": "pkg . -t node20-linux-x64", "pkglinux:x86": "pkg . -t node20-linux-x64",
"pkglinux:arm": "pkg . -t node20-linux-arm64", "pkglinux:arm": "pkg . -t node20-linux-arm64",

View File

@ -1,4 +0,0 @@
FROM nginx:stable-alpine
WORKDIR /easynode-web
COPY dist /easynode-web
COPY web.conf /etc/nginx/conf.d/default.conf

View File

@ -62,16 +62,16 @@ let menuList = reactive([
icon: markRaw(FolderOpened), icon: markRaw(FolderOpened),
index: '/group' index: '/group'
}, },
{ // {
name: '批量指令', // name: '',
icon: markRaw(Pointer), // icon: markRaw(Pointer),
index: '/onekey' // index: '/onekey'
}, // },
{ // {
name: '脚本库', // name: '',
icon: markRaw(ArrowRight), // icon: markRaw(ArrowRight),
index: '/scripts' // index: '/scripts'
}, // },
{ {
name: '系统设置', name: '系统设置',
icon: markRaw(Setting), icon: markRaw(Setting),

View File

@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="visible" v-model="visible"
width="80%" width="60%"
:top="'30px'" :top="'30px'"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -12,7 +12,7 @@
> >
<template #header> <template #header>
<div class="title"> <div class="title">
FileName - <span>{{ status }}</span> {{ FileName }} - <span>{{ status }}</span>
</div> </div>
</template> </template>
<codemirror <codemirror
@ -40,7 +40,7 @@
/> />
</el-select> </el-select>
</div> </div>
<div> <div class="footer_btns">
<el-button type="primary" :loading="loading" @click="handleSave">保存</el-button> <el-button type="primary" :loading="loading" @click="handleSave">保存</el-button>
<el-button type="info" @click="handleClose">关闭</el-button> <el-button type="info" @click="handleClose">关闭</el-button>
</div> </div>
@ -210,14 +210,14 @@ export default {
.cm-scroller { .cm-scroller {
// //
&::-webkit-scrollbar { &::-webkit-scrollbar {
height: 8px; height: 4px;
width: 8px; width: 4px;
background-color: #282c34; background-color: #282c34;
} }
// //
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background-color: #282c34; background-color: #282c34;
border-radius: 5px; border-radius: 3px;
} }
} }
} }
@ -229,10 +229,13 @@ export default {
align-items: center; align-items: center;
padding: 0 15px; padding: 0 15px;
justify-content: space-between; justify-content: space-between;
}
}
.select_wrap { .select_wrap {
width: 150px; width: 150px;
margin-right: 15px; margin-right: 15px;
} }
} .footer_btns {
margin-top: 15px;
} }
</style> </style>

View File

@ -2,7 +2,8 @@
<el-card shadow="always" class="host-card"> <el-card shadow="always" class="host-card">
<div class="host-state"> <div class="host-state">
<span v-if="isError" class="offline">未连接</span> <span v-if="isError" class="offline">未连接</span>
<span v-else class="online">已连接 {{ ping }}</span> <span v-else class="online">已连接</span>
<!-- {{ ping }} -->
</div> </div>
<div class="info"> <div class="info">
<div class="weizhi field"> <div class="weizhi field">
@ -269,9 +270,9 @@ const handleRemoveHost = async () => {
left: 0px; left: 0px;
span { span {
font-size: 8px; font-size: 10px;
// transform: rotate(-45deg); // transform: rotate(-45deg);
transform: scale(0.9); // transform: scale(0.95);
display: inline-block; display: inline-block;
padding: 3px 5px; padding: 3px 5px;
} }

View File

@ -60,7 +60,7 @@ import InfoSide from './info-side.vue'
import Sftp from './sftp.vue' import Sftp from './sftp.vue'
import InputCommand from '@/components/input-command/index.vue' import InputCommand from '@/components/input-command/index.vue'
const { proxy: { $nextTick, $store } } = getCurrentInstance() const { proxy: { $nextTick, $store, $message } } = getCurrentInstance()
const props = defineProps({ const props = defineProps({
terminalTabs: { terminalTabs: {
@ -102,6 +102,7 @@ function handleResizeTerminalSftp() {
} }
const handleCommandHost = (host) => { const handleCommandHost = (host) => {
if (!host.isConfig) return $message.warning('请先配置SSH连接信息')
emit('add-host', host) emit('add-host', host)
} }

View File

@ -31,7 +31,7 @@ export default defineConfig({
// } // }
}, },
build: { build: {
outDir: '../server/app/static', // outDir: '../server/app/static',
emptyOutDir: true emptyOutDir: true
}, },
define: { define: {