chore: 合并 debian 和 alpine 逻辑

This commit is contained in:
whyour 2026-05-30 18:00:31 +08:00
parent 3d536297a1
commit 092a960dd6
10 changed files with 614 additions and 215 deletions

View File

@ -7,8 +7,6 @@ on:
branches:
- "master"
- "develop"
- "debian"
- "debian-dev"
tags:
- "v*"
workflow_dispatch:
@ -91,9 +89,6 @@ jobs:
env:
GITHUB_REPO: github.com/${{ github.repository_owner }}/qinglong-static
GITHUB_BRANCH: ${{ github.ref_name }}
REPO_GITEE: git@gitee.com:whyour/qinglong-static.git
REPO_GITLAB: git@gitlab.com:whyour/qinglong-static.git
PRIVATE_KEY: ${{ secrets.GITLAB_SSH_PK }}
run: |
mkdir -p tmp
cd ./tmp
@ -137,16 +132,13 @@ jobs:
git remote set-url origin git@gitee.com:whyour/qinglong-static.git
git push --force --mirror
build:
build-alpine:
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
needs: build-static
runs-on: ubuntu-22.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
@ -162,11 +154,9 @@ jobs:
run: |
VERSION=$(grep '^version:' version.yaml | awk '{print $2}')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Setup timezone
run: |
sudo timedatectl set-timezone Asia/Shanghai
run: sudo timedatectl set-timezone Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v4
@ -191,9 +181,9 @@ jobs:
flavor: |
latest=false
tags: |
type=ref,event=branch,enable=${{ github.ref == format('refs/heads/{0}', 'debian-dev') }}
type=ref,event=branch,enable=${{ github.ref == format('refs/heads/{0}', 'debian') }}
type=raw,value=${{ steps.version.outputs.version }}-debian,enable=${{ github.ref == format('refs/heads/{0}', 'debian') }}
type=ref,event=branch,enable=${{ github.ref == format('refs/heads/{0}', 'develop') }}
type=ref,event=branch,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=semver,pattern={{version}}
- name: Set up QEMU
@ -202,8 +192,7 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and push
id: docker_build
- name: Build and push (Alpine)
uses: docker/build-push-action@v7
with:
build-args: |
@ -211,29 +200,22 @@ jobs:
QL_BRANCH=${{ github.ref_name }}
SOURCE_COMMIT=${{ github.sha }}
network: host
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/386
context: .
file: ./docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=whyour/qinglong:cache-debian
cache-to: type=registry,ref=whyour/qinglong:cache-debian,mode=max
cache-from: type=registry,ref=whyour/qinglong:cache-alpine
cache-to: type=registry,ref=whyour/qinglong:cache-alpine,mode=max
- name: Image digest
run: |
echo ${{ steps.docker_build.outputs.digest }}
build310:
if: ${{ github.ref_name == 'debian' }}
build-debian:
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
needs: build-static
runs-on: ubuntu-22.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
@ -249,11 +231,85 @@ jobs:
run: |
VERSION=$(grep '^version:' version.yaml | awk '{print $2}')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Setup timezone
run: sudo timedatectl set-timezone Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v6
with:
images: |
${{ github.repository }}
ghcr.io/${{ github.repository }}
flavor: |
latest=false
tags: |
type=raw,value=debian-dev,enable=${{ github.ref == format('refs/heads/{0}', 'develop') }}
type=raw,value=debian,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
type=raw,value=${{ steps.version.outputs.version }}-debian,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and push (Debian)
uses: docker/build-push-action@v7
with:
build-args: |
MAINTAINER=${{ github.repository_owner }}
QL_BRANCH=${{ github.ref_name }}
SOURCE_COMMIT=${{ github.sha }}
network: host
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
context: .
file: ./docker/Dockerfile.debian
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=whyour/qinglong:cache-debian
cache-to: type=registry,ref=whyour/qinglong:cache-debian,mode=max
build-alpine310:
if: ${{ github.ref_name == 'master' }}
needs: build-static
runs-on: ubuntu-22.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: "8.3.1"
- uses: actions/setup-node@v6
with:
cache: "pnpm"
cache-dependency-path: pnpm-lock.yaml
- name: Read version from version.yaml
id: version
run: |
sudo timedatectl set-timezone Asia/Shanghai
VERSION=$(grep '^version:' version.yaml | awk '{print $2}')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Setup timezone
run: sudo timedatectl set-timezone Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v4
@ -274,8 +330,70 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and push python3.10
id: docker_build_310
- name: Build and push (Alpine Python 3.10)
uses: docker/build-push-action@v7
with:
build-args: |
MAINTAINER=${{ github.repository_owner }}
QL_BRANCH=${{ github.ref_name }}
SOURCE_COMMIT=${{ github.sha }}
network: host
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/386
context: .
file: ./docker/310.Dockerfile
push: true
tags: |
whyour/qinglong:python3.10
whyour/qinglong:${{ steps.version.outputs.version }}-python3.10
cache-from: type=registry,ref=whyour/qinglong:cache-alpine-python3.10
cache-to: type=registry,ref=whyour/qinglong:cache-alpine-python3.10,mode=max
build-debian310:
if: ${{ github.ref_name == 'master' }}
needs: build-static
runs-on: ubuntu-22.04
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: "8.3.1"
- uses: actions/setup-node@v6
with:
cache: "pnpm"
cache-dependency-path: pnpm-lock.yaml
- name: Read version from version.yaml
id: version
run: |
VERSION=$(grep '^version:' version.yaml | awk '{print $2}')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Setup timezone
run: sudo timedatectl set-timezone Asia/Shanghai
- name: Login to DockerHub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and push (Debian Python 3.10)
uses: docker/build-push-action@v7
with:
build-args: |
@ -285,7 +403,7 @@ jobs:
network: host
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
context: .
file: ./docker/310.Dockerfile
file: ./docker/310.Dockerfile.debian
push: true
tags: |
whyour/qinglong:debian-python3.10
@ -293,14 +411,9 @@ jobs:
cache-from: type=registry,ref=whyour/qinglong:cache-debian-python3.10
cache-to: type=registry,ref=whyour/qinglong:cache-debian-python3.10,mode=max
- name: Image digest
run: |
echo ${{ steps.docker_build_310.outputs.digest }}
publish:
if: ${{ github.ref_name == 'debian' }}
needs: build
if: ${{ github.ref_name == 'master' }}
needs: [build-alpine, build-debian]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -318,7 +431,7 @@ jobs:
pnpm build:front
pnpm build:back
- name: publich npm package
- name: publish npm package
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc
npm publish

