Repository navigation
Expand file tree
/
Copy pathbuild-docker-linux.sh
More file actions
executable file
·375 lines (339 loc) · 12.3 KB
/
Copy pathbuild-docker-linux.sh
File metadata and controls
executable file
·375 lines (339 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#!/bin/bash
# QrCodeGen Linux Docker 一键打包脚本
# 使用 electron-builder 官方 Docker 镜像在容器内打包 Linux 包,
# 无需本地安装 dpkg-deb / rpmbuild 等工具链。
#
# 用法:
# ./build-docker-linux.sh # 默认打包 deb
# ./build-docker-linux.sh deb # 只打包 deb
# ./build-docker-linux.sh deb x64 # 打包 deb, 指定架构 x64
# ./build-docker-linux.sh deb arm64 # 打包 deb, 指定架构 arm64
# ./build-docker-linux.sh deb all # 打包 deb, x64 + arm64
# ./build-docker-linux.sh appimage # 只打包 AppImage
# ./build-docker-linux.sh appimage x64
# ./build-docker-linux.sh -h|--help # 显示帮助
#
# 注: rpm 格式使用独立的 Fedora 容器脚本 build-docker-rpm.sh,
# 该脚本基于 fedora:39 镜像 (内置 rpmbuild)。
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$SCRIPT_DIR"
# ==================== 参数解析 ====================
TARGET="deb"
ARCH="" # 空表示当前主机架构; 可选 x64 / arm64 / all
show_help() {
cat <<EOF
QrCodeGen Linux Docker 一键打包脚本
用法:
$0 [target] [arch]
target:
deb 打包 deb (Debian/Ubuntu) [默认]
appimage 打包 AppImage (通用 Linux)
rpm 跳转至 build-docker-rpm.sh (Fedora 容器)
arch:
(空) 当前主机架构
x64 仅 x64 (amd64)
arm64 仅 arm64 (aarch64)
all 同时打包 x64 和 arm64
示例:
$0 # deb, 当前架构
$0 deb x64 # deb, x64
$0 deb all # deb, x64 + arm64
$0 appimage # AppImage, 当前架构
注意:
rpm 格式请使用独立脚本:
./build-docker-rpm.sh (Fedora 容器, 内置 rpmbuild)
或 npm run build:linux:docker:rpm
EOF
exit 0
}
for arg in "$@"; do
case $arg in
-h|--help) show_help ;;
deb|appimage|rpm) TARGET="$arg" ;;
x64|arm64|all) ARCH="$arg" ;;
*)
echo "未知参数: $arg"
echo "使用 $0 --help 查看帮助"
exit 1
;;
esac
done
# rpm 由独立的 Fedora 容器脚本处理
if [[ "$TARGET" == "rpm" ]]; then
echo "=========================================="
echo " rpm → 使用独立 Fedora 容器脚本"
echo "=========================================="
echo ""
echo "rpm 打包使用 Fedora 容器 (含 rpmbuild), 请运行:"
echo " ./build-docker-rpm.sh # 当前架构"
echo " ./build-docker-rpm.sh x64 # x64"
echo " ./build-docker-rpm.sh arm64 # arm64"
echo ""
echo "或通过 npm:"
echo " npm run build:linux:docker:rpm"
echo " npm run build:linux:docker:rpm:x64"
echo " npm run build:linux:docker:rpm:arm64"
exit 0
fi
echo "=========================================="
echo " QrCodeGen Linux Docker 打包"
echo " 目标: $TARGET 架构: ${ARCH:-当前主机}"
echo "=========================================="
# ==================== Docker 检测与安装 ====================
detect_os() {
case "$(uname -s)" in
Darwin) echo "macos" ;;
Linux)
if [[ -f /etc/os-release ]]; then
. /etc/os-release
case "$ID" in
ubuntu|debian|linuxmint|pop) echo "debian" ;;
fedora|rhel|centos|rocky|alma|amzn) echo "rhel" ;;
arch|manjaro) echo "arch" ;;
*) echo "linux_unknown" ;;
esac
else
echo "linux_unknown"
fi
;;
MINGW*|MSYS*|CYGWIN*) echo "windows" ;;
*) echo "unknown" ;;
esac
}
ensure_docker() {
if command -v docker &>/dev/null; then
if docker info &>/dev/null 2>&1; then
echo "✓ Docker 已就绪 ($(docker --version | awk '{print $3}' | tr -d ', '))"
return 0
else
echo "⚠ 检测到 docker 命令, 但守护进程未运行"
local os
os=$(detect_os)
case "$os" in
macos)
echo " 请启动 Docker Desktop (从应用程序或菜单栏)"
;;
debian|rhel|arch)
echo " 尝试启动 docker 服务..."
sudo systemctl start docker 2>/dev/null || true
if docker info &>/dev/null 2>&1; then
echo "✓ Docker 服务已启动"
return 0
fi
echo " 请手动执行: sudo systemctl start docker"
;;
esac
echo " 启动后重新运行本脚本"
exit 1
fi
fi
echo ""
echo ">>> 未检测到 Docker, 开始自动安装 (国内源)..."
local os
os=$(detect_os)
case "$os" in
macos)
install_docker_macos
;;
debian)
install_docker_debian
;;
rhel)
install_docker_rhel
;;
arch)
install_docker_arch
;;
windows)
echo "❌ Windows 请手动安装 Docker Desktop:"
echo " https://docs.docker.com/docker-for-windows/install/"
exit 1
;;
*)
echo "❌ 无法识别的操作系统, 请手动安装 Docker:"
echo " https://docs.docker.com/get-docker/"
exit 1
;;
esac
# 安装后再次校验
if ! command -v docker &>/dev/null; then
echo "❌ Docker 安装后仍未检测到 docker 命令"
echo " 请重新打开终端或重启 Docker Desktop 后重试"
exit 1
fi
if ! docker info &>/dev/null 2>&1; then
echo "⚠ Docker 已安装但守护进程未运行"
case "$os" in
macos) echo " 请启动 Docker Desktop" ;;
*) sudo systemctl start docker 2>/dev/null || true ;;
esac
if ! docker info &>/dev/null 2>&1; then
echo " 请手动启动 Docker 后重新运行本脚本"
exit 1
fi
fi
echo "✓ Docker 安装并启动成功"
}
install_docker_macos() {
if command -v brew &>/dev/null; then
echo " 使用 Homebrew cask 安装 Docker Desktop..."
brew install --cask docker || {
echo "❌ brew 安装失败, 请手动下载:"
echo " https://desktop.docker.com/mac/main/arm64/Docker.dmg"
exit 1
}
echo " 请启动 Docker Desktop 后重新运行本脚本"
exit 0
else
echo "❌ 未检测到 Homebrew, 请先安装 Homebrew:"
echo " /bin/bash -c \"\$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)\""
echo "或直接下载 Docker Desktop:"
echo " https://desktop.docker.com/mac/main/arm64/Docker.dmg"
exit 1
fi
}
install_docker_debian() {
echo " 使用阿里云镜像源安装 Docker (Debian/Ubuntu)..."
# 移除旧版本
sudo apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
sudo apt-get update -y
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# 添加阿里云 Docker GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 2>/dev/null || \
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 写入 apt 源 (按发行版区分)
local codename
codename=$(lsb_release -cs 2>/dev/null || echo "focal")
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://mirrors.aliyun.com/docker-ce/linux/ubuntu $codename stable" | \
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt-get update -y
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 启动并设置开机自启
sudo systemctl enable --now docker
# 将当前用户加入 docker 组 (免 sudo)
sudo usermod -aG docker "$USER" 2>/dev/null || true
echo " 提示: 已将用户 $USER 加入 docker 组, 需重新登录或执行 'newgrp docker' 生效"
}
install_docker_rhel() {
echo " 使用阿里云镜像源安装 Docker (RHEL/Fedora/CentOS)..."
sudo yum remove -y docker docker-client docker-client-latest \
docker-common docker-latest docker-latest-logrotate \
docker-logrotate docker-engine 2>/dev/null || true
sudo yum install -y yum-utils
# 阿里云 Docker CE 仓库
sudo yum-config-manager --add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER" 2>/dev/null || true
echo " 提示: 已将用户 $USER 加入 docker 组, 需重新登录或执行 'newgrp docker' 生效"
}
install_docker_arch() {
echo " 使用 pacman 安装 Docker (Arch/Manjaro)..."
sudo pacman -Sy --noconfirm docker docker-buildx docker-compose
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER" 2>/dev/null || true
echo " 提示: 已将用户 $USER 加入 docker 组, 需重新登录或执行 'newgrp docker' 生效"
}
# ==================== 依赖检查 ====================
ensure_node() {
if ! command -v node &>/dev/null; then
echo "❌ 未检测到 Node.js, 请先安装 Node.js >= 20"
echo " macOS: brew install node@20"
echo " Ubuntu: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt install -y nodejs"
echo " Fedora: sudo dnf install -y nodejs"
exit 1
fi
echo "✓ Node.js $(node --version)"
}
ensure_deps() {
echo ""
echo ">>> 检查项目依赖..."
if [[ ! -d "$PROJECT_DIR/node_modules" ]] || \
[[ ! -f "$PROJECT_DIR/node_modules/.bin/electron-builder" ]]; then
echo " 安装项目依赖..."
cd "$PROJECT_DIR" && npm install || {
echo "❌ npm install 失败"
exit 1
}
fi
echo "✓ 项目依赖就绪"
}
# ==================== 构建 ====================
run_builder() {
local target="$1"
local arch_arg="$2"
local cmd_args=(--linux "$target")
if [[ -n "$arch_arg" && "$arch_arg" != "all" ]]; then
cmd_args+=(--"$arch_arg")
fi
echo ""
echo ">>> 执行: electron-builder ${cmd_args[*]}"
echo " (Docker 模式: USE_DOCKER=true)"
cd "$PROJECT_DIR"
if [[ "$arch_arg" == "all" ]]; then
# 分别构建 x64 和 arm64
echo " -- 打包 x64 --"
USE_DOCKER=true npx electron-builder --linux "$target" --x64 || {
echo "❌ $target x64 打包失败"
exit 1
}
echo " -- 打包 arm64 --"
USE_DOCKER=true npx electron-builder --linux "$target" --arm64 || {
echo "❌ $target arm64 打包失败"
exit 1
}
else
USE_DOCKER=true npx electron-builder "${cmd_args[@]}" || {
echo "❌ $target ${arch_arg:-} 打包失败"
exit 1
}
fi
}
show_result() {
local target="$1"
echo ""
echo "=========================================="
echo " ✓ 打包完成!"
echo "=========================================="
echo ""
echo "输出目录: $PROJECT_DIR/electron-dist/"
echo ""
echo "产物文件:"
case "$target" in
deb)
ls -lh "$PROJECT_DIR"/electron-dist/*.deb 2>/dev/null | awk '{printf " %s %s\n", $5, $9}'
;;
appimage)
ls -lh "$PROJECT_DIR"/electron-dist/*.AppImage 2>/dev/null | awk '{printf " %s %s\n", $5, $9}'
;;
esac
echo ""
echo "安装方式:"
case "$target" in
deb)
echo " Debian/Ubuntu: sudo dpkg -i <文件名.deb>"
echo " 或: sudo apt install ./<文件名.deb>"
;;
appimage)
echo " chmod +x <文件名.AppImage>"
echo " ./<文件名.AppImage>"
;;
esac
echo ""
}
# ==================== 主流程 ====================
main() {
ensure_docker
ensure_node
ensure_deps
run_builder "$TARGET" "$ARCH"
show_result "$TARGET"
}
main