首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >自建图床教程:图片上传服务部署与对象存储对接

自建图床教程:图片上传服务部署与对象存储对接

原创
作者头像
克劳德2048
发布2026-09-16 10:53:10
发布2026-09-16 10:53:10
1800
举报

摘要

图床解决的是博客、文档和论坛发帖时的图片托管问题:上传后拿到一个稳定链接,随处引用。本文完成一个自建图床的部署,并把底层存储对接到对象存储,让容量不受服务器磁盘限制。内容涵盖方案选择、部署配置、存储对接、访问加速、防盗链与容量控制,以及图片外链场景特有的成本和合规注意事项。

一、为什么图床要接对象存储

自建图床有两种存储方式,差别很实际。

存在服务器本地磁盘:配置最简单,读写延迟低。但问题很快会出现——图片只增不减,磁盘迟早写满;图片外链会持续消耗服务器带宽,图片较多的文章一次访问就要传输几 MB;服务器故障时图片全部失效,已发布的文章会大面积显示图片破损。

存到对象存储:图床程序只负责上传和管理,图片实体存在对象存储中。容量按实际用量计费不必预先规划;对象存储提供较高的数据持久性;配合内容分发网络分发时,图片流量不经过服务器,源站带宽压力大幅下降。

对图床这个场景,对接对象存储几乎是必选项。图片外链的流量特征是持续、分散、体积大,正是对象存储加内容分发网络最擅长的负载,用服务器带宽承接既贵又慢。

二、方案选择与资源规划

图床类工具有多种,选择时主要看使用方式:

方案类型

特点

适合场景

独立图床程序

提供网页上传界面、相册管理、多用户

需要管理界面和多人使用

客户端直传工具

桌面工具直接上传到对象存储,无需服务端

只有自己使用,追求简单

网盘程序的分享功能

复用已部署的网盘

已有网盘,不想再多部署一个服务

如果只是自己写博客用,客户端直传工具其实最省事——不需要服务器,配好密钥直接传到对象存储。但它缺少统一的图片管理界面,也不方便多人使用。

本文按独立图床程序部署,因为它覆盖的场景更完整。

资源规划:

项目

最低配置

说明

CPU

1 核

图片处理时短时占用较高

内存

1~2 GB

缩略图生成需要一定内存

磁盘

20 GB

接了对象存储后本地只存程序和数据库

接了对象存储之后,服务器磁盘需求很小,图片都不落本地。这也是这个方案的优势之一。

需要放通的端口:

端口

协议

用途

22

TCP

SSH 登录(默认已放通)

80

TCP

HTTP,用于证书验证与跳转

443

TCP

HTTPS 访问

三、准备对象存储

在对象存储控制台创建存储桶,记录以下信息:

信息项

说明

存储桶名称

创建时指定

所属地域

建议与服务器同地域,上传走内网更快

访问域名

图片外链会用到

密钥 ID 与密钥 Key

程序访问授权用

权限设置需要区分对待,这一点与网盘场景不同。

图床的图片需要被公开访问——文章里的图片链接要能被任何读者打开。所以存储桶或图片所在路径需要允许公共读取。

但要注意:只开放读取,不要开放写入。 公有读写权限意味着任何人都能往你的存储桶上传或删除文件,会被用来存放违规内容或恶意占用你的空间和流量。正确配置是公有读、私有写,上传通过程序用密钥完成。

密钥使用子账号并限定权限。 为图床单独创建子账号,只授予该存储桶的读写权限。不要用主账号密钥——图床程序如果存在漏洞,主账号密钥泄露会影响所有云资源。

四、部署图床程序

以 Docker Compose 方式部署:

代码语言:bash
复制
mkdir -p ~/apps/imagehost && cd ~/apps/imagehost

编写 compose.yaml

代码语言:yaml
复制
services:
  db:
    image: mariadb:10.11
    environment:
      MYSQL_ROOT_PASSWORD: 替换为强密码
      MYSQL_DATABASE: imagehost
      MYSQL_USER: imagehost
      MYSQL_PASSWORD: 替换为强密码
    volumes:
      - db-data:/var/lib/mysql
    restart: unless-stopped

  app:
    image: 图床程序镜像:固定版本号
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - app-data:/var/www/html
    environment:
      DB_HOST: db
      DB_DATABASE: imagehost
      DB_USERNAME: imagehost
      DB_PASSWORD: 与上面保持一致
      TZ: Asia/Shanghai
    depends_on:
      - db
    restart: unless-stopped

volumes:
  db-data:
  app-data:

几处配置的说明:

  • DB_HOST: db 用容器服务名。填 localhost 连不上,因为在容器内这个地址指向容器自身。
  • 端口绑定到 127.0.0.1,必须经过反向代理访问。
  • 镜像标签固定为具体版本号,不使用滚动标签。