View File

@ -1,6 +1,6 @@
import * as fs from 'fs/promises';
import * as path from 'path';
import { exec } from 'child_process';
import { exec, execSync } from 'child_process';
import psTreeFun from 'ps-tree';
import { promisify } from 'util';
import { load } from 'js-yaml';
@ -16,6 +16,32 @@ export * from './share';
let osType: 'Debian' | 'Ubuntu' | 'Alpine' | undefined;
function getOsTypeSync(): 'Debian' | 'Ubuntu' | 'Alpine' | undefined {
// 1. 环境变量覆盖
const envOs = process.env.QL_OS_TYPE?.toLowerCase();
if (envOs === 'alpine') return 'Alpine';
if (envOs === 'debian') return 'Debian';
if (envOs === 'ubuntu') return 'Ubuntu';
// 2. 模块缓存(由 detectOS 设置)
if (osType) return osType;
// 3. 能力检测:检查包管理器二进制
try {
execSync('which apt-get', { stdio: 'ignore' });
return 'Debian';
} catch {
try {
execSync('which apk', { stdio: 'ignore' });
return 'Alpine';
} catch {
// macOS / 未知系统
}
}
return undefined;
}
export async function getFileContentByName(fileName: string) {
const _exsit = await fileExist(fileName);
if (_exsit) {
@ -553,7 +579,9 @@ except:
spec=u.find_spec(name)
print(name if spec else '')
''')"`,
[DependenceTypes.linux]: `apt-get info ${name}`,
[DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
? `apk info -es ${name}`
: `dpkg-query -s ${name}`,
};
return baseCommands[type];
@ -564,7 +592,9 @@ export function getInstallCommand(type: DependenceTypes, name: string): string {
[DependenceTypes.nodejs]: 'pnpm add -g',
[DependenceTypes.python3]:
'pip3 install --disable-pip-version-check --root-user-action=ignore',
[DependenceTypes.linux]: 'apt install -y',
[DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
? 'apk add --no-check-certificate'
: 'apt-get install -y',
};
let command = baseCommands[type];
@ -584,7 +614,9 @@ export function getUninstallCommand(
[DependenceTypes.nodejs]: 'pnpm remove -g',
[DependenceTypes.python3]:
'pip3 uninstall --disable-pip-version-check --root-user-action=ignore -y',
[DependenceTypes.linux]: 'apt remove -y',
[DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
? 'apk del'
: 'apt-get remove -y',
};
return `${baseCommands[type]} ${name.trim()}`;
@ -619,6 +651,21 @@ export async function detectOS(): Promise<
'Debian' | 'Ubuntu' | 'Alpine' | undefined
> {
if (osType) return osType;
const envOs = process.env.QL_OS_TYPE?.toLowerCase();
if (envOs === 'alpine') {
osType = 'Alpine';
return osType;
}
if (envOs === 'debian') {
osType = 'Debian';
return osType;
}
if (envOs === 'ubuntu') {
osType = 'Ubuntu';
return osType;
}
const platform = os.platform();
if (platform === 'linux') {

View File

@ -39,6 +39,25 @@ export default class CronService {
return false;
}
private get schedulerMode(): 'system' | 'node' {
const env = process.env.QL_SCHEDULER;
if (env === 'system') return 'system';
if (env === 'node') return 'node';
try {
execSync('which crond', { stdio: 'ignore' });
return 'system';
} catch {
return 'node';
}
}
private shouldUseCronClient(cron: Crontab): boolean {
if (this.schedulerMode === 'node') {
return !this.isSpecialSchedule(cron.schedule);
}
return this.isNodeCron(cron) && !this.isSpecialSchedule(cron.schedule);
}
private isOnceSchedule(schedule?: string) {
return schedule?.startsWith(ScheduleType.ONCE);
}
@ -80,7 +99,7 @@ export default class CronService {
return doc;
}
if (!this.isSpecialSchedule(doc.schedule)) {
if (this.shouldUseCronClient(doc)) {
await cronClient.addCron([
{
name: doc.name || '',
@ -113,7 +132,7 @@ export default class CronService {
await cronClient.delCron([String(newDoc.id)]);
if (!this.isSpecialSchedule(newDoc.schedule)) {
if (this.shouldUseCronClient(newDoc)) {
await cronClient.addCron([
{
name: doc.name || '',
@ -575,18 +594,20 @@ export default class CronService {
public async enabled(ids: number[]) {
await CrontabModel.update({ isDisabled: 0 }, { where: { id: ids } });
const docs = await CrontabModel.findAll({ where: { id: ids } });
const crons = docs.map((doc) => ({
name: doc.name || '',
id: String(doc.id),
schedule: doc.schedule!,
command: this.makeCommand(doc),
extra_schedules: doc.extra_schedules || [],
}));
const crons = docs
.filter((x) => this.shouldUseCronClient(x))
.map((doc) => ({
name: doc.name || '',
id: String(doc.id),
schedule: doc.schedule!,
command: this.makeCommand(doc),
extra_schedules: doc.extra_schedules || [],
}));
if (isDemoEnv()) {
return;
}
await cronClient.addCron(crons);
await this.setCrontab();
}
@ -687,6 +708,15 @@ export default class CronService {
await writeFileWithLock(config.crontabFile, crontab_string);
if (this.schedulerMode === 'system') {
try {
execSync(`crontab ${config.crontabFile}`);
} catch (error: any) {
const errorMsg = error.message || String(error);
this.logger.error('[crontab] Failed to update system crontab:', errorMsg);
}
}
await CrontabModel.update({ saved: true }, { where: {} });
}
@ -732,7 +762,11 @@ export default class CronService {
public async autosave_crontab() {
const tabs = await this.crontabs();
const regularCrons = tabs.data
.filter((x) => x.isDisabled !== 1 && !this.isSpecialSchedule(x.schedule))
.filter(
(x) =>
x.isDisabled !== 1 &&
this.shouldUseCronClient(x),
)
.map((doc) => ({
name: doc.name || '',
id: String(doc.id),

View File

@ -1,18 +1,13 @@
FROM node:22-slim AS nodebuilder
FROM python:3.10-slim-bookworm AS builder
FROM python:3.10-alpine3.18 AS builder
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
apt-get update && \
apt-get install --no-install-recommends -y libatomic1 && \
npm i -g pnpm@8.3.1 && \
cd /tmp/build && \
pnpm install --prod
RUN set -x \
&& apk update \
&& apk add nodejs npm git \
&& npm i -g pnpm@8.3.1 pm2 ts-node \
&& cd /tmp/build \
&& pnpm install --prod
FROM python:3.10-slim-bookworm
FROM python:3.10-alpine
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
@ -26,63 +21,51 @@ ENV QL_DIR=/ql \
SHELL=/bin/bash \
PS1="\u@\h:\w \$ "
ARG QL_UID=5432
ARG QL_GID=5432
RUN groupadd -g ${QL_GID} qinglong && \
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
chmod 700 /home/qinglong/.ssh && \
chown -R ${QL_UID}:${QL_GID} /home/qinglong
VOLUME /ql/data
ENV QL_USER=qinglong
ENV QL_HOME=/home/$QL_USER
EXPOSE 5700
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/bin/. /usr/local/bin/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y git \
RUN set -x \
&& apk update -f \
&& apk upgrade \
&& apk --no-cache add -f bash \
coreutils \
git \
curl \
wget \
tzdata \
perl \
openssl \
openssh-client \
nodejs \
jq \
openssh \
procps \
netcat-openbsd \
unzip \
libatomic1 && \
apt-get clean && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" >/etc/timezone && \
git config --global user.email "qinglong@users.noreply.github.com" && \
git config --global user.name "qinglong" && \
git config --global http.postBuffer 524288000 && \
npm install -g pnpm@8.3.1 pm2 ts-node && \
rm -rf /root/.cache && \
rm -rf /root/.npm && \
rm -rf /etc/apt/apt.conf.d/docker-clean && \
ulimit -c 0
RUN mkdir -p ${QL_DIR} ${QL_DIR}/data && \
chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
USER qinglong
npm \
&& rm -rf /var/cache/apk/* \
&& apk update \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& git config --global user.email "qinglong@users.noreply.github.com" \
&& git config --global user.name "qinglong" \
&& git config --global http.postBuffer 524288000 \
&& rm -rf /root/.cache \
&& ulimit -c 0
ARG SOURCE_COMMIT
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
cd ${QL_DIR} && \
cp -f .env.example .env && \
chmod 777 ${QL_DIR}/shell/*.sh && \
chmod 777 ${QL_DIR}/docker/*.sh && \
git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /tmp/static && \
mkdir -p ${QL_DIR}/static && \
cp -rf /tmp/static/* ${QL_DIR}/static && \
rm -rf /tmp/static
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \
&& cd ${QL_DIR} \
&& cp -f .env.example .env \
&& chmod 777 ${QL_DIR}/shell/*.sh \
&& chmod 777 ${QL_DIR}/docker/*.sh \
&& git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /static \
&& mkdir -p ${QL_DIR}/static \
&& cp -rf /static/* ${QL_DIR}/static \
&& rm -rf /static
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
@ -96,9 +79,7 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOM
RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node_modules/
USER root
COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
WORKDIR ${QL_DIR}
@ -106,7 +87,3 @@ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf --noproxy '*' http://localhost:${QlPort:-5700}/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
VOLUME /ql/data
EXPOSE 5700

View File

@ -0,0 +1,112 @@
FROM node:22-slim AS nodebuilder
FROM python:3.10-slim-bookworm AS builder
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
apt-get update && \
apt-get install --no-install-recommends -y libatomic1 && \
npm i -g pnpm@8.3.1 && \
cd /tmp/build && \
pnpm install --prod
FROM python:3.10-slim-bookworm
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
ARG QL_URL=https://github.com/${QL_MAINTAINER}/qinglong.git
ARG QL_BRANCH=develop
ARG PYTHON_SHORT_VERSION=3.10
ENV QL_DIR=/ql \
QL_BRANCH=${QL_BRANCH} \
LANG=C.UTF-8 \
SHELL=/bin/bash \
PS1="\u@\h:\w \$ "
ARG QL_UID=5432
ARG QL_GID=5432
RUN groupadd -g ${QL_GID} qinglong && \
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
chmod 700 /home/qinglong/.ssh && \
chown -R ${QL_UID}:${QL_GID} /home/qinglong
ENV QL_USER=qinglong
ENV QL_HOME=/home/$QL_USER
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y git \
curl \
wget \
tzdata \
perl \
openssl \
openssh-client \
jq \
procps \
netcat-openbsd \
unzip \
libatomic1 && \
apt-get clean && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" >/etc/timezone && \
git config --global user.email "qinglong@users.noreply.github.com" && \
git config --global user.name "qinglong" && \
git config --global http.postBuffer 524288000 && \
npm install -g pnpm@8.3.1 pm2 ts-node && \
rm -rf /root/.cache && \
rm -rf /root/.npm && \
rm -rf /etc/apt/apt.conf.d/docker-clean && \
ulimit -c 0
RUN mkdir -p ${QL_DIR} ${QL_DIR}/data && \
chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
USER qinglong
ARG SOURCE_COMMIT
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
cd ${QL_DIR} && \
cp -f .env.example .env && \
chmod 777 ${QL_DIR}/shell/*.sh && \
chmod 777 ${QL_DIR}/docker/*.sh && \
git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /tmp/static && \
mkdir -p ${QL_DIR}/static && \
cp -rf /tmp/static/* ${QL_DIR}/static && \
rm -rf /tmp/static
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \
HOME=/root
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \
PIP_CACHE_DIR=${PYTHON_HOME}/pip \
PYTHONPATH=${PYTHON_HOME}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}/site-packages
RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node_modules/
USER root
WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf --noproxy '*' http://localhost:${QlPort:-5700}/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
VOLUME /ql/data
EXPOSE 5700

View File

@ -1,18 +1,13 @@
FROM node:22-slim AS nodebuilder
FROM python:3.11-slim-bookworm AS builder
FROM python:3.11-alpine3.18 AS builder
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
apt-get update && \
apt-get install --no-install-recommends -y libatomic1 && \
npm i -g pnpm@8.3.1 && \
cd /tmp/build && \
pnpm install --prod
RUN set -x \
&& apk update \
&& apk add nodejs npm git \
&& npm i -g pnpm@8.3.1 pm2 ts-node \
&& cd /tmp/build \
&& pnpm install --prod
FROM python:3.11-slim-bookworm
FROM python:3.11-alpine
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
@ -26,63 +21,51 @@ ENV QL_DIR=/ql \
SHELL=/bin/bash \
PS1="\u@\h:\w \$ "
ARG QL_UID=5432
ARG QL_GID=5432
RUN groupadd -g ${QL_GID} qinglong && \
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
chmod 700 /home/qinglong/.ssh && \
chown -R ${QL_UID}:${QL_GID} /home/qinglong
VOLUME /ql/data
ENV QL_USER=qinglong
ENV QL_HOME=/home/$QL_USER
EXPOSE 5700
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
COPY --from=builder /usr/local/bin/. /usr/local/bin/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx && \
apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y git \
RUN set -x \
&& apk update -f \
&& apk upgrade \
&& apk --no-cache add -f bash \
coreutils \
git \
curl \
wget \
tzdata \
perl \
openssl \
openssh-client \
nodejs \
jq \
openssh \
procps \
netcat-openbsd \
unzip \
libatomic1 && \
apt-get clean && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" >/etc/timezone && \
git config --global user.email "qinglong@users.noreply.github.com" && \
git config --global user.name "qinglong" && \
git config --global http.postBuffer 524288000 && \
npm install -g pnpm@8.3.1 pm2 ts-node && \
rm -rf /root/.cache && \
rm -rf /root/.npm && \
rm -rf /etc/apt/apt.conf.d/docker-clean && \
ulimit -c 0
npm \
&& rm -rf /var/cache/apk/* \
&& apk update \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& git config --global user.email "qinglong@users.noreply.github.com" \
&& git config --global user.name "qinglong" \
&& git config --global http.postBuffer 524288000 \
&& rm -rf /root/.cache \
&& ulimit -c 0
RUN mkdir -p ${QL_DIR} ${QL_DIR}/data && \
chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
USER qinglong
ARG SOURCE_COMMIT
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
cd ${QL_DIR} && \
cp -f .env.example .env && \
chmod 777 ${QL_DIR}/shell/*.sh && \
chmod 777 ${QL_DIR}/docker/*.sh && \
git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /tmp/static && \
mkdir -p ${QL_DIR}/static && \
cp -rf /tmp/static/* ${QL_DIR}/static && \
rm -rf /tmp/static
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \
&& cd ${QL_DIR} \
&& cp -f .env.example .env \
&& chmod 777 ${QL_DIR}/shell/*.sh \
&& chmod 777 ${QL_DIR}/docker/*.sh \
&& git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /static \
&& mkdir -p ${QL_DIR}/static \
&& cp -rf /static/* ${QL_DIR}/static \
&& rm -rf /static
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
@ -96,9 +79,7 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOM
RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node_modules/
USER root
COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
WORKDIR ${QL_DIR}
@ -106,7 +87,3 @@ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf --noproxy '*' http://localhost:${QlPort:-5700}/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
VOLUME /ql/data
EXPOSE 5700

112
docker/Dockerfile.debian Normal file
View File

@ -0,0 +1,112 @@
FROM node:22-slim AS nodebuilder
FROM python:3.11-slim-bookworm AS builder
COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
apt-get update && \
apt-get install --no-install-recommends -y libatomic1 && \
npm i -g pnpm@8.3.1 && \
cd /tmp/build && \
pnpm install --prod
FROM python:3.11-slim-bookworm
ARG QL_MAINTAINER="whyour"
LABEL maintainer="${QL_MAINTAINER}"
ARG QL_URL=https://github.com/${QL_MAINTAINER}/qinglong.git
ARG QL_BRANCH=develop
ARG PYTHON_SHORT_VERSION=3.11
ENV QL_DIR=/ql \
QL_BRANCH=${QL_BRANCH} \
LANG=C.UTF-8 \
SHELL=/bin/bash \
PS1="\u@\h:\w \$ "
ARG QL_UID=5432
ARG QL_GID=5432
RUN groupadd -g ${QL_GID} qinglong && \
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
chmod 700 /home/qinglong/.ssh && \
chown -R ${QL_UID}:${QL_GID} /home/qinglong
ENV QL_USER=qinglong
ENV QL_HOME=/home/$QL_USER
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/
COPY --from=nodebuilder /usr/local/lib/node_modules/. /usr/local/lib/node_modules/
RUN set -x && \
ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx && \
apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y git \
curl \
wget \
tzdata \
perl \
openssl \
openssh-client \
jq \
procps \
netcat-openbsd \
unzip \
libatomic1 && \
apt-get clean && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" >/etc/timezone && \
git config --global user.email "qinglong@users.noreply.github.com" && \
git config --global user.name "qinglong" && \
git config --global http.postBuffer 524288000 && \
npm install -g pnpm@8.3.1 pm2 ts-node && \
rm -rf /root/.cache && \
rm -rf /root/.npm && \
rm -rf /etc/apt/apt.conf.d/docker-clean && \
ulimit -c 0
RUN mkdir -p ${QL_DIR} ${QL_DIR}/data && \
chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
USER qinglong
ARG SOURCE_COMMIT
RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
cd ${QL_DIR} && \
cp -f .env.example .env && \
chmod 777 ${QL_DIR}/shell/*.sh && \
chmod 777 ${QL_DIR}/docker/*.sh && \
git clone --depth=1 -b ${QL_BRANCH} https://github.com/${QL_MAINTAINER}/qinglong-static.git /tmp/static && \
mkdir -p ${QL_DIR}/static && \
cp -rf /tmp/static/* ${QL_DIR}/static && \
rm -rf /tmp/static
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \
HOME=/root
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \
PIP_CACHE_DIR=${PYTHON_HOME}/pip \
PYTHONPATH=${PYTHON_HOME}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}:${PYTHON_HOME}/lib/python${PYTHON_SHORT_VERSION}/site-packages
RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node_modules/
USER root
WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf --noproxy '*' http://localhost:${QlPort:-5700}/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
VOLUME /ql/data
EXPOSE 5700

View File

@ -128,6 +128,19 @@ fi
log_with_style "SUCCESS" "🎉 容器启动成功!"
tail -f /dev/null
# 自动检测调度模式:有 crond 二进制 → system 模式,否则 node 模式
if [ -z "$QL_SCHEDULER" ]; then
if command -v crond &>/dev/null; then
export QL_SCHEDULER="system"
else
export QL_SCHEDULER="node"
fi
fi
if [ "$QL_SCHEDULER" = "system" ]; then
crond -f > /dev/null
else
tail -f /dev/null
fi
exec "$@"

View File

@ -9,15 +9,22 @@ else
fi
echo -e "\n1、安装bot依赖...\n"
os_name=$(source /etc/os-release && echo "$ID")
if [[ $os_name == 'alpine' ]]; then
apk --no-cache add -f zlib-dev gcc jpeg-dev python3-dev musl-dev freetype-dev
elif [[ $os_name == 'debian' ]] || [[ $os_name == 'ubuntu' ]]; then
apt-get install -y gcc python3-dev musl-dev
else
echo -e "暂不支持此系统 $os_name"
exit 1
os_name="${QL_OS_TYPE:-}"
if [ -z "$os_name" ]; then
os_name=$(source /etc/os-release && echo "$ID")
fi
case "$os_name" in
alpine)
apk --no-cache add -f zlib-dev gcc jpeg-dev python3-dev musl-dev freetype-dev
;;
debian|ubuntu)
apt-get install -y gcc python3-dev musl-dev zlib1g-dev libjpeg-dev libfreetype-dev
;;
*)
echo -e "暂不支持此系统 $os_name"
exit 1
;;
esac
echo -e "\nbot依赖安装成功...\n"
echo -e "2、下载bot所需文件...\n"

View File

@ -36,31 +36,38 @@ command="$1"
if [[ $command != "reload" ]]; then
# 安装依赖
os_name=$(source /etc/os-release && echo "$ID")
if [[ $os_name == 'alpine' ]]; then
apk update
apk add -f bash \
coreutils \
git \
curl \
wget \
tzdata \
perl \
openssl \
jq \
nginx \
openssh \
procps \
netcat-openbsd
elif [[ $os_name == 'debian' ]] || [[ $os_name == 'ubuntu' ]]; then
apt-get update
apt-get install -y git curl wget tzdata perl openssl jq nginx procps netcat-openbsd openssh-client
else
echo -e "暂不支持此系统部署 $os_name"
exit 1
os_name="${QL_OS_TYPE:-}"
if [ -z "$os_name" ]; then
os_name=$(source /etc/os-release && echo "$ID")
fi
case "$os_name" in
alpine)
apk update
apk add -f bash \
coreutils \
git \
curl \
wget \
tzdata \
perl \
openssl \
jq \
nginx \
openssh \
procps \
netcat-openbsd
;;
debian|ubuntu)
apt-get update
apt-get install -y git curl wget tzdata perl openssl jq nginx procps netcat-openbsd openssh-client
;;
*)
echo -e "暂不支持此系统部署 $os_name"
exit 1
;;
esac
npm install -g pnpm@8.3.1 pm2 ts-node
fi