From b865402b10eb66600b3ae506c92294ea1ee6f9e4 Mon Sep 17 00:00:00 2001 From: okxlin Date: Thu, 14 Mar 2024 17:10:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BF=AE=E6=94=B9mixspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mixspace/5/.env.sample | 8 +++ apps/mixspace/5/data.yml | 51 ++++++++++++------- apps/mixspace/5/docker-compose.yml | 43 +++++++++------- apps/mixspace/README.md | 3 +- apps/mixspace/latest/.env.sample | 8 +++ apps/mixspace/latest/data.yml | 54 +++++++++++++++++++++ apps/mixspace/latest/docker-compose.yml | 62 ++++++++++++++++++++++++ apps/mixspace/logo.png | Bin 8410 -> 4396 bytes 8 files changed, 192 insertions(+), 37 deletions(-) create mode 100644 apps/mixspace/5/.env.sample create mode 100644 apps/mixspace/latest/.env.sample create mode 100644 apps/mixspace/latest/data.yml create mode 100644 apps/mixspace/latest/docker-compose.yml diff --git a/apps/mixspace/5/.env.sample b/apps/mixspace/5/.env.sample new file mode 100644 index 00000000..aa813917 --- /dev/null +++ b/apps/mixspace/5/.env.sample @@ -0,0 +1,8 @@ +CONTAINER_NAME="mixspace" +PANEL_APP_PORT_HTTP="40203" +ALLOWED_ORIGINS="example.com" +ENCRYPT_ENABLE="false" +ENCRYPT_KEY="" +JWT_SECRET="Np2qgqtiUayA857a_2KpAwe" +TIME_ZONE="Asia/Shanghai" +SUBNET_PREFIX="172.19.0" \ No newline at end of file diff --git a/apps/mixspace/5/data.yml b/apps/mixspace/5/data.yml index b8e919fa..f62253e2 100644 --- a/apps/mixspace/5/data.yml +++ b/apps/mixspace/5/data.yml @@ -1,37 +1,54 @@ additionalProperties: formFields: - - default: 2333 + - default: 40203 edit: true envKey: PANEL_APP_PORT_HTTP labelEn: Port - labelZh: 应用端口 + labelZh: 端口 required: true rule: paramPort type: number - default: example.com + edit: true envKey: ALLOWED_ORIGINS - labelEn: Allowed_Origins - labelZh: 允许域名(前端绑定域名,不需要https://,多个使用英文逗号分割) + labelEn: Allowed domain (multiple delimited with ",") + labelZh: 被允许的域名 (多个使用英文逗号分割) required: true type: text - - default: Np2qgqtiUayA857 + - default: Np2qgqtiUayA857a + edit: true envKey: JWT_SECRET - labelEn: Password - labelZh: JWT密钥(16到32位字符,请一定修改至要求!) + labelEn: JWT key (16 to 32 characters) + labelZh: JWT 密钥 (16 到 32 位字符) random: true required: true rule: paramComplexity type: password - - default: + - default: '' + edit: true envKey: ENCRYPT_KEY - labelEn: ENCRYPT_KEY - labelZh: 加密密钥(非特殊需求不建议填写) + labelEn: Encryption key (not recommended for non-special needs, run "openssl rand -hex 32" on the terminal to obtain it) + labelZh: 加密密钥 (非特殊需求不建议填写,终端执行 "openssl rand -hex 32" 获取) required: false - rule: paramCommon - type: password - - default: + type: text + - default: "false" + edit: true envKey: ENCRYPT_ENABLE - labelEn: ENCRYPT_ENABLE - labelZh: 是否开启加密(true或false,需要填写加密密钥) - required: false - type: text \ No newline at end of file + labelEn: Whether to enable encryption (true or false, if you want to enable it, you need to enter the encryption key) + labelZh: 是否开启加密 (true或false,开启则需要填写加密密钥) + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TIME_ZONE + labelEn: Time zone + labelZh: 时区 + required: true + type: text + - default: 172.19.0 + edit: true + envKey: SUBNET_PREFIX + labelEn: New docker network subnet prefix + labelZh: 新 docker 网络子网前缀 + required: true + type: text diff --git a/apps/mixspace/5/docker-compose.yml b/apps/mixspace/5/docker-compose.yml index f7991b97..75131388 100644 --- a/apps/mixspace/5/docker-compose.yml +++ b/apps/mixspace/5/docker-compose.yml @@ -1,12 +1,11 @@ version: '3.8' - services: - app: + mixspace: container_name: ${CONTAINER_NAME} image: innei/mx-server:5 command: bash ./docker-run.sh environment: - - TZ=Asia/Shanghai + - TZ=${TIME_ZONE} - NODE_ENV=production - ALLOWED_ORIGINS=${ALLOWED_ORIGINS} - JWT_SECRET=${JWT_SECRET} @@ -16,14 +15,8 @@ services: - ./data/mx-space:/root/.mx-space ports: - '${PANEL_APP_PORT_HTTP}:2333' - depends_on: - - mongo - - redis - links: - - mongo - - redis networks: - - 1panel-network + - mixspace-network restart: always healthcheck: test: ['CMD', 'curl', '-f', 'http://127.0.0.1:2333/api/v2/ping'] @@ -31,25 +24,39 @@ services: timeout: 30s retries: 5 start_period: 30s + depends_on: + - mongo + - redis + links: + - mongo + - redis labels: createdBy: "Apps" mongo: - container_name: mongo + container_name: ${CONTAINER_NAME}-mongo image: mongo volumes: - ./data/db:/data/db networks: - - 1panel-network + - mixspace-network restart: always + labels: + createdBy: "Apps" redis: image: redis - container_name: redis + container_name: ${CONTAINER_NAME}-redis networks: - - 1panel-network + - mixspace-network restart: always - -networks: - 1panel-network: - external: true \ No newline at end of file + labels: + createdBy: "Apps" + +networks: + mixspace-network: + driver: bridge + ipam: + driver: default + config: + - subnet: ${SUBNET_PREFIX}.0/16 \ No newline at end of file diff --git a/apps/mixspace/README.md b/apps/mixspace/README.md index d3bcf2a8..2b3dd818 100644 --- a/apps/mixspace/README.md +++ b/apps/mixspace/README.md @@ -4,8 +4,7 @@ Mix Space 是一个一款简洁而不简单的个人博客系统,它够快, ## 注意事项 -在此处你安装的是Mix-Space的后端,你还需要参照官方文档中的[前端主题](https://mx-space.js.org/themes -)部分完成前端部署 +在此处你安装的是Mix-Space的后端,你还需要参照官方文档中的 [前端主题](https://mx-space.js.org/themes) 部分完成前端部署 ## 主要功能: diff --git a/apps/mixspace/latest/.env.sample b/apps/mixspace/latest/.env.sample new file mode 100644 index 00000000..aa813917 --- /dev/null +++ b/apps/mixspace/latest/.env.sample @@ -0,0 +1,8 @@ +CONTAINER_NAME="mixspace" +PANEL_APP_PORT_HTTP="40203" +ALLOWED_ORIGINS="example.com" +ENCRYPT_ENABLE="false" +ENCRYPT_KEY="" +JWT_SECRET="Np2qgqtiUayA857a_2KpAwe" +TIME_ZONE="Asia/Shanghai" +SUBNET_PREFIX="172.19.0" \ No newline at end of file diff --git a/apps/mixspace/latest/data.yml b/apps/mixspace/latest/data.yml new file mode 100644 index 00000000..f62253e2 --- /dev/null +++ b/apps/mixspace/latest/data.yml @@ -0,0 +1,54 @@ +additionalProperties: + formFields: + - default: 40203 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: example.com + edit: true + envKey: ALLOWED_ORIGINS + labelEn: Allowed domain (multiple delimited with ",") + labelZh: 被允许的域名 (多个使用英文逗号分割) + required: true + type: text + - default: Np2qgqtiUayA857a + edit: true + envKey: JWT_SECRET + labelEn: JWT key (16 to 32 characters) + labelZh: JWT 密钥 (16 到 32 位字符) + random: true + required: true + rule: paramComplexity + type: password + - default: '' + edit: true + envKey: ENCRYPT_KEY + labelEn: Encryption key (not recommended for non-special needs, run "openssl rand -hex 32" on the terminal to obtain it) + labelZh: 加密密钥 (非特殊需求不建议填写,终端执行 "openssl rand -hex 32" 获取) + required: false + type: text + - default: "false" + edit: true + envKey: ENCRYPT_ENABLE + labelEn: Whether to enable encryption (true or false, if you want to enable it, you need to enter the encryption key) + labelZh: 是否开启加密 (true或false,开启则需要填写加密密钥) + required: true + type: text + - default: Asia/Shanghai + edit: true + envKey: TIME_ZONE + labelEn: Time zone + labelZh: 时区 + required: true + type: text + - default: 172.19.0 + edit: true + envKey: SUBNET_PREFIX + labelEn: New docker network subnet prefix + labelZh: 新 docker 网络子网前缀 + required: true + type: text diff --git a/apps/mixspace/latest/docker-compose.yml b/apps/mixspace/latest/docker-compose.yml new file mode 100644 index 00000000..080fa98f --- /dev/null +++ b/apps/mixspace/latest/docker-compose.yml @@ -0,0 +1,62 @@ +version: '3.8' +services: + mixspace: + container_name: ${CONTAINER_NAME} + image: innei/mx-server:latest + command: bash ./docker-run.sh + environment: + - TZ=${TIME_ZONE} + - NODE_ENV=production + - ALLOWED_ORIGINS=${ALLOWED_ORIGINS} + - JWT_SECRET=${JWT_SECRET} + - ENCRYPT_KEY=${ENCRYPT_KEY} + - ENCRYPT_ENABLE=${ENCRYPT_ENABLE} + volumes: + - ./data/mx-space:/root/.mx-space + ports: + - '${PANEL_APP_PORT_HTTP}:2333' + networks: + - mixspace-network + restart: always + healthcheck: + test: ['CMD', 'curl', '-f', 'http://127.0.0.1:2333/api/v2/ping'] + interval: 1m30s + timeout: 30s + retries: 5 + start_period: 30s + depends_on: + - mongo + - redis + links: + - mongo + - redis + labels: + createdBy: "Apps" + + mongo: + container_name: ${CONTAINER_NAME}-mongo + image: mongo + volumes: + - ./data/db:/data/db + networks: + - mixspace-network + restart: always + labels: + createdBy: "Apps" + + redis: + image: redis + container_name: ${CONTAINER_NAME}-redis + networks: + - mixspace-network + restart: always + labels: + createdBy: "Apps" + +networks: + mixspace-network: + driver: bridge + ipam: + driver: default + config: + - subnet: ${SUBNET_PREFIX}.0/16 \ No newline at end of file diff --git a/apps/mixspace/logo.png b/apps/mixspace/logo.png index 78f0fe3f334c0271a9502474e83d66bcb07d0388..b89ed9fa8df9f5688a8d375254dcc3b71cf19b52 100644 GIT binary patch literal 4396 zcmYkAcQ~8<_s3DIRP5R-C6d-Cu}4}&jR&=2?>&pE+Da*6q>6gPsGV39wMuK&s1dE& z6xA55RjVkWzV~ze{`q~bE1#TPIrll|{d#}yKkgfCY^1})z{@~ELBXV_i!=qkoBsRI zUjcRo_G4hDIx#jd*9HP$J$drv{{mo_m6fHWq|D9D&CJZCp`p>!({puoEh#BcR8*v* zq5}S+r>E!O;Na!ug+ifVFxb}Cw!OVwLqns#zkhOalA4;DmX;RCk&~0Nx3_n8c1})C z26muDR#ujyqhnK3)6me6ii!%51{4$#5n*Ctg27-wJ`e*1Q7Dv-jt)ORe_&vsxVX5n zv2kcYh3UYCA0oByi)ongTdI?*r=(g0f>Nt4h{}L1>kaTZ*Kts0TUAw zKwxccZDC=dnVA_dNor~;AS66I98d=k14dl+pp28fD?h=`Am2Zq1Ayadbw47#|uU}R)GIXO8! zJq3Ws%gY0j7Zw(3YHDO;WDXAxx3;!`n*00vb8~Y*eK;KM;^G20a(sLYc>3eVkENxh zsHi9i1Og0JR8(YPVF9S_?d`3vuLoKK8UeOPM@JhQ8-NRTc6PeDx`0jR=jW@dt0^fd zfC_*Q09jH}a%E*@d3hN)34q?<;9z%mcYqJT1i%GI77`KyL;-l~>goal0z5oC0LcKf ziHQj#BO@&>Ex-sqK0e@hba!_X2!!nHYye9_LV}l<7nw{Zkw{}>V;?_$1kM0p9AF>7 zp`)YY-Me>HRaL+dU0+`Zhymzwa&iD-1_lOSzkZ#WnaRk=P*zrMY-}tmEA#a9oSK?i zocDeR;LCbsYGg)nL36rCW;#MLE`~qgxw^BlI@UwTg^Tj@(#%eD)Mus|8Qz15vtOk- zS{ol9?CWZ&D|+=TILO?{5OIT#?f1^skCpk6;ep=wZwPg`^8B2v$HCstmMCKtDN#N) zR;I1KT0AcQc|!cth!8&yH!GBx9#U0B4lXUaJpI15EF&@T;RAn12YW+hMTtEuCM798 zNC$PD<_B=+n&=@l%){ol^E?gAOgKIg7*8CaztmS09;_@y@_CX3WqxtXW4Pr9?k`Q` zz{-rf^-Ykh+WgQ`XtM1>=~KqHt%%vJ_q)wBHM{MdrRa-jD$Nf?BW;(L%0D#iS_8j- zc*e*j^H!CC~dwh<_CG^3s{(I?mTP7S2%_@(A4-SyD$y#+_dgvu6)iQA2P3oA}|t~G8yJxY?Nv5hJ_ zCoHH6F7wXDS} zPRuSQhTUXzwOA0VFELfm6nf;(s1P-%qQ$y^Zl#~*s547fDwK@w&b#=+G4lP!hLhpQ zT3?%ajepimiF6g)Z|rCPD7R}t5T=`PoEn~0rsJhd(-z8K(P9myV5{4UjCha}@r(7h zk9vK2kLoDcmc(7F;-eVGW06~^J|1&v6iD>dw=bqi`}6)(Xp0*3nL(Am_m4+<-_1FX z9VpN#Oj9#z+@hErT=o9gxYD%z zk|v-r1-T7EddL}nDe~2o$Ak$UG}%CZ#IX#78@m01`jIH zfqVJb<+))~1FV}8Y6L30u3jlsenqELstWUk#`5pl`~0|6xrgE=o|!pPJVm{dj%6|3 z%GDJ{{a#d`j7h>bVzWx|N@HCs>AK5GN*t41@5^&{XNyy{LZQ2{6C)zuZY}9o1^wZ< z8~U6yrY|xv&HC-u)dFKlZPx8xKY_^U2%#Vy>wlphnRN7j=!)gx;5XIGeaS19LH!p$ z16lSu(k9#KD8@TDE3aq0sV4~-$pm#Wmk#V}KC@v4r!INN%2#J{dBrYYw!Rhb=5s%fw0`%N1cZS{@* zsN5pqXT2aB1J%o`c{1%=x4B>BeGVQ4>par!Lfm>R{IhVPDNZ<02n)09?dRhm7>B3@ zXfXKQbL{;PmEXh_`YCf=dgi`QKZ6F2$Q9I~n7&-eMD=_O3l5y)6Gqnz;0%hHL)BN8 zQ4vf5dS(0A4}YpD;k&2!*=#gL+#I#GJ!15XS{UBnQh5KkRNr)6;+ww0Ze68HCWrg* zRmeUydHflL7%YqRjE3)2H2NfSEDIJcM!Q!@Rfsq7f#n($l)-?HYI@>)$<8 z(%?Xc^sZ_>_8<=xbmry5aJD`oV$zeW81P`V>I-AoN|5dD#W?i(OH1W_l2In?F;bmk>-u6hhP53uz z3W9(th#Xi^Q?VY%KC4Mq7U0$0`5yAA+uUwHyHGZXnrUY>uEkM4y|WT*aHu4KhobTs?sT$cO`NQnqTD+R?& zTAOdY{A?mTn{{NpQvG@Ov%XxE=U)-FR0-{rPIA5_bdj-yQ+?3L#4q>C@ekDNj^Rh0 zxXFWy#NF(DrI)8yn|t9bR^{V*TUiux_@ag^a`)zJ=5bQ|YfyYzm=2-%aWLCttG`A80W6Kn;(j-;gIjJJ0s7q5I;3gi!jhej?Zk)tQ?{+(+t zR1A3huWJ*e;rjwRk|=Yfw&cY*^6s%XiV%Bbe5-LbN?iWYx)?E4H-F zBMA*ha|0b5#}@I4kaAo^+Nwn$Y2S=8j3Nz^2dtIvB3!dRD;kC>O19I& z6sS^gUDdZlL&Crpr*CQ8JGEw*;(w;KnvlKi90!{fqNYXeP`w%DmrzNMe0if(0bLNe zC#jhk;xlb#v@g}$|AqKA{@G{s_8Arv+mVzzfqFW9ZvXf!nNc-L*Gt_9VtyF6U9stn zG?!Mu&`~AZZ*g=cR;r6ljJqqr3!gD}WGjvEeb+-a8{apK=hqV$J`>)RZNQ#Zd253o zq!CZ$>`-Qh%3|!@9yu}}$BFl_hu#E1q#d)xWQp)96TugOUoCPchI*~vW^r~CQ!iFv zwaky^f0*6E)$?8kHYJPCrS$W_ZhespPFsa@-3L48EKEpV@GW*to;k_|^T&=#Wbuq* z%%9n5IE<67>mzg~@t0fair(vl?mcUW$gQNh&yX+Qa0s0OUAI3L9!Jg;ECdz-d&m^A zU32!*ZdqM>Z?MTf09lxK3lEsq>uQt;JCAi{=R0o1pjvIRTep+hrp2hC25(QrdoH zrOCg#d~qq=EG&3@RaUsqA^RLLqr#Pp(MB$vzLJA;&tEIR0JxZc&Lx=A}Fg2|m1lQMI_`S}` zOg-0BEw_dJ#l4H#3~hSFE(*`bl(`f$2aQ495c+rv(FEl`hOr;Pq)Lya%2tnu&=Aer zgKey_DVs5U&YUk!uQgPKB%3r~wJ@cn=87bxuFb&$Iz4Z41zd|(whRsDZASJl`ei&? z7u1c2Gsu_kgKfP)gRXGB4`SeSutx{uIKG}Fi^L61*8Wq_R4Oa`w)>@vAlPg)Ny%TN zx-NF>XIVy-9Y*PMuxK?Xe#EWV=h~O2_oLm8g($e%(ACPXknC%lB8|JEt$mW_qqW*{ z<5PUt3&K&c2*OFmKZku(qAsP{_1;)6j19H4f=p*JQwyYNz%n9|l zx&B&`i_Llp4)HSaR}OjsiO+bS!}uxe6vES{+?+h}yI>{mI^|XCdx04}n}k*r)-kcw z7|U>x!PuH1a0S$Qa$W^$^RY*#%KM~;{{&U!-5n=ezR6AcxQFXo!x4`@v473Plj}x)*Ue%S@LD=V>ZjLv#gJQbxcT;vc_yK!x81P zVUK-NPsJRg_BQh=8QjkHV2Cs7^%a>9|8ms8BEJ?hEmm}=mTV9nsHG_BSaNp2)S$PH zR!6m%nQ_IhAFt$Rk*0ln?n)SU&t;eYgPs8i8mPsa?2HJCH+5L5Y3 zw)EheetG$ykV4gBIsHwuj$pWH0|d4AEskW!HHKmq71}JrNx%c)|691TD=yI?Pxuz<*8h9kp{H$xtkZOQ`af$OFFpVO literal 8410 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 O2tmlI$P`PNy#F6gS1%#}