具体的镜像名称和环境变量以所选程序的官方文档为准,不同程序的配置项差异较大。

启动服务:

代码语言:bash
复制
docker compose up -d
docker compose ps
docker compose logs app --tail 30

五、配置域名与 HTTPS

在域名服务商处添加 A 记录,解析生效后验证:

代码语言:bash
复制
dig +short img.example.com

配置反向代理,以 Caddy 为例:

代码语言:caddyfile
复制
img.example.com {
    reverse_proxy 127.0.0.1:8080
    request_body {
        max_size 100MB
    }
}

request_body max_size 要覆盖单张图片的最大体积。默认限制偏小时,上传较大的图片会失败并返回 413,而界面上往往只显示上传失败。

HTTPS 在图床场景有个额外的必要性:如果你的博客是 HTTPS 站点,而图片链接是 HTTP,浏览器会拦截这些图片并提示混合内容,图片无法显示。所以图床必须启用 HTTPS。

服务器位于中国内地且使用域名对外提供服务时,需要先完成 ICP 备案。图片外链使用的对象存储访问域名如果绑定了自定义域名,同样需要备案。

六、对接对象存储

在图床程序的后台设置中配置存储方式,选择 S3 兼容协议或对象存储对应的选项,填入:

配置项

填写内容

存储桶名称

创建的存储桶名

地域

存储桶所属地域标识

访问域名

存储桶的访问地址

密钥 ID

子账号的密钥 ID

密钥 Key

子账号的密钥 Key

存储路径前缀

可选,例如 images/

具体的参数名称与取值格式请以对象存储的 S3 兼容协议文档为准,不同服务的地域标识和域名格式存在差异。

配置存储路径前缀是个好习惯。 把图床的文件都放在一个固定前缀下,便于后续做权限控制、生命周期管理和统计,也避免与存储桶中其他用途的文件混在一起。

配置完成后上传一张测试图片,然后到对象存储控制台查看存储桶,确认对应路径下出现了新文件。

七、配置内容分发网络加速

图片是典型的静态资源,适合用内容分发网络分发。接入后带来两个改善:不同地区访客的加载速度提升;图片流量由分发节点承担,回源流量大幅减少。

在内容分发网络控制台添加域名,源站指向对象存储的访问地址。配置要点:

  • 缓存时间设长一些。 图片上传后基本不会修改,缓存时间可以设为较长周期,提高命中率。
  • 配置正确的回源 Host。 回源时携带的 Host 头需要与源站匹配,配置错误会导致回源失败。
  • 启用 HTTPS。 分发域名同样需要配置证书。

配置完成后,把图床程序中的图片访问域名改为分发域名,新上传的图片会使用加速链接。

这里有个成本上的注意点:内容分发网络按流量计费。如果图片被大量引用或被恶意刷流量,费用可能超出预期。建议:

  • 在控制台设置流量告警,及时感知异常。
  • 配置防盗链,只允许自己的域名引用。
  • 对单个文件设置合理的大小上限,避免有人上传超大文件消耗流量。

八、配置防盗链

防盗链是图床必须配置的一项,否则你的图片可能被其他网站直接引用,流量费用由你承担。

在内容分发网络或对象存储的控制台配置来源限制:

  • 设置允许的来源域名白名单,只包含自己的博客和文档站域名。
  • 决定是否允许空来源。直接在浏览器打开图片链接时来源为空,如果希望这种访问也能成功(例如分享单张图片链接),需要允许空来源;如果要严格防盗链,则拒绝空来源,但这样直接打开链接会失败。

多数个人博客场景建议允许空来源,同时限制域名白名单,在便利和防护之间取平衡。

九、验证部署是否可用

网页端可通过 HTTPS 访问

代码语言:bash
复制
curl -I https://img.example.com

上传功能正常:在网页端上传一张图片,确认上传成功并返回链接。

图片确实存到了对象存储:在对象存储控制台确认存储桶对应路径下出现了新文件。这一步验证存储对接真的生效,而不是文件仍在写本地磁盘。

外链可正常访问:复制返回的图片链接,在新的浏览器窗口打开,确认图片正常显示。

在实际引用场景中验证:把图片链接插入到你的博客文章中,确认显示正常且没有混合内容告警。这是图床的真实使用场景,必须实测。

大图上传通过:上传一张接近大小上限的图片。小图测试完全不会暴露请求体大小限制的问题。

加速链接生效:如果配置了内容分发网络,确认图片链接使用的是分发域名,并检查响应头中的缓存命中标识。

防盗链生效:这一项建议主动测试。用一个不在白名单中的来源引用图片,确认被拒绝。配了防盗链但实际没生效的情况不少见。

十、常见问题与排查

上传后图片无法显示

