Docker+cpolar双剑合璧:在家搭建永久可用的HivisionIDPhotos证件照服务器
Docker与cpolar深度整合:构建高可用私人证件照服务系统
引言
证件照作为日常生活中高频使用的图像类型,其制作需求往往具有突发性和时效性。传统照相馆模式存在时间成本高、隐私风险大、重复修改不便等痛点。本文将介绍如何利用Docker容器化技术与cpolar内网穿透服务,搭建一套可随时随地访问的私人证件照制作系统。
这个方案特别适合以下场景:
- 经常需要更新证件照的商务人士
- 有多个家庭成员需要不同规格证件照的家庭
- 对隐私保护有较高要求的用户
- 希望降低长期证件照制作成本的技术爱好者
我们将从基础环境搭建开始,逐步深入到生产级部署的各个环节,重点解决临时地址不稳定、服务可靠性等实际问题。
1. 基础环境配置
1.1 Docker引擎安装与优化
在Ubuntu系统上安装Docker推荐使用官方脚本,但针对国内网络环境需要特别优化:
# 安装必要依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
# 添加Docker官方GPG密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# 设置稳定版仓库
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完成后,建议进行以下优化配置:
-
用户组配置:将当前用户加入docker组,避免每次使用sudo
sudo usermod -aG docker $USER newgrp docker -
日志限制:防止容器日志占用过多磁盘空间
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "registry-mirrors": ["https://docker.m.daocloud.io"] } EOF sudo systemctl restart docker
1.2 系统资源调优
为确保服务稳定运行,需要对系统参数进行调整:
# 增加系统最大文件描述符数量
echo "fs.file-max = 100000" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 调整内核参数优化网络性能
echo "net.core.somaxconn = 65535" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog = 65535" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
2. HivisionIDPhotos容器化部署
2.1 容器启动与配置
使用官方镜像启动服务时,建议添加资源限制和健康检查:
docker run -d \
--name hivision_idphotos \
--restart unless-stopped \
--memory 2g \
--cpus 1.5 \
-p 7860:7860 \
--health-cmd "curl -f http://localhost:7860 || exit 1" \
--health-interval 30s \
--health-timeout 10s \
--health-retries 3 \
linzeyi/hivision_idphotos
关键参数说明:
--restart unless-stopped:确保容器异常退出后自动重启--memory 2g:限制容器最大内存使用量--cpus 1.5:限制容器CPU使用量- 健康检查配置:每30秒检查一次服务可用性
2.2 持久化存储配置
为防止容器重建时数据丢失,应该将重要目录挂载到宿主机:
mkdir -p ~/hivision_data/{config,output}
docker run -d \
--name hivision_idphotos \
-v ~/hivision_data/config:/app/config \
-v ~/hivision_data/output:/app/output \
-p 7860:7860 \
linzeyi/hivision_idphotos
目录结构说明:
/app/config:保存应用配置/app/output:存储生成的证件照
3. cpolar高级配置技巧
3.1 服务安装与系统集成
cpolar的安装可以通过官方脚本完成,但生产环境建议配置为系统服务:
# 安装cpolar
curl https://get.cpolar.sh | sudo bash
# 创建系统服务配置文件
sudo tee /etc/systemd/system/cpolar.service <<-'EOF'
[Unit]
Description=Cpolar Service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/cpolar http 7860
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
# 启用并启动服务
sudo systemctl daemon-reload
sudo systemctl enable cpolar
sudo systemctl start cpolar
3.2 隧道管理最佳实践
创建隧道时,建议使用配置文件而非Web UI,便于版本控制和批量管理:
# 创建配置文件目录
mkdir -p ~/cpolar_config
# 生成隧道配置文件
cat > ~/cpolar_config/hivision_tunnel.yml <<EOF
tunnels:
hivision:
addr: 7860
proto: http
region: hk
hostname: myphotos.example.com
auth:
username: myuser
password: mypassword
EOF
# 使用配置文件启动隧道
cpolar start-all -config ~/cpolar_config/hivision_tunnel.yml
配置文件优势:
- 支持多个隧道集中管理
- 可以纳入版本控制系统
- 便于批量部署和迁移
4. 生产级部署方案
4.1 固定域名与HTTPS配置
要实现真正的生产级部署,需要配置固定域名和HTTPS加密:
-
域名准备:
- 注册一个专属域名(如yourdomain.com)
- 在DNS服务商处添加CNAME记录指向cpolar提供的域名
-
HTTPS配置:
# 使用Let's Encrypt获取SSL证书 sudo apt-get install -y certbot sudo certbot certonly --standalone -d myphotos.yourdomain.com # 配置cpolar使用SSL证书 cpolar http 7860 \ -hostname=myphotos.yourdomain.com \ -tls-cert=/etc/letsencrypt/live/myphotos.yourdomain.com/fullchain.pem \ -tls-key=/etc/letsencrypt/live/myphotos.yourdomain.com/privkey.pem -
证书自动续期:
# 创建续期脚本 sudo tee /etc/cron.weekly/renew_certs <<'EOF' #!/bin/bash certbot renew --quiet --post-hook "systemctl restart cpolar" EOF sudo chmod +x /etc/cron.weekly/renew_certs
4.2 高可用架构设计
对于关键业务场景,可以考虑以下高可用方案:
方案一:多节点负载均衡
用户请求 → 负载均衡器 → [节点1, 节点2, 节点3]
↘ 数据库集群
方案二:热备部署
- 主节点:在线提供服务
- 备节点:实时同步数据,主节点故障时自动切换
实现示例(使用Docker Swarm):
# 初始化Swarm集群
docker swarm init
# 部署服务
docker service create \
--name hivision_idphotos \
--replicas 3 \
--publish published=7860,target=7860 \
--mount type=bind,source=/path/to/shared/storage,target=/app/output \
linzeyi/hivision_idphotos
4.3 监控与告警系统
完善的监控体系应包括:
-
基础资源监控:
- CPU、内存、磁盘使用率
- 网络带宽利用率
-
服务健康监控:
- 服务响应时间
- 错误率
- 请求吞吐量
-
业务指标监控:
- 证件照生成数量
- 平均处理时间
- 用户满意度
推荐使用Prometheus+Grafana搭建监控平台:
# 启动Prometheus
docker run -d \
--name=prometheus \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
# 启动Grafana
docker run -d \
--name=grafana \
-p 3000:3000 \
grafana/grafana
5. 安全加固措施
5.1 访问控制策略
-
基础认证:
# 启动带基础认证的cpolar隧道 cpolar http 7860 \ -auth="username:password" -
IP白名单:
# 使用iptables限制访问IP sudo iptables -A INPUT -p tcp --dport 7860 -s 192.168.1.100 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 7860 -j DROP -
速率限制:
# 使用nginx作为反向代理并配置限流 docker run -d \ --name nginx_proxy \ -p 80:80 \ -v /path/to/nginx.conf:/etc/nginx/nginx.conf \ nginx
示例nginx.conf限流配置:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
location / {
limit_req zone=one burst=20;
proxy_pass http://hivision_idphotos:7860;
}
}
}
5.2 数据安全保护
-
加密存储:
# 使用eCryptFS创建加密目录 sudo apt-get install -y ecryptfs-utils mkdir -p ~/encrypted_photos sudo mount -t ecryptfs ~/hivision_data/output ~/encrypted_photos -
自动备份方案:
# 使用rsync进行增量备份 rsync -avz --delete ~/hivision_data/ backup_server:/backup/hivision/ # 设置定时任务 (crontab -l 2>/dev/null; echo "0 3 * * * rsync -avz --delete ~/hivision_data/ backup_server:/backup/hivision/") | crontab - -
敏感信息处理:
# 使用openssl加密配置文件 openssl enc -aes-256-cbc -salt -in config.yml -out config.yml.enc
6. 性能优化技巧
6.1 容器资源调优
通过cgroups限制资源使用:
docker update \
--cpus 2 \
--memory 4g \
--memory-swap 4g \
hivision_idphotos
建议监控指标:
- 容器CPU使用率(保持在70%以下)
- 内存使用量(避免频繁交换)
- 磁盘IOPS(特别是生成大量图片时)
6.2 网络性能优化
-
TCP参数调优:
echo "net.ipv4.tcp_tw_reuse = 1" | sudo tee -a /etc/sysctl.conf echo "net.ipv4.tcp_fin_timeout = 30" | sudo tee -a /etc/sysctl.conf sudo sysctl -p -
启用BBR拥塞控制:
echo "net.core.default_qdisc = fq" | sudo tee -a /etc/sysctl.conf echo "net.ipv4.tcp_congestion_control = bbr" | sudo tee -a /etc/sysctl.conf sudo sysctl -p
6.3 图片处理加速
-
GPU加速:
# 启用NVIDIA GPU支持 docker run -d \ --gpus all \ -p 7860:7860 \ linzeyi/hivision_idphotos -
内存缓存优化:
# 使用tmpfs加速临时文件访问 docker run -d \ --tmpfs /tmp:rw,size=1g \ -p 7860:7860 \ linzeyi/hivision_idphotos
7. 扩展功能开发
7.1 API集成方案
HivisionIDPhotos可以通过API与其他系统集成:
import requests
def generate_id_photo(image_path, size="1inch"):
url = "http://yourdomain.com/api/generate"
files = {'image': open(image_path, 'rb')}
data = {'size': size, 'background': 'white'}
response = requests.post(url, files=files, data=data)
if response.status_code == 200:
with open('output.jpg', 'wb') as f:
f.write(response.content)
return True
return False
7.2 批量处理功能
使用Shell脚本实现批量处理:
#!/bin/bash
INPUT_DIR="./input_photos"
OUTPUT_DIR="./output_photos"
for file in "$INPUT_DIR"/*.{jpg,jpeg,png}; do
filename=$(basename -- "$file")
curl -X POST \
-F "image=@$file" \
-F "size=1inch" \
-F "background=blue" \
"http://localhost:7860/api/generate" \
> "$OUTPUT_DIR/${filename%.*}_idphoto.jpg"
done
7.3 自定义模板开发
通过修改容器内的模板文件实现个性化:
# 进入容器shell
docker exec -it hivision_idphotos /bin/bash
# 修改模板文件
vi /app/templates/default.html
# 重启容器使更改生效
docker restart hivision_idphotos
8. 故障排查指南
8.1 常见问题解决
问题1:容器启动失败
- 检查日志:
docker logs hivision_idphotos - 验证端口冲突:
sudo netstat -tulnp | grep 7860 - 测试基础镜像:
docker run -it --rm linzeyi/hivision_idphotos /bin/bash
问题2:cpolar连接不稳定
- 检查网络延迟:
ping cpolar.cn - 验证防火墙设置:
sudo ufw status - 测试不同区域:更换
region参数为hk或us
8.2 性能瓶颈分析
使用工具进行系统性能分析:
# 容器资源使用情况
docker stats hivision_idphotos
# 系统级监控
sudo apt-get install -y htop
htop
# 网络流量分析
sudo apt-get install -y iftop
sudo iftop -P -n -i eth0
8.3 日志分析技巧
集中管理容器日志:
# 使用json格式日志
docker run -d \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
linzeyi/hivision_idphotos
# 实时查看日志
docker logs -f --tail 100 hivision_idphotos
# 错误日志过滤
docker logs hivision_idphotos 2>&1 | grep -i error
9. 成本优化方案
9.1 资源使用评估
计算当前部署的资源消耗:
# CPU使用率
docker stats --no-stream --format "{{.Container}}: {{.CPUPerc}}" hivision_idphotos
# 内存占用
docker stats --no-stream --format "{{.Container}}: {{.MemUsage}}" hivision_idphotos
9.2 按需伸缩策略
根据负载自动调整资源:
# 创建自动伸缩脚本
cat > /usr/local/bin/scale_service <<'EOF'
#!/bin/bash
LOAD=$(awk '{print $1}' /proc/loadavg)
CPUS=$(nproc)
if (( $(echo "$LOAD > $CPUS*0.8" | bc -l) )); then
docker update --cpus $(($CPUS+1)) hivision_idphotos
elif (( $(echo "$LOAD < $CPUS*0.3" | bc -l) )); then
docker update --cpus $(($CPUS/2)) hivision_idphotos
fi
EOF
# 设置定时任务
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/scale_service") | crontab -
9.3 备用方案对比
| 方案 | 月成本 | 可靠性 | 维护复杂度 |
|---|---|---|---|
| 家庭服务器 | $10-50 | 中 | 高 |
| 云服务器(基础型) | $20-100 | 高 | 中 |
| 容器服务(托管) | $50-200 | 很高 | 低 |
10. 用户体验优化
10.1 响应速度提升
前端优化技巧:
<!-- 预加载关键资源 -->
<link rel="preload" href="main.js" as="script">
<link rel="preload" href="styles.css" as="style">
<!-- 使用WebP格式减少图片大小 -->
<picture>
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" alt="证件照示例">
</picture>
10.2 移动端适配
针对手机用户的特别优化:
/* 响应式布局调整 */
@media (max-width: 768px) {
.photo-container {
width: 100%;
padding: 10px;
}
.control-panel {
flex-direction: column;
}
}
10.3 个性化设置
允许用户保存偏好配置:
// 使用localStorage保存用户设置
function savePreferences() {
const preferences = {
bgColor: document.getElementById('bg-color').value,
photoSize: document.getElementById('photo-size').value
};
localStorage.setItem('userPreferences', JSON.stringify(preferences));
}
// 加载时恢复设置
window.addEventListener('load', () => {
const saved = JSON.parse(localStorage.getItem('userPreferences'));
if (saved) {
document.getElementById('bg-color').value = saved.bgColor;
document.getElementById('photo-size').value = saved.photoSize;
}
});
11. 生态系统集成
11.1 与相册应用对接
通过WebDAV协议实现与相册应用的集成:
# 配置rclone访问证件照输出目录
rclone config create hivision_photos webdav \
url=http://localhost:7860/output \
vendor=other \
user=myuser \
pass=mypass
# 定时同步到相册应用
rclone sync ~/hivision_data/output hivision_photos:IDPhotos -P
11.2 办公软件集成
在Word中插入证件照的宏代码:
Sub InsertIDPhoto()
Dim photoPath As String
photoPath = "http://yourdomain.com/output/latest_photo.jpg"
ActiveDocument.InlineShapes.AddPicture _
FileName:=photoPath, _
LinkToFile:=False, _
SaveWithDocument:=True
End Sub
11.3 智能家居联动
通过Home Assistant自动化实现语音控制:
automation:
- alias: "Print ID Photo"
trigger:
platform: event
event_type: mobile_app_notification_action
event_data:
action: "PRINT_ID_PHOTO"
action:
- service: shell_command.take_id_photo
- delay: "00:00:10"
- service: mqtt.publish
data:
topic: "printer/command"
payload: "PRINT"
12. 维护与升级策略
12.1 变更管理流程
-
测试环境验证:
# 创建测试容器 docker run -d --name hivision_test -p 7861:7860 linzeyi/hivision_idphotos:beta -
变更记录表:
| 日期 | 变更内容 | 负责人 | 回滚方案 |
|---|---|---|---|
| 2023-08-01 | 升级到v1.2 | 张三 | 恢复v1.1镜像 |
| 2023-08-15 | 新增蓝色背景 | 李四 | 回滚配置文件 |
12.2 备份与恢复
全量备份脚本示例:
#!/bin/bash
BACKUP_DIR="/backup/hivision_$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 备份数据卷
docker run --rm \
-v hivision_data:/volume \
-v $BACKUP_DIR:/backup \
alpine tar cvf /backup/data.tar /volume
# 备份配置
docker inspect hivision_idphotos > $BACKUP_DIR/inspect.json
docker exec hivision_idphotos env > $BACKUP_DIR/env.list
12.3 版本升级方案
使用Docker标签管理版本:
# 平滑升级步骤
docker pull linzeyi/hivision_idphotos:latest
docker stop hivision_idphotos
docker rm hivision_idphotos
docker run -d \
--name hivision_idphotos \
-v ~/hivision_data:/app/data \
-p 7860:7860 \
linzeyi/hivision_idphotos:latest
# 验证新版本
curl -I http://localhost:7860
13. 法律与合规考量
13.1 隐私保护措施
-
数据加密传输:
# 强制使用HTTPS cpolar http 7860 -scheme=https -redirect-http=true -
自动清除策略:
# 设置定时任务清除旧照片 (crontab -l 2>/dev/null; echo "0 4 * * * find ~/hivision_data/output -type f -mtime +30 -delete") | crontab -
13.2 使用条款建议
建议在服务页面添加以下内容:
<div class="terms">
<h3>服务条款</h3>
<ol>
<li>本服务仅限个人非商业用途</li>
<li>用户需确保上传照片拥有合法权利</li>
<li>生成的照片将在30天后自动删除</li>
<li>禁止上传任何违法或侵权内容</li>
</ol>
</div>
13.3 版权声明处理
在输出照片中添加水印:
// 使用Canvas添加版权信息
function addWatermark(image) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
ctx.font = '16px Arial';
ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
ctx.fillText('© MyIDPhoto Service', 20, image.height - 20);
return canvas.toDataURL('image/jpeg');
}
14. 社区与支持体系
14.1 知识库建设
使用Wiki系统构建文档:
# 启动Wiki.js容器
docker run -d \
--name wiki \
-p 3001:3000 \
-v ~/wiki_data:/var/db/wiki \
ghcr.io/requarks/wiki:2
文档结构建议:
1. 快速入门
1.1 系统要求
1.2 安装指南
2. 使用教程
2.1 基本功能
2.2 高级技巧
3. 故障排除
3.1 常见问题
3.2 错误代码
14.2 用户反馈机制
集成反馈表单:
<form action="/api/feedback" method="post">
<label for="rating">满意度评分:</label>
<select id="rating" name="rating">
<option value="5">非常满意</option>
<option value="4">满意</option>
<option value="3">一般</option>
<option value="2">不满意</option>
<option value="1">非常不满意</option>
</select>
<label for="comments">建议:</label>
<textarea id="comments" name="comments"></textarea>
<button type="submit">提交反馈</button>
</form>
14.3 社区贡献指南
开源项目协作规范:
## 如何贡献
1. Fork项目仓库
2. 创建特性分支 (`git checkout -b feature/your-feature`)
3. 提交更改 (`git commit -am 'Add some feature'`)
4. 推送到分支 (`git push origin feature/your-feature`)
5. 创建Pull Request
## 代码规范
- 遵循PEP8标准
- 提交信息使用英文描述
- 新功能需附带测试用例
15. 商业价值拓展
15.1 增值服务设计
潜在收费点分析:
| 服务类型 | 定价策略 | 目标用户 |
|---|---|---|
| 高清输出 | 按次收费 | 专业用户 |
| 批量处理 | 套餐包 | 企业用户 |
| 模板商店 | 单品销售 | 普通用户 |
15.2 数据分析应用
收集的使用数据示例:
{
"metrics": {
"daily_active_users": 42,
"popular_sizes": ["1inch", "2inch"],
"average_processing_time": "3.2s",
"conversion_rate": "68%"
}
}
15.3 合作伙伴生态
可能的合作模式:
- 照相设备厂商:预装软件
- 打印服务商:API对接
- 证件服务商:白标解决方案
16. 技术演进路线
16.1 短期改进计划
接下来3个月的重点:
- 实现GPU加速支持
- 添加更多证件类型模板
- 优化移动端用户体验
16.2 中期技术规划
未来6-12个月的方向:
- 集成AI背景识别
- 开发离线处理能力
- 构建分布式处理集群
16.3 长期愿景
3-5年技术目标:
- 全自动证件照质量评估
- 区块链存证服务
- AR实时预览功能
17. 替代方案评估
17.1 同类产品对比
| 产品 | 开源 | Docker支持 | 远程访问 | 成本 |
|---|---|---|---|---|
| HivisionIDPhotos | 是 | 是 | 需配置 | 低 |
| 商业方案A | 否 | 部分 | 内置 | 高 |
| 开源方案B | 是 | 否 | 无 | 免费 |
17.2 自建vs托管服务
决策矩阵:
| 因素 | 自建方案 | 托管服务 |
|---|---|---|
| 初期成本 | 中 | 高 |
| 长期成本 | 低 | 高 |
| 可控性 | 高 | 低 |
| 维护负担 | 高 | 低 |
| 扩展性 | 中 | 高 |
17.3 技术栈替代方案
备选组件评估:
-
内网穿透替代:
- ngrok:简单但有限制
- frp:配置复杂但功能强大
- 自建中继服务器:成本高但完全可控
-
容器编排替代:
- Docker Compose:简单单机部署
- Kubernetes:复杂但可扩展
- Nomad:平衡选择
18. 真实案例分享
18.1 个人用户实践
"作为自由职业者,我经常需要为不同客户提交不同规格的证件照。这个方案让我在任何地方都能快速生成符合要求的照片,最近一次签证申请就省去了专门拍照的麻烦。"
18.2 小型企业应用
某咨询公司为50名员工部署了此系统:
- 年节省照相费用约$5,000
- 新员工入职流程从2天缩短到2小时
- 统一了全公司证件照风格标准
18.3 教育机构部署
大学计算机实验室采用此方案:
- 服务3000多名学生
- 集成到校园门户网站
- 高峰时段自动扩容应对负载
19. 资源推荐列表
19.1 学习资料
- Docker官方文档:https://docs.docker.com/
- cpolar使用指南:https://www.cpolar.com/docs
- 图像处理优化技巧:https://imageoptim.com/guides
19.2 工具集合
必备开发工具:
-
Docker扩展:
- Portainer:可视化容器管理
- Dive:镜像分析工具
- ctop:容器监控
-
网络调试:
- Wireshark:抓包分析
- Postman:API测试
- curl:命令行HTTP工具
19.3 社区资源
活跃的技术论坛:
- Docker中文社区
- Stack Overflow的docker标签
- GitHub相关项目Issues区
20. 创新应用场景
20.1 智能证件照助手
结合语音交互:
import speech_recognition as sr
r = sr.Recognizer()
with sr.Microphone() as source:
print("请说出您需要的证件照规格:")
audio = r.listen(source)
text = r.recognize_google(audio, language='zh-CN')
print(f"即将生成: {text}规格的证件照")
20.2 自动化简历系统
集成到求职流程:
function generateResumeWithPhoto(userData) {
return fetch('/api/generate_id_photo', {
method: 'POST',
body: JSON.stringify(userData)
})
.then(response => response.json())
.then(photoUrl => {
document.getElementById('resume-photo').src = photoUrl;
});
}
20.3 虚拟活动应用
线上会议证件生成:
# 批量生成参会证件
for attendee in $(cat attendees.list); do
curl -X POST \
-F "image=@photos/$attendee.jpg" \
-F "template=conference_badge" \
http://localhost:7860/api/generate \
> "badges/$attendee.jpg"
done
更多推荐
所有评论(0)