最近一段时间我一直在折腾同一个主题:怎么用一台免费PaaS主机,把日常用得到的小工具、小页面、自动任务全塞进去。折腾了几天之后,博客、图床、定时脚本陆续都迁了上去,稳定跑了将近两个月,中间踩了不少坑。今天这篇就围绕“搭建各种服务”这件事,把这类免费主机的资源边界、开工前的必做配置、三个典型服务的完整部署过程,以及托管期最常遇到的问题一次讲清楚。适合想练手、预算有限、又需要一个长期在线小服务的开发者参考。
先说结论:这类平台适合跑“小”和“稳”的服务,不适合跑“重”和“常驻”的服务。把它当成一台可以长期开机、偶尔折腾的轻量主机,而不是生产环境服务器,你会顺手很多。
1. 资源边界:先搞清楚免费主机到底能扛什么活
1.1 免费配额到底给了什么
这类免费PaaS主机,典型配置是一套FreeBSD系统,外加一个可视化管理面板。面板里集成了文件管理、MySQL数据库、定时任务、域名解析、SSL证书申请、PHP版本切换这些功能。你还会拿到一个SSH登录入口,可以从本机直接连上去操作文件、跑命令。
配额这个概念要重点讲一下。它不是按“几核CPU几G内存”来算的,而是按一套更细的配额体系来限制。实际影响最大的通常是这几个维度:磁盘空间、可创建进程数、可占用的内存上限、可执行的CPU时间。不同服务商给的具体数字不一样,但逻辑是共通的。你在里面跑的东西越轻、越少,翻车概率就越低。
我建议在注册下来之后,先做一次“探底测试”。至少要知道四样东西:
- 磁盘总空间还剩多少,用
df -h看。 - 系统自带的PHP、Python、Node版本分别是多少,用对应命令
php -v、python3 -V、node -v看。 - 是否允许你自己编译安装软件,还是只能跑系统预装的环境。
- 进程数量有没有硬性限制,比如同时最多跑多少个进程。
这些信息决定了“各种服务”到底能搭到什么程度。我见过有人想在上面跑完整版应用市场、在线IDE、视频转码服务,结果要么装不上,要么装上就崩溃。不是技术不行,是平台本身就不允许。
1.2 适合托管的服务和淘汰名单
拿我自己跑过的项目来举例,适合放在这类免费主机上的服务有这几类:
第一类是个人内容型站点,比如博客、知识库、个人导航页。这类站点访问量小、逻辑简单,用PHP或者静态页面就能跑,占用很少。第二类是图床或者文件分享页,只要注意磁盘配额,完全够用。第三类是定时脚本,比如每天抓一次天气、监控几个网址的状态、定时备份数据库,这些用面板的cron就能搞定。第四类是轻量接口服务,比如把某个网页接口格式化后转成JSON输出,用一个Python脚本或者Node服务监听端口就行。
不适合的服务也很明确:Docker这类容器平台基本别想,因为虚拟化层面就不支持;大型数据库仓库、搜索索引、消息队列这类常驻重量级中间件,配额顶不住;长时间高CPU占用的任务也不建议,比如视频转码、大模型推理、高频爬虫,轻则进程被杀,重则账户被限制。
做个表格更直观:
| 服务类型 | 是否推荐 | 原因 |
|---|---|---|
| 个人博客 / 知识库 | 推荐 | 静态或轻量动态页面,占用低 |
| 图床 / 文件分享 | 推荐 | 注意磁盘配额即可 |
| 定时脚本(抓取、备份、通知) | 推荐 | 短时运行,配额吃得消 |
| 轻量API转发/聚合服务 | 推荐 | 逻辑简单,内存占用可控 |
| 在线IDE / 大型应用 | 不推荐 | 进程数和内存都不支持 |
| Docker / 容器 | 不推荐 | 平台层面不允许 |
| 视频转码 / 高并发站点 | 不推荐 | CPU与内存配额扛不住 |
“搭建各种服务”并不意味着只有一条路。我后来形成了一套固定思路:凡是能用静态页面解决的,绝不上PHP;凡是能用脚本解决放后台的,绝不写成Web应用;凡是必须上数据库的,只建必要的表,不加索引的冗余表一概不要。
2. 开工前的三件套:SSH权限、面板开关、数据库
2.1 三步拿到SSH权限
很多人一拿到账号就急着往面板里传代码,结果后面改文件权限、跑命令行的时候才发现SSH没开。SSH这一步最好放在最开始。
第一步,登录面板,找到“SSH”相关设置,通常叫“SSH Access”或者“管理SSH密钥”。有的平台默认关闭密码登录,需要你先在面板里添加公钥,或者点一个“启用”按钮。我个人的习惯是生成一对密钥来登录,不建议直接暴露密码口令。
第二步,在本机终端里确认能连上。Windows用户用系统自带的OpenSSH客户端或者终端软件,macOS和Linux用户直接开终端。命令很简单:
ssh 你的用户名@你的服务器地址首次连接会提示确认指纹,输入yes后会让你填密码或者验证密钥。能进到这个界面,说明SSH链路已经通了。
第三步,顺手跑两条命令看一眼环境:
whoami pwd这两条命令看起来没什么用,其实很重要。第一次登录的时候看清当前用户和当前目录,后面传文件、写脚本的时候才不会搞错路径。我就犯过这种低级错误:把站点文件传到了另一个用户的目录下,结果网页怎么都打不开,排查了半天才发现是目录搞错了。
2.2 面板里的三个关键开关
不同平台的面板界面大同小异,但有三个设置项建议一进去就处理掉,别留到出问题时手足无措。
第一是“自动续期”或“账户保活”。免费主机最怕的就是白嫖用户注册后不登录,所以一般都有账户有效期机制。面板里通常会有“Renewal”或者“账户续期”的入口,进去后把提醒邮件打开,注册邮箱千万别用填错了就收不到的那种。我自己是把续期日期写进手机日历,提前三天提醒。
第二是“默认页面清理”。很多平台会在你的WWW目录下放一个默认首页,内容可能是“恭喜开通”之类的占位页。不删掉的话,后面部署自己的博客,总会出现“访问域名看到的是平台默认页而不是我的站点”的诡异问题。删掉默认目录里的index.html或者类似文件,只保留空目录就好。
第三是“允许的命令行工具”。有些面板默认限制SSH里执行某些命令,比如wget、curl、git。如果你后面打算直接在服务器上拉代码、下源码包,提前在面板里把这几个工具打开,省得部署到一半提示Permission denied。我试过在没开这些开关的情况下执行git clone,直接被拒了,返回信息也看不懂,后来面板里翻了一圈才发现是这个原因。
2.3 建数据库别用默认配置
网站类服务基本离不开数据库,这类平台一般会预装MySQL或MariaDB。面板里通常有一个“Database”入口,创建流程是:填数据库名、用户名、密码,选字符集,然后点创建。
这个环节有三个细节值得留意。
一是数据库名、用户名可以相同,但密码一定要自己生成,别用自动生成的那串随机密码,也别用纯数字。后面要写进配置文件的,太复杂容易复制错,太简单容易被扫。折中办法是用一串带大小写和特殊符号的20位密码,填进配置文件后尽量别在网页上直接填了。
二是字符集选utf8mb4,不要图省事选latin1或者老的utf8。现在网站内容、评论、文件描述都会有中文,utf8mb4对emoji和生僻字的支持更完整,省得后面数据库和页面出现乱码。
三是记好“数据库地址”。很多免费主机的MySQL并不在本机localhost上,而是单独一台数据库服务器地址。面板的数据库页面里通常会明确写出来。我最初建博客时,配置文件里填了localhost,结果一直报连接失败,后来改成面板给的那个地址就好了。
建完数据库后,我建议用本地客户端先连一次试试。只要能连上,后面Web应用配置数据库信息的时候基本一次过。
3. 部署实战:博客、图床、定时脚本一次跑通
3.1 传文件到主机的三种方式
文件怎么上传到主机,是很多人第一次接触这类平台时卡住的地方。其实方式很多,我按推荐程度排一下。
最常用的是面板自带的文件管理器。打开面板的“File Manager”,会看到整个主机的目录树,找到WWW目录或者网站根目录,直接拖文件上去或者从本地上传压缩包。这种方式的优点是直观,缺点是上传大文件容易超时,而且一次只能传一个。
第二种是SSH/SFTP。用本机的终端软件连上SSH之后,如果是Windows终端,可以用scp命令:
scp 本地压缩包.zip 用户名@服务器地址:/目标路径/如果是Linux/macOS,同样的命令直接可用。传完之后再SSH登录上去解压,速度比面板快很多。
第三种是直接在服务器上用wget或git clone拉取远程资源。这种方式最省事,前提前面说的命令行工具开关要打开。命令示例:
git clone 某个仓库的地址 ~/www/mysite三种方式各有适用场景。小文件、急用、不熟练终端操作的用面板;大文件、批量文件、有终端基础的建议用scp;源码能直接从仓库拉的,直接clone最干净。我自己的习惯是:源码包一律先在本地看一遍,确认没有夹带乱七八糟的内容,再用scp传上去,安全性和可控性都更高。
3.2 部署一个轻量动态博客
博客我选的是资源占用很小的轻量PHP程序。整个部署周期大概30分钟,已经够日常写作和测试用了。
第一步,创建目录并绑定域名。在面板的“Web”或“Sites”入口里,添加一个站点,填上你的域名或平台给的二级域名,选择PHP版本。这里有个坑:很多平台添加站点后,会自动生成一个站点根目录,默认可能是domains/你的域名/public_html,不是想象中的~/www。你要在面板绑定页面里确认清楚实际路径,再去那个目录传文件。
第二步,传代码。把博客源码包上传到上述路径并解压。如果解压后目录里有一层嵌套,比如public_html/typecho/,那就需要把typecho里的所有文件往上一级移动到public_html/下,否则访问域名会出现404。
第三步,填数据库配置。浏览器访问你的域名,进入安装向导,填上前面创建的数据库名、用户名、密码、数据库地址。这里的地址是面板“Database”页面里显示的服务器地址,不是localhost。
第四步,处理伪静态。博客类应用开启友好链接时通常需要重写规则。面板里可能叫“URL Rewrite”或者“伪静态”,打开它并选择适配你这个应用的重写配置。这一步不处理的话,后台功能正常,但前台文章页URL会变得很长,控制台还会提示配置缺失。
整个过程中最容易出错的是两步:站点根目录找错,以及伪静态没开。我朋友第一次部署时就因为这两个问题来回折腾了一晚上。后来我总结出一个判断方法:访问域名看到的是默认目录结构,但网页报404,多半是文件路径不对;访问后台一切正常,但前台链接全带index.php,多半是伪静态开关没开。
3.3 部署一个能传图又能防盗链的图床
第二个我实际部署过的是图床服务。图床对这类免费主机来说算比较吃资源的,但只要选轻量方案,完全能跑。
我用的是一套开源的PHP图床程序,支持本地上传、粘贴上传、批量上传,也带用户分组和图册功能。部署流程和博客类似,但有几个额外参数需要重点设置。
安装完成后,进入后台,第一件事是添加上传存储策略。可选项通常是本地存储、数据库存储、外部存储之类。默认建议选本地存储,因为外部存储需要额外配置接口,免费主机的限制比较多。但本地存储意味着每张图片都会占用磁盘配额,所以在配额设置里要严格控制每个用户的上传大小和格式,图片压缩建议关闭,浪费CPU和内存。
第二件事是设置防盗链。图床最怕别人拿到外链地址到处引用,白白消耗流量和配额。后台一般有“防盗链白名单”,把你自己的域名加进去,允许的Referer就直接放行,其他来源返回403。这里要特别留意:有些应用会从同一个域名下不同子路径加载图片,如果白名单写得太死,可能会把自己网站的图片也拦掉,测试时多换几个页面验证。
第三件事是开启访问令牌或密钥。如果你希望图床只给自己用,把“公开注册”关掉,走后台添加用户的路径。我开的图床只允许本站博客调用,上传时用API密钥方式对接,这样别人就算猜到前端地址也无法直接上传。
图床部署完,还要做一次定时清理。图片上传多了,磁盘会被慢慢吃掉。我加了一个shell脚本,每周把超过30天未访问的临时上传文件删掉,这个脚本放到后面第四节的定时任务里一起跑。
3.4 跑一个能自动通知的Python定时脚本
除了Web站点,免费主机另一个很好用的场景是定时任务。面板里一般叫“Cron Jobs”或者“计划任务”,可以按分钟、小时、天来设置执行周期。
我放了一个很实用的脚本:每10分钟检查一次指定网址是否还能正常访问,如果连续两次失败,就通过邮件或通知接口给我发一条消息。实现思路不复杂,但很能说明这类主机上跑脚本的基本套路。
先写一个Python脚本,放在非Web目录下,比如~/script/site_check.py:
#!/usr/bin/env python3 import urllib.request def check(url): try: response = urllib.request.urlopen(url, timeout=10) return response.status == 200 except Exception: return False if __name__ == "__main__": if not check("https://你的域名"): print("site is down")在面板的Cron页面里添加一条任务,执行时间填*/10 * * * *,执行命令用绝对路径:
python3 ~/script/site_check.py >> ~/script/check.log 2>&1这样脚本每次运行的结果都会写入日志,出问题的时候能一眼看到。日志这个细节很关键,否则脚本跑没跑、报错在哪,完全无迹可寻。
这里有个新手容易忽略的地方:定时任务的环境变量和SSH登录时不一样。你在SSH里敲命令能跑通的程序,加到cron里可能因为PATH没包含Python目录而执行失败。保险做法是命令里用绝对路径,比如/usr/local/bin/python3而不是python3。可以先在SSH里执行which python3获取实际路径,再填到cron里。
我实际用下来,这类脚本占用的资源非常小,跑脚本的时间通常只有几秒钟,对配额的影响可以忽略不计。同一台主机上,博客、图床加上三四个定时脚本同时跑,完全没压力。
4. 常见问题与排查技巧实录
4.1 进程被杀、页面500的典型排查流程
免费主机上最常见的故障就是进程被杀。表现为:网站突然返回500错误,SSH进去执行ps查看不到自己的Web进程,或者面板提示配额超限。
排查流程我总结成三步。第一步,看错误日志,日志位置一般在~/logs/或Web目录下,按日期命名。第二步,查看当前进程数,执行ps aux | wc -l和内存占用htop或top,确认有没有异常进程把配额耗尽。第三步,看Cron日志,因为有些定时任务可能在半夜并发执行,把进程数顶到上限。
进程被杀还有另一个隐藏原因:平台为了防止长期占资源,可能每晚或每周定期重启一次所有用户进程。这种机制下,如果你依赖某个常驻进程,重启后必须自动拉起,否则服务就挂到第二天。我的处理方式是写一个轻量的检测脚本,每5分钟检查目标进程是否存在,不存在就重新启动。免费主机上跑服务,不能按生产服务器的思维要求“永不重启”,只能做到“重启后快速恢复”。
4.2 域名解析和SSL证书的坑
这类平台通常允许你绑定自己的域名。流程是在你的域名服务商处添加一条A记录,指向平台提供给你的IP地址,然后在面板的“域名绑定”里把你的域名加进去。很多新人只做了第一步,忘了第二步,结果解析已经生效,访问域名还是看不到自己的站点。
一个更容易踩的坑是:平台可能要求你绑定时填“不带www”的根域名和“带www”的域名两个都加,不然网站可以访问,但带了www会指向默认页。我每次绑定域名都会把根域名、www子域名、还有可能的资源子域名一起加全,避免后面来回跳转出问题。
SSL证书申请也有讲究。平台一般提供免费的Let's Encrypt证书,申请按钮在面板里。申请时如果提示失败,90%是域名解析还没完全生效。先执行一下dig 你的域名确认解析指向的IP和面板显示的平台IP一致,再申请。证书签发后,记得把强制HTTPS打开,不然访问者还能走HTTP明文,页面容易判为不安全。
证书快到期前,平台会尝试自动续期。但自动续期依赖域名还能正常解析到服务器,如果你中途换了解析地址,续期就会失败。常见症状是:证书过期后,HTTPS访问出现红色警告,但HTTP正常。这时回到面板重新申请一次即可,不用删掉原来的证书。
4.3 数据库连接失败的三分钟检查法
数据库连接失败一般是四类原因:地址填错、用户名或密码写错、字符集不匹配、权限没开。地址填错最常见,很多人习惯性填localhost,但这类平台往往把数据库放在单独的主机名上。密码写错多见于复制的时候把多余空格也复制进去了,配置文件里换行或缩进也会导致语法错误,所以优先把数据库配置写成一行内联字符串。
字符集不匹配的问题不容易想到:应用建表时用了utf8,但数据库服务端配置了utf8mb4,在某些版本组合下会导致写入报错。解决办法是建表时统一指定COLLATE utf8mb4_unicode_ci。
权限问题相对少,但一旦出现很烦。如果你在面板里用某个用户名创建了数据库,系统一般会自动给该用户分配权限。但如果你想用另一个账号访问同一个库,必须去数据库管理界面手动授权。授权语句很简单:
GRANT ALL PRIVILEGES ON 数据库名.* TO '用户名'@'%' IDENTIFIED BY '密码'; FLUSH PRIVILEGES;4.4 文件配额满了怎么清理
免费主机磁盘配额用满的典型症状:上传文件失败、页面写入Session报错、数据库备份失败。清理思路按消耗量从大到小排列。
先用一条命令找出哪些目录占空间最大:
du -sh ~/* ~/.* | sort -rh | head -20一般会发现大头是:上传图片目录、解压时留下的压缩包、日志文件、数据库备份文件。压缩包没删是最可惜的,很多人传完源码就忘了源码压缩包还在目录里躺着。日志文件则适合做轮转,面板如果没提供日志清理,就自己写一个定时删除30天以上日志的脚本。
我整理了一份很实用的清理流程:每周日执行一次tar备份数据库和站点配置文件,保留最近两版,其余删掉;每月执行一次find删除超过30天的.*.log文件;每个月底检查一次上传图片目录,把明显失真的、测试用的无效图片删掉。这样下来半年多都没再出现过配额告警。
5. 长期维护:让免费服务安稳活下去
5.1 续期提醒与账户保活
免费主机的“免费”是有条件的。大多数平台要求用户每隔一段时间登录一次面板或者手动点击续期,否则账户会被回收。这个机制看似麻烦,却是防止大量僵尸账户占资源的手段,合理但需要适应。
我的做法是“双保险”:一方面在手机日历里设置周期提醒,时间定在截止日的前三天;另一方面把平台发给我的所有邮件单独加一个标签,只要看到“Renewal”或者“Expiration”关键词就立刻处理,绝不拖过当天。账户被回收是件非常麻烦的事,数据全部没机会导出来,所以保住账户永远是第一优先级。
登录频率上,建议至少每两周登录一次面板,随便点开一个页面都行。只登录后台不打开任何服务页面,也算活跃。保持账户活跃还有一个隐藏好处:如果你之后想提升配额、申请更多数据库,活跃用户通常更容易通过审核。
5.2 日志、备份与安全底线
服务跑起来了,维护的核心就变成日志和备份。
日志方面,尽量让日志文件独立成目录,而不是全部堆在应用根目录下。路径比如~/logs/app/,既方便定时清理,也不容易因为日志文件过大暴露到Web目录下。如果应用允许配置文件日志级别,生产模式下调成error级别就够了,省空间也减少IO。
备份是我一开始忽略掉、出过一次事之后才补上的环节。窗口期正好赶上我调整了一个网站插件的版本,数据库表结构被改崩了,想恢复才发现之前的备份都过期了。从那以后,我用cron每周自动备份一次数据库,备份文件放到非Web目录,确认备份文件大小至少和数据库实际大小在一个量级,再手动下载到本地存档。备份脚本不要用太重的方式,直接在cron命令里拼接完整语句最省事:
mysqldump -u 用户名 -p密码 数据库名 > 备份路径/backup_$(date +\%Y\%m\%d).sql安全方面,底线是:Web目录下永远不放数据库密码、接口密钥、私钥这类敏感文件。大多数部署翻车事件都是从某一次误操作开始的,比如测试时把配置文件临时放在站点根目录,结果忘了删。我在部署完每一个服务后,都会专门花一分钟扫描一下Web目录,找出所有带.env、config.php、*.key命名的文件,确保它们要么在非Web目录,要么设置了无法访问的权限。
5.3 一点个人经验收尾
最后分享一个我最近养成的习惯:把所有服务按“独立子域名、独立目录”隔离。博客放在blog.你的域名下的独立目录,图床放在img.你的域名下的独立目录,脚本放在完全不属于Web路径的~/script/目录里。这样做的好处是,单个服务崩了,不会拖累其他站点;某个目录的配额吃紧,也能一眼定位到是谁的问题。配一个简单的状态页脚本,定时探测这几个子域名的HTTP状态码,任何一个从200变成500或404,我都能第一时间在消息提醒里看到。
折腾免费主机这件事,最有价值的地方不是把服务搭起来,而是搞清楚每个平台隐藏的边界,并且在边界内找到最稳定的方案。如果你也打算在上面部署一两个服务,记住一句话:先看面板、再查配额、勤写脚本、定期备份。顺序对了,能少走很多弯路。