先确认文件是否真的到了对象存储。到了但访问不了,通常是存储桶或路径的读取权限未开放。检查权限配置,确认允许公共读取。

上传大图失败

检查两处:反向代理的请求体大小限制、图床程序自身的上传大小配置。取值较小的那一处决定实际上限。

图片在博客中显示破损

多为混合内容问题。确认图片链接是 https 开头。如果历史文章中有 http 链接,需要批量替换。

上传成功但链接是内网地址

图床程序中配置的访问域名有误。检查存储配置中的访问域名,应填写公网可访问的地址。

对象存储返回权限错误

检查密钥是否正确、子账号是否有该存储桶的写入权限、存储桶名称和地域是否匹配。

流量费用异常增长

先查看是否被盗链。在对象存储或内容分发网络的日志中分析来源分布,如果有大量来自陌生域名的请求,说明防盗链未生效或配置有误。

也要检查是否有超大文件被反复请求。可以对单文件大小设限,并考虑对图片做压缩处理。

缩略图生成失败

图片处理需要一定内存,处理超大图片时可能超出限制。检查程序日志中的具体报错,必要时提高内存上限或限制上传图片的最大尺寸。

十一、容量与成本控制

图床的成本主要来自存储和流量,有几个实用的控制手段。

上传前压缩

这是性价比最高的优化。网页展示用的图片通常不需要原图质量,压缩后体积可以显著下降,存储和流量成本同步降低。可以在图床程序中开启自动压缩,或上传前手动处理。

限制单文件大小与格式

设置合理的上限,避免有人上传超大文件。同时限制允许的格式,只接受常见图片格式,拒绝其他类型的文件——这也是一项安全措施,防止图床被用来托管可执行文件。

使用生命周期规则

对象存储支持生命周期管理,可以把较早的图片自动转为成本更低的存储类型。适合归档不常访问的历史图片。

定期清理无用图片

上传了但没有被引用的图片会持续占用空间。部分图床程序提供未引用图片的统计功能,可以定期清理。

设置费用告警

在控制台配置流量和存储的用量告警,异常增长时能及时发现。这比月底看账单要好得多。

十二、安全与合规

这一节对图床格外重要,因为图床是一个对外提供上传能力的服务。

关闭开放注册

如果图床程序支持多用户,务必关闭开放注册。一个允许任意注册的图床很快会被用来托管垃圾内容或违规图片,而你作为服务的运营者要对其上的内容承担责任

需要给他人使用时,通过后台手动创建账号。

限制上传格式

只允许图片格式。允许任意文件上传会带来严重风险:可能被上传恶意脚本,或被用作文件分发渠道。

内容责任

自建图床意味着你要对存储在上面的内容负责。要点:

  • 上传的图片必须是你有权使用和传播的内容。不要上传未获授权的他人作品、有版权的素材图。
  • 不得存储和传播违法违规内容。
  • 不要上传含有他人个人信息的图片,例如未经同意的他人照片、身份证件、包含隐私信息的截图。
  • 如果开放给他人使用,需要有内容审核机制,并保留处理违规内容的能力。

保护凭据

对象存储密钥是核心凭据,泄露后他人可以任意读写你的存储桶。不要把密钥写在前端代码或提交到代码仓库中。使用子账号并限定最小权限,定期轮换。

备份要点

图床需要备份的是数据库(记录图片与用户的对应关系)。图片实体在对象存储中,其持久性由对象存储保障。

但要注意:数据库丢失会导致所有图片失去索引——文件还在,但不知道哪张图属于谁、原始文件名是什么。所以数据库备份不能省。

代码语言:bash
复制
docker compose exec -T db \
  mysqldump -u imagehost -p'密码' imagehost | gzip > ~/img-db-$(date +%Y%m%d).sql.gz

把备份同步到服务器之外的位置。

变更前创建快照:升级程序版本前给实例创建快照。回滚会把整块系统盘恢复到快照时间点,之后写入的数据会被清除,运行中的实例会自动关机。使用存储型套餐的实例不支持创建快照。

部署完成后,如果需要把其他自建服务的存储也统一到对象存储,或为多个服务配置统一的域名入口,可以作为下一步方向。

图片存储和外链场景,对象存储 COS 提供高持久性、按量计费和生命周期管理,配合CDN分发可显著降低源站带宽压力;运行图床程序的机器,轻量应用服务器的入门规格即可承载。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 摘要
  • 一、为什么图床要接对象存储
  • 二、方案选择与资源规划
  • 三、准备对象存储
  • 四、部署图床程序
  • 五、配置域名与 HTTPS
  • 六、对接对象存储
  • 七、配置内容分发网络加速
  • 八、配置防盗链
  • 九、验证部署是否可用
  • 十、常见问题与排查
  • 十一、容量与成本控制
  • 十二、安全与合规
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档