@whyour/qinglong 2.20.2-3 → 2.21.0-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -0
- package/AGENTS.md +43 -0
- package/README-en.md +11 -0
- package/README.md +11 -0
- package/back/protos/api.proto +3 -0
- package/deploy/kubernetes/README.md +81 -0
- package/deploy/kubernetes/base/kustomization.yaml +5 -0
- package/deploy/kubernetes/base/qinglong.yaml +95 -0
- package/deploy/kubernetes/overlays/example/kustomization.yaml +10 -0
- package/docker/Dockerfile +51 -69
- package/docker/Dockerfile.310 +94 -0
- package/docker/Dockerfile.debian +120 -0
- package/docker/{310.Dockerfile → Dockerfile.debian310} +13 -5
- package/docker/docker-entrypoint.sh +95 -3
- package/docs/PROJECT_ARCHITECTURE.md +550 -0
- package/package.json +29 -28
- package/sample/config.sample.sh +19 -3
- package/sample/notify.js +145 -9
- package/sample/notify.py +110 -11
- package/shell/api.sh +51 -21
- package/shell/bot.sh +30 -16
- package/shell/check.sh +21 -19
- package/shell/lang/en.sh +105 -0
- package/shell/lang/zh.sh +105 -0
- package/shell/otask.sh +117 -28
- package/shell/preload/client.js +20 -2
- package/shell/preload/esm-loader.mjs +41 -0
- package/shell/preload/sitecustomize.js +36 -0
- package/shell/pub.sh +8 -8
- package/shell/rmlog.sh +5 -5
- package/shell/share.sh +50 -31
- package/shell/start.sh +40 -27
- package/shell/task.sh +10 -2
- package/shell/update.sh +22 -22
- package/static/build/api/config.js +17 -7
- package/static/build/api/cron.js +40 -3
- package/static/build/api/dashboard.js +344 -0
- package/static/build/api/env.js +40 -2
- package/static/build/api/index.js +2 -0
- package/static/build/api/log.js +15 -5
- package/static/build/api/script.js +34 -9
- package/static/build/api/system.js +22 -8
- package/static/build/api/user.js +6 -5
- package/static/build/app.js +22 -19
- package/static/build/config/const.js +8 -6
- package/static/build/config/container.js +12 -0
- package/static/build/config/grpcCerts.js +150 -0
- package/static/build/config/index.js +6 -4
- package/static/build/config/util.js +69 -18
- package/static/build/data/cron.js +3 -1
- package/static/build/data/cronStats.js +59 -0
- package/static/build/data/env.js +2 -0
- package/static/build/data/notify.js +18 -1
- package/static/build/data/runningInstance.js +57 -0
- package/static/build/data/sock.js +1 -0
- package/static/build/loaders/app.js +7 -7
- package/static/build/loaders/db.js +8 -2
- package/static/build/loaders/deps.js +1 -22
- package/static/build/loaders/express.js +19 -15
- package/static/build/loaders/initData.js +20 -2
- package/static/build/loaders/initFile.js +3 -1
- package/static/build/loaders/initTask.js +3 -2
- package/static/build/loaders/server.js +1 -1
- package/static/build/protos/api.js +23 -1
- package/static/build/schedule/addCron.js +67 -10
- package/static/build/schedule/api.js +1 -1
- package/static/build/schedule/client.js +9 -1
- package/static/build/schedule/delCron.js +11 -1
- package/static/build/schedule/health.js +1 -1
- package/static/build/services/config.js +19 -5
- package/static/build/services/cron.js +198 -38
- package/static/build/services/dependence.js +19 -18
- package/static/build/services/env.js +31 -3
- package/static/build/services/grpc.js +32 -6
- package/static/build/services/http.js +33 -18
- package/static/build/services/notify.js +87 -8
- package/static/build/services/open.js +2 -1
- package/static/build/services/sshKey.js +6 -3
- package/static/build/services/subscription.js +8 -5
- package/static/build/services/system.js +34 -9
- package/static/build/services/user.js +39 -13
- package/static/build/shared/auth.js +7 -1
- package/static/build/shared/i18n.js +160 -0
- package/static/build/shared/pLimit.js +15 -3
- package/static/build/shared/runCron.js +5 -0
- package/static/build/shared/store.js +7 -0
- package/static/build/validation/schedule.js +10 -0
- package/static/dist/1089.0ecc5383.async.js +1 -0
- package/static/dist/1147.62793604.async.js +1 -0
- package/static/dist/1192.4e5740f2.async.js +1 -0
- package/static/dist/1214.c6469b53.async.js +1 -0
- package/static/dist/134.54df9e38.async.js +1 -0
- package/static/dist/1352.96a77e1d.async.js +1 -0
- package/static/dist/{1765.d8e002d7.async.js → 1765.5ac01a93.async.js} +1 -1
- package/static/dist/1836.f0b74cf1.async.js +1 -0
- package/static/dist/{1885.e0d00d2d.async.js → 1885.e1ea09f6.async.js} +1 -1
- package/static/dist/1967.3f3945d0.async.js +1 -0
- package/static/dist/{2096.383c1047.async.js → 2096.6d98fd12.async.js} +1 -1
- package/static/dist/2208.85285476.async.js +1 -0
- package/static/dist/2286.f371c743.async.js +1 -0
- package/static/dist/2476.4e9b0992.async.js +1 -0
- package/static/dist/2537.2b262ee0.async.js +1 -0
- package/static/dist/{255.12f03ab2.async.js → 255.8a80b983.async.js} +1 -1
- package/static/dist/2635.d4c59d23.async.js +1 -0
- package/static/dist/2808.cdc0995c.async.js +1 -0
- package/static/dist/{2821.be3dc88e.async.js → 2821.651f31e5.async.js} +1 -1
- package/static/dist/2986.4c49eef7.async.js +1 -0
- package/static/dist/300.08ac9875.async.js +1 -0
- package/static/dist/3191.545ab873.async.js +1 -0
- package/static/dist/3714.8d6dba9e.async.js +1 -0
- package/static/dist/3906.a5eee612.async.js +1 -0
- package/static/dist/{6541.a6d499de.async.js → 3948.4fe809fd.async.js} +1 -1
- package/static/dist/{5171.7fc6d0a2.async.js → 4573.16f19278.async.js} +1 -1
- package/static/dist/{4859.93e63ea6.async.js → 4859.6592cebb.async.js} +1 -1
- package/static/dist/4887.8e3ae573.async.js +1 -0
- package/static/dist/{4902.54ecbdb5.async.js → 4902.555f92ab.async.js} +1 -1
- package/static/dist/{4934.1ca6b6b0.async.js → 4934.f3539d08.async.js} +1 -1
- package/static/dist/5077.cbd111cd.async.js +1 -0
- package/static/dist/{6247.b550d996.async.js → 5157.7c5af144.async.js} +1 -1
- package/static/dist/{540.481d4708.async.js → 540.19ddf020.async.js} +1 -1
- package/static/dist/{5970.10ac4f16.async.js → 5970.d3a6e7bd.async.js} +1 -1
- package/static/dist/{6013.2d7bb12a.async.js → 6013.4e38de36.async.js} +1 -1
- package/static/dist/{6016.9c379049.async.js → 6016.1e6574b6.async.js} +1 -1
- package/static/dist/{6035.5889ddc7.async.js → 6035.32ebfad9.async.js} +1 -1
- package/static/dist/6339.ab305e96.async.js +1 -0
- package/static/dist/6569.55177f6a.async.js +1 -0
- package/static/dist/6610.c111af7e.async.js +1 -0
- package/static/dist/{3034.6413c38e.async.js → 6638.87a163d2.async.js} +1 -1
- package/static/dist/{6646.5fc37228.async.js → 6646.95e92533.async.js} +1 -1
- package/static/dist/6665.1d099ad1.async.js +1 -0
- package/static/dist/{7355.b7c0562f.async.js → 7355.f9f263d8.async.js} +1 -1
- package/static/dist/{7384.065ccae2.async.js → 7384.1bb449d5.async.js} +1 -1
- package/static/dist/7441.ee1bf2bb.async.js +1 -0
- package/static/dist/{7508.a31662a3.async.js → 7508.7dcee91c.async.js} +1 -1
- package/static/dist/{7802.6b73f16a.async.js → 7802.34255805.async.js} +1 -1
- package/static/dist/{7984.e6bb9378.async.js → 7984.594296a5.async.js} +1 -1
- package/static/dist/{5653.4fce7ce8.async.js → 8033.5cb31493.async.js} +1 -1
- package/static/dist/8147.2fb55202.async.js +1 -0
- package/static/dist/8187.48c130d6.async.js +1 -0
- package/static/dist/8495.d53e15ca.async.js +1 -0
- package/static/dist/8587.315b06c0.async.js +1 -0
- package/static/dist/8826.db34ad8d.async.js +1 -0
- package/static/dist/{2742.4852aac8.async.js → 8865.ed665d31.async.js} +1 -1
- package/static/dist/901.7ee5c6d3.async.js +1 -0
- package/static/dist/9271.231db2ce.async.js +1 -0
- package/static/dist/9323.a33f47da.async.js +1 -0
- package/static/dist/{9730.30083c91.async.js → 9730.801665a3.async.js} +1 -1
- package/static/dist/{9761.627ca3b5.async.js → 9761.360a19d8.async.js} +1 -1
- package/static/dist/index.html +2 -2
- package/static/dist/layouts__index.a7a2bfe0.async.js +1 -0
- package/static/dist/layouts__index.adf0692f.chunk.css +1 -0
- package/static/dist/preload_helper.3048fe5b.js +1 -0
- package/static/dist/{src__pages__config__index.622b6ee8.async.js → src__pages__config__index.a22ff7dc.async.js} +1 -1
- package/static/dist/{src__pages__crontab__const.323d5124.async.js → src__pages__crontab__const.aba07deb.async.js} +1 -1
- package/static/dist/src__pages__crontab__detail.b98f0084.async.js +1 -0
- package/static/dist/src__pages__crontab__index.68e78a33.async.js +1 -0
- package/static/dist/{src__pages__crontab__logModal.5e6a4bf2.async.js → src__pages__crontab__logModal.831d5e4b.async.js} +1 -1
- package/static/dist/src__pages__crontab__modal.f7041c7c.async.js +1 -0
- package/static/dist/src__pages__crontab__type.d7af36e5.async.js +1 -0
- package/static/dist/{src__pages__crontab__viewCreateModal.ffcf7a24.async.js → src__pages__crontab__viewCreateModal.4d589f66.async.js} +1 -1
- package/static/dist/{src__pages__crontab__viewManageModal.c2724575.async.js → src__pages__crontab__viewManageModal.0e317746.async.js} +1 -1
- package/static/dist/src__pages__dashboard__index.58177357.async.js +1 -0
- package/static/dist/src__pages__dependence__index.b7bbc795.async.js +1 -0
- package/static/dist/{src__pages__dependence__logModal.f123e2ac.async.js → src__pages__dependence__logModal.0681830b.async.js} +1 -1
- package/static/dist/src__pages__dependence__modal.f7bb47ba.async.js +1 -0
- package/static/dist/src__pages__env__editNameModal.48715576.async.js +1 -0
- package/static/dist/src__pages__env__index.452cdc47.async.js +1 -0
- package/static/dist/src__pages__env__modal.e1234834.async.js +1 -0
- package/static/dist/src__pages__error__index.dedb2b90.async.js +1 -0
- package/static/dist/src__pages__initialization__index.22620a77.async.js +1 -0
- package/static/dist/src__pages__log__index.9c66639f.async.js +1 -0
- package/static/dist/{src__pages__login__index.cd6e3152.async.js → src__pages__login__index.8c813eb1.async.js} +1 -1
- package/static/dist/{src__pages__script__components__UnsupportedFilePreview__index.39074c68.async.js → src__pages__script__components__UnsupportedFilePreview__index.c347a13a.async.js} +1 -1
- package/static/dist/src__pages__script__editNameModal.532a3044.async.js +1 -0
- package/static/dist/src__pages__script__index.1fc20f22.async.js +1 -0
- package/static/dist/src__pages__script__renameModal.5cdde919.async.js +1 -0
- package/static/dist/src__pages__script__saveModal.5ffed35f.async.js +1 -0
- package/static/dist/src__pages__script__setting.1a82c6d7.async.js +1 -0
- package/static/dist/src__pages__setting__appModal.43b7758a.async.js +1 -0
- package/static/dist/src__pages__setting__checkUpdate.34d773f2.async.js +1 -0
- package/static/dist/src__pages__setting__dependence.9c04c79a.async.js +1 -0
- package/static/dist/src__pages__setting__index.7e070838.async.js +1 -0
- package/static/dist/src__pages__setting__notification.bac481c2.async.js +1 -0
- package/static/dist/src__pages__setting__other.707cfafe.async.js +1 -0
- package/static/dist/src__pages__setting__security.b7235753.async.js +1 -0
- package/static/dist/src__pages__setting__systemLog.b81a8c1d.async.js +1 -0
- package/static/dist/{src__pages__subscription__logModal.0caa7283.async.js → src__pages__subscription__logModal.3864b37f.async.js} +1 -1
- package/static/dist/src__pages__subscription__modal.562448e2.async.js +1 -0
- package/static/dist/{umi.ef8199a4.js → umi.a54a59f6.js} +1 -1
- package/version.yaml +33 -4
- package/sample/notify.py.save +0 -1010
- package/static/dist/105.85a5c47a.async.js +0 -1
- package/static/dist/1083.f86ce804.async.js +0 -1
- package/static/dist/1147.32f41a88.async.js +0 -1
- package/static/dist/1352.ab6da08e.async.js +0 -1
- package/static/dist/1690.f0290540.async.js +0 -1
- package/static/dist/1742.6cbe5aca.async.js +0 -1
- package/static/dist/2208.8e3a7325.async.js +0 -1
- package/static/dist/3191.70bc19db.async.js +0 -1
- package/static/dist/5312.74b95311.async.js +0 -1
- package/static/dist/5691.931f59c5.async.js +0 -1
- package/static/dist/6159.55cb068a.async.js +0 -1
- package/static/dist/7025.f4080d63.async.js +0 -1
- package/static/dist/739.6be5552a.async.js +0 -1
- package/static/dist/7571.4f6240b1.async.js +0 -1
- package/static/dist/786.59fc381c.async.js +0 -1
- package/static/dist/8317.c44c1ebd.async.js +0 -1
- package/static/dist/8826.0291edfd.async.js +0 -1
- package/static/dist/955.3c9481f7.async.js +0 -1
- package/static/dist/layouts__index.1fce90e0.chunk.css +0 -1
- package/static/dist/layouts__index.8dcf1576.async.js +0 -1
- package/static/dist/preload_helper.116a62f6.js +0 -1
- package/static/dist/src__pages__crontab__detail.b07f0c0a.async.js +0 -1
- package/static/dist/src__pages__crontab__index.2e2e1096.async.js +0 -1
- package/static/dist/src__pages__crontab__modal.4d8c2a22.async.js +0 -1
- package/static/dist/src__pages__crontab__type.db7c1858.async.js +0 -1
- package/static/dist/src__pages__dependence__index.3d87ceac.async.js +0 -1
- package/static/dist/src__pages__dependence__modal.631ffb5b.async.js +0 -1
- package/static/dist/src__pages__env__editNameModal.ff85ef8c.async.js +0 -1
- package/static/dist/src__pages__env__index.a0a2fece.async.js +0 -1
- package/static/dist/src__pages__env__modal.d1004662.async.js +0 -1
- package/static/dist/src__pages__error__index.1bc3c90b.async.js +0 -1
- package/static/dist/src__pages__initialization__index.8b1cbaf9.async.js +0 -1
- package/static/dist/src__pages__log__index.cf00c9af.async.js +0 -1
- package/static/dist/src__pages__script__editNameModal.53424d49.async.js +0 -1
- package/static/dist/src__pages__script__index.e65df827.async.js +0 -1
- package/static/dist/src__pages__script__renameModal.4bbe7fb1.async.js +0 -1
- package/static/dist/src__pages__script__saveModal.cf449f3c.async.js +0 -1
- package/static/dist/src__pages__script__setting.b345d59a.async.js +0 -1
- package/static/dist/src__pages__setting__appModal.03faec89.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.46efe057.async.js +0 -1
- package/static/dist/src__pages__setting__dependence.4495c7b6.async.js +0 -1
- package/static/dist/src__pages__setting__index.6919c399.async.js +0 -1
- package/static/dist/src__pages__setting__notification.d6a3884f.async.js +0 -1
- package/static/dist/src__pages__setting__other.0d931d6f.async.js +0 -1
- package/static/dist/src__pages__setting__security.91cb545f.async.js +0 -1
- package/static/dist/src__pages__setting__systemLog.1d433a48.async.js +0 -1
- package/static/dist/src__pages__subscription__modal.0b84f6cf.async.js +0 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
FROM node:22-slim AS nodebuilder
|
|
2
|
+
|
|
3
|
+
FROM python:3.11-slim-bookworm AS builder
|
|
4
|
+
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
|
|
5
|
+
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
|
|
6
|
+
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
|
|
7
|
+
RUN set -x && \
|
|
8
|
+
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
|
|
9
|
+
apt-get update && \
|
|
10
|
+
apt-get install --no-install-recommends -y libatomic1 && \
|
|
11
|
+
npm i -g pnpm@8.3.1 && \
|
|
12
|
+
cd /tmp/build && \
|
|
13
|
+
pnpm install --prod
|
|
14
|
+
|
|
15
|
+
FROM python:3.11-slim-bookworm
|
|
16
|
+
|
|
17
|
+
ARG QL_MAINTAINER="whyour"
|
|
18
|
+
LABEL maintainer="${QL_MAINTAINER}"
|
|
19
|
+
ARG QL_URL=https://github.com/${QL_MAINTAINER}/qinglong.git
|
|
20
|
+
ARG QL_BRANCH=develop
|
|
21
|
+
ARG PYTHON_SHORT_VERSION=3.11
|
|
22
|
+
|
|
23
|
+
ENV QL_DIR=/ql \
|
|
24
|
+
QL_BRANCH=${QL_BRANCH} \
|
|
25
|
+
QL_CONTAINER=true \
|
|
26
|
+
LANG=C.UTF-8 \
|
|
27
|
+
SHELL=/bin/bash \
|
|
28
|
+
PS1="\u@\h:\w \$ "
|
|
29
|
+
|
|
30
|
+
ARG QL_UID=5432
|
|
31
|
+
ARG QL_GID=5432
|
|
32
|
+
RUN groupadd -g ${QL_GID} qinglong && \
|
|
33
|
+
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
|
|
34
|
+
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
|
|
35
|
+
chmod 700 /home/qinglong/.ssh && \
|
|
36
|
+
chown -R ${QL_UID}:${QL_GID} /home/qinglong && \
|
|
37
|
+
mkdir -p /etc/sudoers.d && \
|
|
38
|
+
echo 'qinglong ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/qinglong
|
|
39
|
+
|
|
40
|
+
ENV QL_USER=qinglong
|
|
41
|
+
ENV QL_HOME=/home/$QL_USER
|
|
42
|
+
|
|
43
|
+
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
|
|
44
|
+
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
|
|
45
|
+
|
|
46
|
+
RUN set -x && \
|
|
47
|
+
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
|
|
48
|
+
ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx && \
|
|
49
|
+
apt-get update && \
|
|
50
|
+
apt-get upgrade -y && \
|
|
51
|
+
apt-get install --no-install-recommends -y git \
|
|
52
|
+
curl \
|
|
53
|
+
wget \
|
|
54
|
+
tzdata \
|
|
55
|
+
perl \
|
|
56
|
+
openssl \
|
|
57
|
+
openssh-client \
|
|
58
|
+
jq \
|
|
59
|
+
procps \
|
|
60
|
+
netcat-openbsd \
|
|
61
|
+
sudo \
|
|
62
|
+
unzip \
|
|
63
|
+
libatomic1 && \
|
|
64
|
+
apt-get clean && \
|
|
65
|
+
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
|
66
|
+
echo "Asia/Shanghai" >/etc/timezone && \
|
|
67
|
+
git config --global user.email "qinglong@users.noreply.github.com" && \
|
|
68
|
+
git config --global user.name "qinglong" && \
|
|
69
|
+
git config --global http.postBuffer 524288000 && \
|
|
70
|
+
npm install -g pnpm@8.3.1 pm2 ts-node && \
|
|
71
|
+
rm -rf /root/.cache && \
|
|
72
|
+
rm -rf /root/.npm && \
|
|
73
|
+
rm -rf /etc/apt/apt.conf.d/docker-clean && \
|
|
74
|
+
ulimit -c 0
|
|
75
|
+
|
|
76
|
+
RUN mkdir -p ${QL_DIR} && \
|
|
77
|
+
chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
|
|
78
|
+
|
|
79
|
+
USER qinglong
|
|
80
|
+
ARG SOURCE_COMMIT
|
|
81
|
+
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
|
|
82
|
+
cd ${QL_DIR} && \
|
|
83
|
+
cp -f .env.example .env && \
|
|
84
|
+
chmod 777 ${QL_DIR}/shell/*.sh && \
|
|
85
|
+
chmod 777 ${QL_DIR}/docker/*.sh && \
|
|
86
|
+
git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /tmp/static && \
|
|
87
|
+
mkdir -p ${QL_DIR}/static && \
|
|
88
|
+
cp -rf /tmp/static/* ${QL_DIR}/static && \
|
|
89
|
+
rm -rf /tmp/static
|
|
90
|
+
|
|
91
|
+
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
|
|
92
|
+
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
|
|
93
|
+
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \
|
|
94
|
+
HOME=/home/qinglong
|
|
95
|
+
|
|
96
|
+
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \
|
|
97
|
+
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \
|
|
98
|
+
PIP_CACHE_DIR=${PYTHON_HOME}/pip \
|
|
99
|
+
PYTHONPATH=${PYTHON_HOME}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}/site-packages
|
|
100
|
+
|
|
101
|
+
RUN pip3 install --prefix ${PYTHON_HOME} requests
|
|
102
|
+
|
|
103
|
+
COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node_modules/
|
|
104
|
+
|
|
105
|
+
USER root
|
|
106
|
+
|
|
107
|
+
RUN ln -sf ${QL_DIR}/shell/task.sh /usr/local/bin/task \
|
|
108
|
+
&& ln -sf ${QL_DIR}/shell/update.sh /usr/local/bin/ql \
|
|
109
|
+
&& chmod +x /usr/local/bin/task /usr/local/bin/ql
|
|
110
|
+
|
|
111
|
+
WORKDIR ${QL_DIR}
|
|
112
|
+
|
|
113
|
+
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
|
|
114
|
+
CMD curl -sf --noproxy '*' http://localhost:${QlPort:-5700}/api/health || exit 1
|
|
115
|
+
|
|
116
|
+
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
|
|
117
|
+
|
|
118
|
+
VOLUME /ql/data
|
|
119
|
+
|
|
120
|
+
EXPOSE 5700
|
|
@@ -22,6 +22,7 @@ ARG PYTHON_SHORT_VERSION=3.10
|
|
|
22
22
|
|
|
23
23
|
ENV QL_DIR=/ql \
|
|
24
24
|
QL_BRANCH=${QL_BRANCH} \
|
|
25
|
+
QL_CONTAINER=true \
|
|
25
26
|
LANG=C.UTF-8 \
|
|
26
27
|
SHELL=/bin/bash \
|
|
27
28
|
PS1="\u@\h:\w \$ "
|
|
@@ -32,7 +33,9 @@ RUN groupadd -g ${QL_GID} qinglong && \
|
|
|
32
33
|
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
|
|
33
34
|
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
|
|
34
35
|
chmod 700 /home/qinglong/.ssh && \
|
|
35
|
-
chown -R ${QL_UID}:${QL_GID} /home/qinglong
|
|
36
|
+
chown -R ${QL_UID}:${QL_GID} /home/qinglong && \
|
|
37
|
+
mkdir -p /etc/sudoers.d && \
|
|
38
|
+
echo 'qinglong ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/qinglong
|
|
36
39
|
|
|
37
40
|
ENV QL_USER=qinglong
|
|
38
41
|
ENV QL_HOME=/home/$QL_USER
|
|
@@ -54,6 +57,7 @@ RUN set -x && \
|
|
|
54
57
|
jq \
|
|
55
58
|
procps \
|
|
56
59
|
netcat-openbsd \
|
|
60
|
+
sudo \
|
|
57
61
|
unzip \
|
|
58
62
|
libatomic1 && \
|
|
59
63
|
apt-get clean && \
|
|
@@ -87,10 +91,10 @@ RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
|
|
|
87
91
|
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
|
|
88
92
|
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
|
|
89
93
|
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \
|
|
90
|
-
HOME=/
|
|
94
|
+
HOME=/home/qinglong
|
|
91
95
|
|
|
92
96
|
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \
|
|
93
|
-
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules
|
|
97
|
+
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \
|
|
94
98
|
PIP_CACHE_DIR=${PYTHON_HOME}/pip \
|
|
95
99
|
PYTHONPATH=${PYTHON_HOME}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}/site-packages
|
|
96
100
|
|
|
@@ -100,13 +104,17 @@ COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node
|
|
|
100
104
|
|
|
101
105
|
USER root
|
|
102
106
|
|
|
107
|
+
RUN ln -sf ${QL_DIR}/shell/task.sh /usr/local/bin/task \
|
|
108
|
+
&& ln -sf ${QL_DIR}/shell/update.sh /usr/local/bin/ql \
|
|
109
|
+
&& chmod +x /usr/local/bin/task /usr/local/bin/ql
|
|
110
|
+
|
|
103
111
|
WORKDIR ${QL_DIR}
|
|
104
112
|
|
|
105
113
|
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
|
|
106
|
-
CMD curl -sf --noproxy '*' http://
|
|
114
|
+
CMD curl -sf --noproxy '*' http://localhost:${QlPort:-5700}/api/health || exit 1
|
|
107
115
|
|
|
108
116
|
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
|
|
109
117
|
|
|
110
118
|
VOLUME /ql/data
|
|
111
|
-
|
|
119
|
+
|
|
112
120
|
EXPOSE 5700
|
|
@@ -15,9 +15,68 @@ log_with_style() {
|
|
|
15
15
|
printf "\n[%s] [%7s] %s\n" "${timestamp}" "${level}" "${message}"
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
# ============================================
|
|
19
|
+
# 确保当前用户对 /ql 和 /ql/data 目录有写入权限
|
|
20
|
+
# /ql/data 是 Docker Volume 挂载点,权限可能与 /ql 不同,需单独检测
|
|
21
|
+
# ============================================
|
|
22
|
+
ensure_ql_permissions() {
|
|
23
|
+
local current_uid
|
|
24
|
+
local current_gid
|
|
25
|
+
current_uid=$(id -u)
|
|
26
|
+
current_gid=$(id -g)
|
|
27
|
+
|
|
28
|
+
if [ "$current_uid" -eq 0 ]; then
|
|
29
|
+
return 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# ---- 检查 /ql 目录 ----
|
|
33
|
+
if ! mkdir -p "$QL_DIR/.tmp" 2>/dev/null; then
|
|
34
|
+
if chown -R "$current_uid:$current_gid" "$QL_DIR" 2>/dev/null; then
|
|
35
|
+
log_with_style "INFO" "已修正 /ql 目录权限: UID=$current_uid GID=$current_gid"
|
|
36
|
+
else
|
|
37
|
+
local ql_owner
|
|
38
|
+
ql_owner=$(stat -c '%u' "$QL_DIR" 2>/dev/null || stat -f '%u' "$QL_DIR" 2>/dev/null)
|
|
39
|
+
log_with_style "ERROR" "============================================="
|
|
40
|
+
log_with_style "ERROR" " 权限错误:无法写入 /ql 目录"
|
|
41
|
+
log_with_style "ERROR" " 当前用户 UID: $current_uid"
|
|
42
|
+
log_with_style "ERROR" " /ql 目录所有者 UID: ${ql_owner:-未知}"
|
|
43
|
+
log_with_style "ERROR" ""
|
|
44
|
+
log_with_style "ERROR" " 解决方案:"
|
|
45
|
+
log_with_style "ERROR" " 1. 使用镜像内置用户: docker run --user ${ql_owner:-5432}:${ql_owner:-5432} ..."
|
|
46
|
+
log_with_style "ERROR" " 2. 使用 root 运行: 移除 --user 参数"
|
|
47
|
+
log_with_style "ERROR" " 3. 修正宿主机数据目录: chown -R $current_uid:$current_gid /path/to/ql/data"
|
|
48
|
+
log_with_style "ERROR" "============================================="
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
fi
|
|
52
|
+
rmdir "$QL_DIR/.tmp" 2>/dev/null || true
|
|
53
|
+
|
|
54
|
+
# ---- 检查 /ql/data 目录(Volume 挂载点,不在用户数据卷内创建临时文件) ----
|
|
55
|
+
if [ ! -w "$QL_DIR/data" ] || [ ! -x "$QL_DIR/data" ]; then
|
|
56
|
+
if chown "$current_uid:$current_gid" "$QL_DIR/data" 2>/dev/null; then
|
|
57
|
+
log_with_style "INFO" "已修正 /ql/data 目录权限: UID=$current_uid GID=$current_gid"
|
|
58
|
+
if [ ! -w "$QL_DIR/data" ] || [ ! -x "$QL_DIR/data" ]; then
|
|
59
|
+
log_with_style "ERROR" "修正后仍无法写入 /ql/data,请检查挂载的数据卷权限"
|
|
60
|
+
log_with_style "ERROR" "确保宿主机目录: chown -R $current_uid:$current_gid /your/data"
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
else
|
|
64
|
+
local data_owner
|
|
65
|
+
data_owner=$(stat -c '%u' "$QL_DIR/data" 2>/dev/null || stat -f '%u' "$QL_DIR/data" 2>/dev/null)
|
|
66
|
+
log_with_style "ERROR" "============================================="
|
|
67
|
+
log_with_style "ERROR" " 权限错误:无法写入 /ql/data (Volume 挂载点)"
|
|
68
|
+
log_with_style "ERROR" " 当前用户 UID: $current_uid"
|
|
69
|
+
log_with_style "ERROR" " /ql/data 所有者 UID: ${data_owner:-未知}"
|
|
70
|
+
log_with_style "ERROR" ""
|
|
71
|
+
log_with_style "ERROR" " 请修正宿主机数据目录权限:"
|
|
72
|
+
log_with_style "ERROR" " chown -R $current_uid:$current_gid /your/ql/data"
|
|
73
|
+
log_with_style "ERROR" "============================================="
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
}
|
|
78
|
+
|
|
18
79
|
# Fix DNS resolution issues in Alpine Linux
|
|
19
|
-
# Alpine uses musl libc which has known DNS resolver issues with certain domains
|
|
20
|
-
# Adding ndots:0 prevents unnecessary search domain appending
|
|
21
80
|
if [ -f /etc/alpine-release ]; then
|
|
22
81
|
if ! grep -q "^options ndots:0" /etc/resolv.conf 2>/dev/null; then
|
|
23
82
|
echo "options ndots:0" >> /etc/resolv.conf
|
|
@@ -25,6 +84,26 @@ if [ -f /etc/alpine-release ]; then
|
|
|
25
84
|
fi
|
|
26
85
|
fi
|
|
27
86
|
|
|
87
|
+
# 确保 /etc/hosts 包含 localhost 解析(应对精简镜像或仅 IPv4/IPv6 环境)
|
|
88
|
+
if ! grep -qE '^127\.0\.0\.1[[:space:]]+.*localhost' /etc/hosts 2>/dev/null; then
|
|
89
|
+
echo "127.0.0.1 localhost" >> /etc/hosts
|
|
90
|
+
log_with_style "INFO" "🔧 0. 已添加 IPv4 localhost 解析"
|
|
91
|
+
fi
|
|
92
|
+
if ! grep -qE '^::1[[:space:]]+.*localhost' /etc/hosts 2>/dev/null; then
|
|
93
|
+
echo "::1 localhost ip6-localhost ip6-loopback" >> /etc/hosts
|
|
94
|
+
log_with_style "INFO" "🔧 0. 已添加 IPv6 localhost 解析"
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# 自定义用户(非 qinglong/root)可能 HOME 为空或不可写
|
|
98
|
+
# 修正 HOME 确保 npm/pip/pm2 等工具有可用的缓存目录
|
|
99
|
+
if [ ! -w "$HOME" ]; then
|
|
100
|
+
mkdir -p "$QL_DIR/.tmp"
|
|
101
|
+
export HOME="$QL_DIR/.tmp"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# 在一切操作之前检查目录权限
|
|
105
|
+
ensure_ql_permissions
|
|
106
|
+
|
|
28
107
|
log_with_style "INFO" "🚀 1. 检测配置文件..."
|
|
29
108
|
load_ql_envs
|
|
30
109
|
export_ql_envs
|
|
@@ -50,6 +129,19 @@ fi
|
|
|
50
129
|
|
|
51
130
|
log_with_style "SUCCESS" "🎉 容器启动成功!"
|
|
52
131
|
|
|
53
|
-
|
|
132
|
+
# 自动检测调度模式:有 crond 二进制 → system 模式,否则 node 模式
|
|
133
|
+
if [ -z "$QL_SCHEDULER" ]; then
|
|
134
|
+
if command -v crond &>/dev/null; then
|
|
135
|
+
export QL_SCHEDULER="system"
|
|
136
|
+
else
|
|
137
|
+
export QL_SCHEDULER="node"
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
if [ "$QL_SCHEDULER" = "system" ]; then
|
|
142
|
+
crond -f > /dev/null
|
|
143
|
+
else
|
|
144
|
+
tail -f /dev/null
|
|
145
|
+
fi
|
|
54
146
|
|
|
55
147
|
exec "$@"
|