推荐使用Docker部署,因其环境一致、快速部署、资源隔离且适合新手与生产环境;若无Docker或资源受限,可选二进制直跑,但需手动初始化配置并注意SQLite并发限制。

WriteFreely 在 Linux 上安装有两条清晰路径:Docker 部署(推荐) 和 二进制直跑(轻量、无依赖)。选哪条,取决于你是否已有 Docker 环境、是否需要多人协作、以及是否打算长期维护。
用 Docker Compose 一键启动(适合新手 & 生产环境)
这是目前最稳定、最易维护的方式,官方镜像 writeas/writefreely:latest 已预编译好,无需手动编译 Go 源码。
常见错误现象:docker-compose up -d 后容器反复重启、日志里出现 failed to connect to database 或 listen tcp :8080: bind: address already in use。
- 确保
docker和docker-compose已安装且服务运行中:sudo systemctl is-active docker应返回active -
docker-compose.yml中的数据库服务名(如writefreely-db)必须和config.ini里[database] host = writefreely-db保持完全一致(大小写、连字符都不能错) - 端口冲突很常见:如果宿主机 8080 已被占用,直接改
ports: ["8130:8080"],然后访问http://localhost:8130 - 数据卷路径权限要放开:
chmod -R 755 ./data,否则容器内进程可能无法写入config.ini或 SQLite 文件
用预编译二进制文件直接运行(适合测试或低资源 VPS)
不需要 Docker,只依赖系统 glibc,适合 512MB 内存的小机器,但默认用 SQLite,多人模式下性能会受限。
关键步骤不是“解压就完事”,而是必须初始化配置并显式指定数据目录:
- 下载最新版:
wget https://github.com/writefreely/writefreely/releases/latest/download/writefreely_linux_amd64.tar.gz - 解压后进入目录,**必须先执行**:
./writefreely --init—— 这会生成config.ini并初始化数据库 - 修改
config.ini中的[server] port和[app] host:后者必须填你实际访问的地址(比如http://your-domain.com),否则图片/链接会指向localhost - 启动命令要带参数:
./writefreely -c config.ini -d ./data,其中-d指定数据目录,避免默认写入当前路径导致权限问题
切换 MySQL/MariaDB 而不是 SQLite(多人博客必需)
单用户 SQLite 模式在并发写入时容易锁表,single_user = false 时必须换 MySQL 类数据库。
最容易踩的坑是连接参数写错或网络不通:
-
[database] type = mysql必须小写,写成MySQL或mysql8会静默失败 -
host填的是容器名(Docker 网络内)或内网 IP(宿主机直连),不是127.0.0.1—— 容器里127.0.0.1指自己,不是宿主机上的数据库 - MySQL 用户需有远程访问权限:
CREATE USER 'writefreely'@'%' IDENTIFIED BY 'P@ssw0rd'; GRANT ALL ON writefreely.* TO 'writefreely'@'%'; FLUSH PRIVILEGES; - 确认 MySQL 的
bind-address没有锁定为127.0.0.1(尤其群晖或宝塔环境下常被默认限制)
让 WriteFreely 从外网访问(Nginx 反向代理关键点)
不配反向代理,就只能用 :8080 端口访问,既不安全也不符合常规域名习惯。
核心是两件事:改 config.ini + 配 Nginx,缺一不可:
-
[app] host必须设为你的公网域名(如https://blog.example.com),不能是http://localhost:8080—— 否则所有生成的链接、RSS、ActivityPub 地址全是错的 - Nginx 配置里
proxy_pass http://127.0.0.1:8080后**必须加斜杠**:proxy_pass http://127.0.0.1:8080/;,否则子路径(如/about)会 404 - 务必转发 WebSocket 头:
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade";,否则实时通知功能失效 - HTTPS 下记得开
[server] tls = true,否则部分前端资源会因混合内容被浏览器拦截
复杂点在于配置项之间有隐式依赖:改了数据库类型就得重跑 dbinit,改了 host 就得清浏览器缓存,改了端口就得同步更新反代配置——每一步都影响下一步能否生效。











