Compiling WriteFreely — a self-hosted, minimalist blogging platform — from Go source and running it on EasyPanel via Docker Compose.
Stack:
- Docker / Docker Compose
- EasyPanel (PaaS management UI)
- Go 1.23 (language)
- SQLite (database)
- Node.js + LESS (compiling static assets)
- Reverse proxy: EasyPanel (TLS / HTTPS management)
1. Goal
- Run WriteFreely on EasyPanel under my own domain (ozturk.ai)
- Get the TLS certificate through EasyPanel
- Persist the configuration to a volume
- Compile the required static files (templates, CSS)
- Resolve any errors as they come up
2. The Compose setup
The following minimal setup was entered into EasyPanel’s Docker Compose tab:
services:
wf_buildbox:
image: golang:1.23-alpine
user: "0:0"
tty: true
stdin_open: true
working_dir: /srv/wf
volumes:
- wf_home:/srv/wf
command: ["/bin/sh","-c","mkdir -p /srv/wf && tail -f /dev/null"]
expose:
- "8080"
volumes:
wf_home:
With this setup:
- The container stays up (never exits)
- Console access is active
- All build output persists in the
/srv/wfvolume
3. Installing the required tools
From the console (EasyPanel → Console):
apk update
apk add --no-cache git build-base nodejs npm sqlite-dev ca-certificates bash
4. Fetching the source
cd /srv/wf
mkdir -p src bin data
cd src
git clone https://github.com/writefreely/writefreely.git
cd writefreely
5. Building
WriteFreely now requires Go 1.23, which is why the golang:1.23-alpine image was chosen. Make sure go.mod is present in the current directory.
go version # should be go1.23.x
go build -v -tags='sqlite' -o /srv/wf/bin/writefreely ./cmd/writefreely/
Errors resolved along the way:
❌
go.mod file not found— was in the wrong directory ❌go: go.mod requires go >= 1.23.0— switched the image togolang:1.23-alpine
6. Compiling static assets
npm i -g less less-plugin-clean-css clean-css
cd less
CSSDIR=../static/css
lessc app.less --clean-css="--s1 --advanced" ${CSSDIR}/write.css
lessc fonts.less --clean-css="--s1 --advanced" ${CSSDIR}/fonts.css
lessc icons.less --clean-css="--s1 --advanced" ${CSSDIR}/icons.css
lessc prose.less --clean-css="--s1 --advanced" ${CSSDIR}/prose.css
cd ../prose
npm install
npm run build
7. Configuration and database
/srv/wf/bin/writefreely -c /srv/wf/data/config.ini --config
/srv/wf/bin/writefreely -c /srv/wf/data/config.ini --init-db
/srv/wf/bin/writefreely -c /srv/wf/data/config.ini --gen-keys
8. Running it
Important: working_dir must be the repo root (that’s where templates and static live).
New Compose:
services:
wf_buildbox:
image: golang:1.23-alpine
user: "0:0"
working_dir: /srv/wf/src/writefreely
volumes:
- wf_home:/srv/wf
command: ["/srv/wf/bin/writefreely","-c","/srv/wf/data/config.ini"]
expose:
- "8080"
volumes:
wf_home:
Error resolved:
❌
load templates: no such file or directory→ setworking_dirto/srv/wf/src/writefreely
9. Domain settings (EasyPanel)
- Domain: ozturk.ai
- Service: wf_buildbox
- Internal port: 8080
- TLS: Let’s Encrypt (Cloudflare DNS only → grey-clouded)
10. Errors and fixes
| Error | Cause | Fix |
|---|---|---|
go.mod file not found |
Wrong directory | cd writefreely |
requires go >= 1.23.0 |
Old Go version | golang:1.23-alpine |
Permission denied |
No write permission on the volume | user: "0:0" + chmod 0777 |
templates: no such file |
Wrong working directory | working_dir: /srv/wf/src/writefreely |
Using autocert on host localhost |
Autocert enabled | autocert = false + port = 8080 |
URLs show localhost:8080 |
base_url missing |
base_url = "https://ozturk.ai" |
Collection.hostName is empty! |
Host column empty in the DB | UPDATE collections SET host='ozturk.ai'; |
11. Current state
https://ozturk.aiis live- TLS certificate is managed by EasyPanel
base_urlandhostsettings are correct- No errors in the console
12. Extra notes
- To create an admin user:
bash /srv/wf/bin/writefreely -c /srv/wf/data/config.ini --create-admin admin:StrongPassword - EasyPanel manages the reverse proxy, so HTTPS must stay disabled on WriteFreely’s own side.
- Backing up the volume (
/srv/wf/data) is enough.
Result
Minimalist blogging infrastructure (WriteFreely), modern reverse proxy management (EasyPanel), a persistent volume, secure TLS, and a systematic run through every error along the way — all done.