海外云服务器搭建自建图床完整教程:EasyImages 2.0 部署 + WebP 压缩 + 防盗链 + CDN 加速(2026最新版)
Meta Description: 从零开始用海外云服务器搭建自己的图床服务器,涵盖 EasyImages 2.0 部署、Nginx 与 PHP-FPM 配置、上传目录禁止执行 PHP、WebP 自动压缩、图片防盗链、Cloudflare CDN 加速、PicGo 客户端接入、旧图批量迁移与备份,附服务器配置推荐与图床方案价格成本对比表。
> 关键词:海外云服务器搭建图床、自建图床教程、EasyImages 简单图床、图床服务器搭建、图片防盗链配置、WebP 图片压缩、Cloudflare CDN 加速
前言:自建图床到底解决什么问题
一句话回答:一台 1 核 1G、月付 3.5 到 4 美元的海外云服务器,半小时就能搭出一个属于你自己的图床,所有图片存在你自己的硬盘上,外链永久有效、流量不要钱、跑路了也能随时搬走。
如果你写过博客、上过电商独立站、混过论坛,你大概经历过下面这几件事中的至少一件:
- 用了某个免费公共图床,某天打开文章发现满屏都是一张裂图,原站跑路了; - 图床开始限流,非会员的图片被插了水印、或者干脆只允许站内引用; - 站点的图片全部挂在第三方域名上,SEO 与品牌都给别人做了嫁衣; - 图片本体放在主机商目录里,一搬家就丢、一删库就全毁。
自建图床解决的就是这四件事。它不是什么"技术炫技",而是一项基础设施投入:图片是内容站、独立站最不能丢的资产之一,而它的托管权本来就应该在自己手里。
> 🚀 还没有海外云服务器?通过 5.chengzicloud.cloud 选购阿里云 / AWS / 腾讯云国际版,享专属折扣和中文技术支持。
本文与本站相邻文章的边界(先看清楚,避免重复劳动)
本站已经写过几篇和"存图片"有关但定位不同的文章,先把边界划清楚,你就知道自己该读哪一篇:
| 既有主题 | 它解决的问题 | 与本文的关系 | |---|---|---| | MinIO 自建对象存储 | S3 兼容的存储基础设施,靠 API 读写对象 | 那是"底层仓库",本文是"上层应用",两者可组合(图床也可以把文件写到对象存储) | | WordPress 独立博客搭建 | 建站程序本身的部署 | 那是站点,本文是给站点配一套图片托管 | | Nginx 反向代理 + Let's Encrypt SSL | 全站 HTTPS 与反代 | 本文直接复用这套证书流程,不展开原理 | | 服务器备份与容灾实战 | 快照、rclone 异地、数据库定时备份 | 本文只给出图床专属的备份清单 |
本文只讲一件事:把一台海外云服务器变成你自己的图床服务。 存储内核、建站程序、证书原理都不重复。
需要诚实说明的两个边界
先说缺点,再讲教程。EasyImages 2.0 的官方 README 里有一句原话值得抄给所有人看:
> 本程序环境要求极低,适用于单一场景(游客上传)和个人使用,不适于多用户复杂场景。
也就是说:它是为"我自己一个人用、图片存自己服务器上"这个场景写的。如果你要做的是一个开放注册、给一堆陌生人当图床的平台,那你要的不是它,而是带用户体系的多用户图床程序(Chevereto、Lsky Pro 那一类,需要数据库,运维复杂度高一档)。本文面向的是 99% 的读者:博客作者、独立站卖家、内容团队,给自己或小团队搭一个稳定可控的图片仓库。
第二个边界:图床是"高流量型"服务,它的成本结构由带宽而非 CPU 决定。 一篇爆款文章带 50 张图、每张 200KB,1 万次浏览就是 100GB 流量。放在对象存储上按 $0.09/GB 出流量计费就是 9 美元,而放在你自己的服务器上,这笔钱是 0 —— 前提是带宽够用。这一点下面第二节会算给你看。
一、服务器配置怎么选:图床的瓶颈在带宽和磁盘,不在 CPU
选图床服务器,先记住一句话:CPU 几乎全程闲着,真正卡人的是磁盘 IO 和月流量。 图片上传是纯 IO 操作(写盘 + 转格式),访问是纯静态文件读取,两者对计算力的需求都极低。所以配置选择的优先级排序是:
1. 月流量 / 带宽:决定图床能扛多少访问,第一优先级; 2. 磁盘读写与容量:决定上传速度与能存多少图,必须 SSD; 3. 内存:PHP-FPM 与图片处理(GD 缩放、WebP 转换)会吃内存,1G 是底线; 4. CPU 核数:最不重要,1 核足够。
表1:配置档位推荐表
| 档位 | 配置 | 适用场景 | 参考月付 | |------|------|---------|---------| | 入门 | 1核1G / 20G SSD / 1TB 流量 | 个人博客图床,月访问 5 万 PV 以内 | $3.5 ~ $4.2 | | 标准(推荐) | 1核2G / 40G SSD / 3TB 流量 | 个人站 + 独立站商品图,月 20 万 PV | $6 ~ $8 | | 进阶 | 2核4G / 100G SSD / 5TB 流量 | 内容团队、多站点共用、开图片压缩与水印 | $12 ~ $16 | | 高性能 | 4核8G / 200G NVMe / 大带宽 | 图片站、素材库、日增千图、多用户 | $30 ~ $45 |
> 💡 三个硬性建议:磁盘必须 SSD(机械盘小文件写入延迟放大 10 倍以上,批量上传会卡到怀疑人生);1G 内存务必加 2G swap(PHP 处理大图时极易 OOM);流量包宁可买大(跑超之后云厂商按 $0.09/GB 级别的价格补收,一次爆量就够买半年服务器)。
表2:主流服务商价格对比(1核2G 档)
| 服务商 | 月付 | 年付(折扣后) | 数据中心 | 优点 | |--------|------|--------------|---------|------| | 阿里云国际版 ECS | $6.0 | $4.5/月 | 新加坡/香港/硅谷 | 中文面板、支持支付宝、流量包便宜 | | AWS Lightsail | $5.0 | $3.5/月 | 全球20+区域 | 新用户免费套餐、CloudFront 组合度高 | | 腾讯云国际版 CVM | $6.5 | $4.8/月 | 香港/新加坡/东京 | 低延迟到国内、微信支付 | | Vultr | $6.0 | $6.0/月 | 全球32个 | 按小时计费、随时销毁重建 | | DigitalOcean | $6.0 | $6.0/月 | 全球14个 | 文档最完善、带宽给得大方 |
> 🚀 通过 5.chengzicloud.cloud 购买以上平台均有额外折扣,点击首页查看最新优惠。
表3:自建图床 vs 公共图床 vs 对象存储:成本与风险对比
按"托管 200GB 图片 + 每月 300GB 出流量"估算:
| 方案 | 存储 | 出流量 | 月成本 | 主要风险 | |------|------|--------|--------|---------| | 自建图床(1核2G + 40G SSD 起步) | 含在月费内 | $0(受带宽约束) | ≈ $6 ~ $8 | 要自己运维、带宽有限 | | 自建图床 + 对象存储后端(S3/MinIO) | 按量 | 内网回源 $0 | ≈ $8 ~ $12 | 架构多一层,调试成本高 | | AWS S3 标准 | 200 × $0.023 = $4.6 | 300 × $0.09 = $27 | ≈ $31.6 | 账单惊吓、请求费另计 | | 阿里云国际 OSS | ≈ $4.0 | ≈ $24 | ≈ $28 | 需实名、有最低消费档 | | 腾讯云国际 COS | ≈ $4.8 | ≈ $25 | ≈ $29.8 | 内网回源免费是唯一优势 | | Cloudflare R2 | 200 × $0.015 = $3.0 | $0(出流量免费) | ≈ $3.0 | 便宜但仍在别人机房、国内访问一般 | | 免费公共图床 | $0 | $0 | $0 | 跑路 / 限流 / 加水印 / 盗链封禁,随时发生 |
结论很清楚:如果你的出流量超过 300GB/月,自建图床的直接成本就反超对象存储,而且服务器上还能顺手跑 Nginx、评论系统、博客后端。 唯一比自建更便宜的是 Cloudflare R2 这类"出流量免费"的托管对象存储——但它的代价是数据仍然放在别人的机房,且你需要接受国内访问质量的不确定性。
表4:四类图床方案对照(选型速查)
| 维度 | EasyImages 2.0(本文) | 多用户图床程序(Chevereto/Lsky 等) | 对象存储直存(S3/R2/COS) | 免费公共图床 | |------|---------------------|--------------------------------|----------------------|-------------| | 是否需要数据库 | 不需要(配置写在 PHP 文件里) | 需要 MySQL/PostgreSQL | 不需要 | 不需要 | | 部署难度 | 极低(上传解压即用) | 中(需装数据库、跑迁移) | 低(拿到密钥即可) | 零 | | 多用户 / 注册体系 | 无(官方定位个人与游客上传场景) | 有 | 无 | 平台提供 | | 上传界面 / 后台管理 | 有(含统计、日志、图片管理) | 有 | 无(要靠客户端) | 有 | | 图片压缩 / 水印 / 防盗链 | 内置 | 内置 | 需自建处理链路 | 不可控 | | 成本结构 | 服务器固定月费,流量零边际成本 | 同左(配置要求更高) | 按存储 + 出流量计费 | 免费但有隐性代价 | | 数据可控性 | 完全在自己手里 | 完全在自己手里 | 在厂商机房 | 无 |
一句话选型:个人 / 小团队、想要"零数据库、上传即用"→ EasyImages 2.0;要做开放注册的公共图床平台 → 多用户图床程序;图片量大、想彻底不入运维场 → 对象存储 + 客户端。 本文讲第一种,也是性价比最高、最容易一次跑通的那一种。
> 声明:本文价格数据采集于 2026 年 9 月,仅为公开官网参考区间。云厂商不定期调整刊例价与活动折扣,下单前请以各厂商控制台结算页的实时价格为准。除特别标注外,金额单位均为美元(USD)。
二、八步部署实战:Ubuntu 22.04 / CentOS 7 双系统命令
下面整套流程给出两套系统的命令,Ubuntu 22.04 与 CentOS 7 各复制各自的那一份即可,不要混着执行。全程用 root 登录,假设你的网站域名是 img.example.com,把它换成你自己的域名。
第一步:系统初始化(时区、swap、防火墙)
先统一时区,否则后台上传日志的时间会错乱;再补 swap,1G 内存的机器不加 swap 处理大图时几乎必然 OOM。
`bash
// 设置时区为上海(两套系统通用)
timedatectl set-timezone Asia/Shanghai && date
// 创建 2G swap(两套系统通用)
fallocate -l 2G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
free -h
`
Ubuntu 22.04 配防火墙,只放行 SSH 与 Web:
`bash
apt update -y && apt install -y ufw curl wget unzip
ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp
ufw --force enable && ufw status
`
CentOS 7 用 firewalld(注意本地与内存的差异,这里直接重载):
`bash
yum install -y epel-release curl wget unzip
systemctl enable --now firewalld
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload && firewall-cmd --list-all
`
> ⚠️ 只改系统防火墙是不够的:云厂商控制台的安全组是另一层,两处都要放行 22/80/443,只改一处等于没改。这是新手最常踩的一脚。
第二步:安装 Nginx 与 PHP-FPM
EasyImages 是 PHP 程序,官方环境要求写得很明确:Nginx + PHP ≥ 7.0 + Linux,且 PHP 必须支持 Fileinfo、iconv、zip、mbstring、openssl 这几个扩展,缺一个就会上传失败或无法删除图片;要开 WebP 转换还需要 GD 带 webp 支持(即 imagecreatefromwebp() 可用)。
Ubuntu 22.04(系统自带 PHP 8.1):
`bash
apt install -y nginx php-fpm php-gd php-mbstring php-zip php-curl php-xml
php -v && nginx -v
`
CentOS 7 的默认 PHP 只有 5.4,太老,用 remi 源装 PHP 7.4:
`bash
yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install --enablerepo=remi-php74 -y nginx php php-fpm php-gd php-mbstring php-zip php-curl php-xml
php -v
`
> 🔴 PHP 版本兼容提醒(官方标注为准):EasyImages 2.0 的官方兼容区间标注为 PHP 5.6 ~ 8.0,推荐 7.0 以上。Ubuntu 22.04 默认装出来的是 PHP 8.1,已经高于官方标注的上限,绝大多数场景能跑,但如果安装向导或上传环节报出奇怪的函数错误,请优先怀疑版本:用 ondrej/php 源装一个 php8.0 并切换 FPM 版本,或者干脆用 Ubuntu 20.04(默认 PHP 7.4)最稳。CentOS 7 走上面的 remi-php74 路线不受影响。
PHP-FPM 起来并设置为开机自启:
`bash
systemctl enable --now php-fpm // Ubuntu 上服务名是 php8.1-fpm 或 php-fpm,用 systemctl list-units | grep php 确认
systemctl enable --now nginx
`
第三步:获取最新版程序(不写死版本号)
不要照抄任何一篇老教程里的固定下载链接——图床程序更新后旧链接会直接 404。正确做法是运行时向 GitHub API 问一次最新版本号:
`bash
cd /tmp
VER=$(curl -s https://api.github.com/repos/icret/EasyImages2.0/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+')
echo "最新稳定版: $VER"
wget -q "https://github.com/icret/EasyImages2.0/archive/refs/tags/${VER}.tar.gz" -O easyimage.tar.gz
mkdir -p /var/www/imgbed && tar -zxf easyimage.tar.gz -C /var/www/imgbed --strip-components=1
`
解压后立刻纠正属主与权限——官方明确要求目录为 755,PHP 进程要有写权限,否则会出现"能登录但不能上传":
`bash
chown -R www-data:www-data /var/www/imgbed // CentOS 7 上是 nginx:nginx
find /var/www/imgbed -type d -exec chmod 755 {} \;
find /var/www/imgbed -type f -exec chmod 644 {} \;
chmod -R 755 /var/www/imgbed/i /var/www/imgbed/config
`
> 💡 顺带打开 OPcache,能明显降低后台与上传接口的响应时间:Ubuntu 装 php-opcache 包,CentOS 7 装 php-opcache/php-pecl-zend-opcache 后在 php.ini 里启用即可。注意:开了 OPcache 之后更新程序版本可能不生效,重启一次 PHP-FPM 就好。
第四步:配置 Nginx(含"上传目录禁止执行 PHP"这条命门)
这一步是整个部署里安全权重最高的一步。图床的上传目录天然是"任何人都能往里写文件"的地方,一旦这个目录能执行 PHP,攻击者上传一个 .php 文件就等于拿到了你的服务器。官方文档给的做法是:禁止 config、docs、i、public 这几个目录运行 PHP。
新建站点配置。注意下面的 i 目录是上传目录(图片默认就存在 /i/年/月/日/ 下),client_max_body_size 必须放大,否则稍大的图片会被 Nginx 直接 413 拒掉:
`nginx
server {
listen 80;
server_name img.example.com;
root /var/www/imgbed;
index index.php index.html;
client_max_body_size 32m;
location / { try_files $uri $uri/ /index.php?$args; }
location ~ \.php$ { fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
location ~ ^/(config|docs|i|public)/.\.(php|php5)$ { deny all; }
}
`
CentOS 7 上 PHP-FPM 默认监听 TCP,把 fastcgi_pass 换成:
`nginx
fastcgi_pass 127.0.0.1:9000;
`
同时把 PHP 的上传上限也调大,两个文件都要改(FPM 与 CLI 各一份,改错文件是最常见的"改了没生效"):
`bash
// Ubuntu
sed -i 's/^upload_max_filesize.*/upload_max_filesize = 32M/' /etc/php/8.1/fpm/php.ini
sed -i 's/^post_max_size.*/post_max_size = 32M/' /etc/php/8.1/fpm/php.ini
// CentOS 7
sed -i 's/^upload_max_filesize.*/upload_max_filesize = 32M/' /etc/php.ini
sed -i 's/^post_max_size.*/post_max_size = 32M/' /etc/php.ini
`
生效并自检:
`bash
systemctl restart php-fpm // CentOS 7 上服务名是 php-fpm
nginx -t && systemctl reload nginx
curl -I http://img.example.com/
`
域名解析不要忘记:把 img.example.com 的 A 记录指向你的服务器公网 IP(如果走 Cloudflare 代理,注意后面第七步 CDN 缓存会干扰上传测试,建议先关掉小云朵代理、直连验证通过后再打开)。
第五步:走安装向导(或绕过它)
浏览器打开 http://img.example.com/install/,按提示填两件事,两个域名都要填,且末尾不能带斜杠:
- 网站域名(domain):http://img.example.com
- 图片域名(image url):与网站域名相同即可(只有一个域名时就填一样的)
安装程序会在 config 目录生成 install.lock;首次访问首页还会再做一次环境自检,生成 EasyImage.lock。两个锁文件都在,说明安装成功。
如果安装向导因为虚拟化环境、权限或 open_basedir 限制打不开,可以直接跳过——官方给出的做法是:
1. 删掉 install 目录;
2. 手工编辑 config/config.php,把 domain(网站网址)和 imgurl(图片网址)改成你的域名,末尾不要加斜杠;
3. 后续所有配置都可以在后台"设置"页面里改。
`bash
rm -rf /var/www/imgbed/install
grep -n "domain\|imgurl" /var/www/imgbed/config/config.php | head -5
`
> ⚠️ 跳过安装向导不等于跳过环境要求:PHP 扩展、目录权限该满足的还得满足,否则一样传不上去。
第六步:后台安全配置与图片处理(最容易漏、也最值钱的一步)
登录后台(默认入口在 /admin/,具体路径以你的部署为准),逐条配置下面这些。这是一个"默认能跑"和"能长期安全地跑"的分水岭:
1. 改掉后台入口与管理员口令。默认路径是公开信息,第一件事就是改掉,别让后台在互联网上裸奔。
2. 改为"仅登录后上传"。个人图床没有任何理由对游客开放上传——开放等于给陌生人免费送存储与带宽,还会被塞垃圾图。
3. 开启 API 上传并生成 Token。这是给 PicGo、ShareX、uPic、Chrome 插件、甚至你自己的脚本用的。Token 只在后台生成,不要泄漏;PicGo 的"自定义 Body"里就填 {"token":"你的token"}。
4. 设置 IP 黑白名单与每日上传次数上限。手机流量会被扫,日上限是最便宜的一道闸。
5. 图片处理:开 WebP 转换 + 打开压缩 + 设定图片质量。这一步直接决定你的图床"费不费流量"。同样一张 4K 截图,原图 PNG 可能 3MB,转成 WebP 并压到质量 80 之后往往只剩 200~300KB,体积掉一个数量级,肉眼几乎看不出差别。开启前先用这条命令确认 GD 支持 WebP:
`bash
php -r "var_dump(function_exists('imagecreatefromwebp'), gd_info()['WebP Support']);"
`
两个都返回 true 才算就绪。若第一条是 false,说明 GD 没编译 webp 支持,转格式时会报 undefined function imagecreatefromwebp()——Ubuntu 装 php-gd、CentOS 装 php-gd 即可(remi 源的包默认带 WebP)。
6. 水印与防盗链水印。文字水印适合品牌曝光;但如果你把图片用在电商详情页上,建议只加水印不加水印背景,避免影响主图合规。
7. 设置单图最小/最大宽高与上传格式白名单。默认允许"其他文件格式",个人用建议直接收窄成图片格式,别让它变成任意文件托管。
8. 图片鉴黄(可选)。有两条路:接 moderatecontent 的在线 API;或者自建 nsfwjs 服务(官方仓库提供了一个 Docker 镜像,跑在 3307 端口,后台把它填成 http://服务器IP:3307/api/nsfw/classify?url= 即可)。个人图床不对外开放上传的话,这一条可以跳过。
9. 隐藏 /i/ 存储路径(可选,进阶)。默认图片链接形如 https://img.example.com/i/2026/09/23/xxxxxx.webp。开启"隐藏 /i/ 目录"后可以把 /i/ 从链接里隐藏掉,但前提是图片域名必须与网站域名不同,并且图片域名要绑定到存储路径目录。这一步不着急,先让站跑起来再说。
配置完成后,直接上传一张图验证:正常应返回一段 JSON,包含 url(图片直链)、thumb(缩略图)、del(删除链接)三个字段。拿到 url 后面能打开图片,说明图床本体已经可用。
第七步:上 HTTPS(Let's Encrypt 免费证书)
图片走 HTTP 有两个现实问题:浏览器对混合内容(HTTPS 页面里嵌 HTTP 图片)会拦截或警告;搜索引擎也会给非 HTTPS 资源降权。用 certbot 签一张免费证书,五分钟搞定:
`bash
// Ubuntu
apt install -y certbot python3-certbot-nginx
// CentOS 7
yum install -y certbot python3-certbot-nginx
// 自动改写 Nginx 配置、签发并配置自动续期(两套系统通用)
certbot --nginx -d img.example.com --agree-tos -m [email protected] --redirect
systemctl list-timers | grep certbot // 确认自动续期定时器已生效
`
完整的证书原理、通配符证书、HTTP/2 与 HSTS 细节,见本站《Nginx 反向代理 + Let's Encrypt SSL 证书配置完整教程》,本文不重复。
第八步:防盗链、缓存与 CDN 加速
防盗链是自建图床的必选项——不设的话,任何人都能把你的图片嵌到他的站上,消耗的全是你的带宽。Nginx 用 valid_referers 判断来源,白名单里写你自己的域名:
`nginx
location ~* \.(gif|jpg|jpeg|png|webp|svg|avif)$ {
valid_referers none blocked server_names img.example.com *.example.com;
if ($invalid_referer) { return 403; }
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
`
这里有两个必须知道的坑:
- none 要不要留? 留 none 意味着"直接粘贴链接访问"也放行——对图床是必要的,否则你在浏览器地址栏直接打开图片都会 403,很多社交平台抓取预览图也可能拿不到。如果你的图只在自己的站点内用,可以去掉 none 收紧一些,但风险是微信/QQ 的图片预览可能失效。
- 官方明确提醒过的一个缓存坑:如果你开了"原图保护"功能后发现打开图片链接显示 404,原因通常是 Nginx 或 Apache 对静态图片做了页面级缓存。处理办法是把 Nginx 默认配置里那段针对 gif|jpg|jpeg|png|bmp|swf 的 expires 30d 段删掉,改由上面这段带防盗链判断的规则接管。
CDN 加速。图片是典型的"读多写少 + 完全静态"资源,最契合 CDN。用 Cloudflare 免费版就能拿到收益:
1. 把图片域名接入 Cloudflare,DNS 记录点亮小云朵(走代理);
2. 缓存规则里把图片扩展名的缓存级别设为 Cache Everything(或用 Page Rule / Cache Rule 指定 *.webp 等),图片基本不会再打到你的源站;
3. 打开 Polish(图片压缩/WebP 自动转换)与 Tiered Cache(分层缓存,提高回源命中率);
4. 打开 Rocket Loader 之外的常规优化即可,别开 Auto Minify 折腾二进制图片;
5. 如果图床源站经常被扫,记得把 SSL/TLS 模式设为 Full (Strict),并配合"Authenticated Origin Pulls",避免有人绕过 CDN 直连源站 IP 刷流量。
> 🔴 用 CDN 后调试上传功能时,先暂停 CDN 代理或加一条 cache bypass 规则。上传接口被 CDN 缓存住会出现"上传成功但图片看不到"、"删图删不掉"这类看似灵异的问题——官方 FAQ 里也把"CDN 缓存"列为图片无法上传/访问的三大原因之一(另外两个是权限问题和防火墙拦截)。
三、把图床接进你的写作与运营工作流
图床搭好只是第一步,真正提升效率的是"截图 → 上传 → 自动拿链接"这条链路自动化。三种接法,按使用频率排序:
3.1 PicGo(写博客/写文档最常用)
1. 安装最新版 PicGo,在"插件设置"里搜索并安装 web-uploader;
2. 进入"图床设置 → 自定义 Web 图床",按下面四项填写,保存并设为默认图床;
3. 回到图床后台,在"图床安全 → 高级设置"里开启 API 上传并生成一个 Token。
`text
API 地址 : https://img.example.com/api/index.php
POST 参数名 : image
JSON 路径 : url
自定义 Body : {"token": "你在后台生成的token"}
`
配好之后,Ctrl+Shift+P(或截图键)上传,剪贴板里直接就是 Markdown 格式的图片链接,粘进文章即可。
3.2 命令行 / 脚本调用(批量场景)
图床的 API 就是一个标准的 multipart POST,任何语言都能调。用 curl 验证一行就够:
`bash
curl -X POST https://img.example.com/api/index.php \
-F "image=@/root/photo.jpg" \
-F "token=你的token"
`
返回的 JSON 里,url 是直链,thumb 是缩略图地址,del 是带 hash 的删除链接——注意这个 del 链接长期有效,不要随手贴到公开场合。
3.3 电商 / 内容站接入
WordPress、Typecho、WooCommerce、Shopify 的详情页都可以直接用图床的直链,好处是主站搬家时图片不受影响、主站服务器也不用承担图片流量。做跨境独立站的话,把商品图统一放在图床域名(而不是站点域名)下,配合 CDN 后主站可以选更小的配置。
四、旧图批量迁移:把散落各处的图片收回自己家
迁移思路很简单:抓取旧文章里的图片链接 → 下载 → 重传到图床 → 替换正文里的链接。下面是一段可直接改用的 Python 脚本骨架(把站点域名改成你自己的,Token 从环境变量读入,避免把凭据写进脚本):
`python
import os, re, requests
SITE = "https://img.example.com" // 换成你的图床域名 TOKEN = os.environ["IMG_BED_TOKEN"] // 先执行 export IMG_BED_TOKEN=后台生成的token SRC = "/root/articles" // 待迁移的 md 目录 os.makedirs("/tmp/dl", exist_ok=True)
pattern = re.compile(r'https?://[^\s\)"\']+\.(?:jpg|jpeg|png|gif|webp)')
for name in os.listdir(SRC):
if not name.endswith(".md"): continue
path = os.path.join(SRC, name)
text = open(path, encoding="utf-8").read()
for url in set(pattern.findall(text)):
if SITE in url: continue // 已经是本站图床的跳过
fn = "/tmp/dl/" + os.path.basename(url.split("?")[0])
try:
open(fn, "wb").write(requests.get(url, timeout=30).content)
r = requests.post(SITE + "/api/index.php",
files={"image": open(fn, "rb")},
data={"token": TOKEN}, timeout=60).json()
if r.get("result") == "success":
text = text.replace(url, r["url"]) // 替换为图床直链
else:
print("上传失败", url, r)
except Exception as e:
print("跳过", url, e)
open(path, "w", encoding="utf-8").write(text)
print("done:", name)
`
跑之前先把文章目录整体备份一份(cp -r articles articles.bak),批量替换出错时能一键回滚。迁移完成后用 grep 扫一遍还有没有残留的外链域名:
`bash
grep -rn "旧图床域名" /root/articles | wc -l
`
五、图床的备份与迁移(和普通网站的备份清单不一样)
图床没有数据库,所以备份清单出奇地短,但也因此更容易被人忘掉:
| 要备份的东西 | 路径 | 说明 |
|---|---|---|
| 全部配置 | /var/www/imgbed/config/ | 内含 config.php、API Token、域名设置,丢了要重配 |
| 全部图片 | /var/www/imgbed/i/(或你自定义的存储路径) | 真正的资产,图片本体 |
| Nginx 站点配置 | /etc/nginx/ | 含防盗链与证书配置 |
| 证书目录(如果用 certbot) | /etc/letsencrypt/ | 迁移后不必重新申请 |
一条命令做本地打包(图片多的话加 -1 走流式压缩):
`bash
cd /var/www && tar -czf /root/imgbed-$(date +%F).tar.gz imgbed/config imgbed/i
`
再配一条 rclone 异地同步(rclone config 先配好远端),每天凌晨跑一次:
`bash
// 加入 crontab:每天 03:30 同步图片目录到异地对象存储
30 3 * rclone sync /var/www/imgbed/i remote:imgbed-backup --transfers 8 --checkers 16
`
换服务器 / 换域名的正确顺序(顺序错了会出现图片全部 404):先在新机按本文第一到第四步部署完成,不要跑安装向导;再把旧的 config 目录和 i 目录完整覆盖过去;接着打开 config/config.php 把 domain 与 imgurl 改成新域名(末尾不加斜杠);最后重新签证书、切 DNS。图片文件本身的路径没变,因此旧文章的直链在域名不变的情况下不会失效。
程序升级的正确顺序:备份 config 目录与图片目录 → 下载新版本解压覆盖 → 把备份的 config 与图片目录放回去 → 进后台把所有底部设置各点一次保存。官方特别提醒:如果升级后出现异常,往往就是"设置项没重新保存一遍"。
六、部署后安全加固清单(逐条勾掉)
1. 上传目录禁止执行 PHP(第四步的 location ~ ^/(config|docs|i|public)/.\.(php|php5)$ { deny all; })——这条最重要,别省。
2. 只允许登录后上传,IP 黑白名单 + 每日上传上限一起开。
3. 后台入口路径与管理员口令全部改掉,不要留默认值。
4. 防火墙与云安全组双重收敛:只放行 22/80/443;如果图床程序用了自定义端口,同样不要对公网开放。
5. 加 fail2ban:图床后台登录页暴露在公网,针对它的 jail 能有效挡住暴力破解。
6. 禁止外部直接访问 config 目录(Nginx 里加一条 deny all),避免 Token 与配置被枚举。
7. 备份自动化:图片是资产,且丢了不可逆;本地打包 + rclone 异地两份。
8. 盯住磁盘与流量:图片只增不减,加一条磁盘使用率超过 85% 就告警的监控(做法见本站《海外云服务器监控运维》)。
七、常见问题 FAQ
Q:上传成功但图片不显示、或者删不掉图片,是什么原因?
A:九成是权限问题。官方要求很明确:所有文件和目录 755,属主是 Web 用户(Ubuntu 是 www-data,CentOS 是 nginx)。用第一步里的 chown -R 加 find ... -exec chmod 两条命令全量纠一遍即可。若在宝塔或军哥 LNMP 环境下,还要关闭防跨站或删掉域名目录下的 user.ini——它会触发 Warning: is_dir(): open_basedir restriction in effect,正好卡住上传与删除。
Q:CentOS 7 上会不会遇到 glibc 版本不兼容的问题?
A:不会。EasyImages 是纯 PHP 程序,没有任何预编译二进制,也不依赖 Node.js 的现代 glibc。这和本站《Meilisearch 自建搜索》《code-server 云端 IDE》里遇到的 GLIBC_2.xx not found 是两类问题。CentOS 7 上真正需要注意的是默认 PHP 只有 5.4,必须按第二步走 remi-php74 换成 7.4。
Q:提示 upload File size exceeds the maximum value 怎么解决?
A:PHP 的上传上限太小。改 upload_max_filesize 与 post_max_size(第二步末尾给了 sed 命令),同时确认 Nginx 的 client_max_body_size 不小于它们,改完重启 PHP-FPM。只改一处不算改。
Q:转 WebP 时报 undefined function imagecreatefromwebp()?
A:GD 没带 WebP 支持。装 php-gd(Ubuntu)/ php-gd(CentOS 7 走 remi 源),重启 PHP-FPM;用第六步里的 php -r 一行命令自检。
Q:报 Fatal error: Allowed memory size ... exhausted?
A:内存或分配给 PHP 的内存不够。优先升内存(1G 以下处理大图基本没戏),其次调 php.ini 的 memory_limit,再者把 PHP-FPM 的进程数收敛、别让多个大图请求同时处理。图床这种场景,1核2G 比 2核1G 稳得多。
Q:开了"原图保护"之后打开图片链接是 404?
A:这是官方 FAQ 里记录过的已知现象,原因是 Nginx/Apache 对静态图片做了页面级缓存。把默认配置里那段针对图片扩展名的 expires 30d 段删掉,改用第八步那种带防盗链判断的 location 规则接管。
Q:后台设置页面显示不全 / 版本号一直显示旧版本?
A:可以在后台关闭环境自检;或者手工把 version.json 下载下来放到 admin/logs/version/ 目录。另外,开了 OPcache 后更新文件或版本号可能不生效,重启一次 PHP-FPM 就正常了。
Q:我该不该用宝塔面板装?
A:宝塔确实提供了"简单图床"的一键部署,对完全不想碰命令行的用户很友好。但如果你已经按本文走到这里,纯命令行方案更轻、更透明,也不会因为面板本身暴露额外的攻击面。两种都行,别两套混着来(面板环境 + 手工配置最容易出现权限与 user.ini 打架)。
Q:图床会不会被人刷流量刷爆? A:会,所以必须做三件事:防盗链(第八步)、CDN 缓存(图片打到 CDN,不打源站)、登录后才允许上传(避免被当免费中转站)。再进一步的做法是给图片目录加访问频率限制,以及用 CDN 的速率限制规则兜底。
Q:网站域名和图片域名必须是同一个吗?
A:不必须。只有一个域名时填成一样的最省事;但如果你要开"隐藏 /i/ 目录"、或者想把图片单独挂在 CDN 域名下,就需要两个不同的域名,并把图片域名绑定到存储路径目录。
八、总结
用海外云服务器自建图床,本质上是一次成本极低、收益极高的基础设施投资:
- 成本:一台 1核2G 的海外服务器,月付 6 到 8 美元,比一杯咖啡贵不了多少;出流量不再单独计费; - 收益:图片资产 100% 在自己手里、外链永久有效、不再担心公共图床跑路或限流,还能顺手复用到博客、独立站、电商详情页; - 关键动作只有四个:上传目录禁止执行 PHP、只允许登录后上传、开 WebP 压缩、配防盗链 + CDN。
整套流程的复杂度其实低于大多数人的预期——解压一个程序、配一段 Nginx、调一次 PHP 上限、签一张免费证书,四步做完图床就能跑。真正决定它能不能长期稳定服务的,是那些不起眼的细节:PHP 版本是否落在官方兼容区间、目录属主是否是 Web 用户、上传目录能不能执行脚本、备份有没有自动化。
把这几点守好,一套自建图床可以稳定跑很多年,而你要操心的只有一件事:磁盘够不够大。
延伸阅读: - 海外云服务器搭建 MinIO 自建对象存储:S3 兼容 + 图床 + 静态托管 - 海外云服务器搭建 WordPress 独立博客完整教程 - Nginx 反向代理 + Let's Encrypt 免费 SSL 证书配置完整教程 - 海外云服务器监控运维:Prometheus + Grafana + Telegram 告警 - 海外云服务器备份与容灾实战(快照 + rclone 异地 + 数据库定时备份)
> 本文由 5.chengzicloud.cloud 提供,点击访问首页了解更多海外云服务器部署方案和专属优惠。