Repository navigation
Releases: dc9-dev/formd
Release list
formd v0.3.0
formd is a self-hosted form backend for static sites: one Go binary next to your site that accepts submissions, filters out bots without a captcha, stores them in SQLite and sends email through your SMTP server or Amazon SES.
Website with a live demo: https://formd.top
What's new: English and Polish
formd now speaks English by default and Polish on request.
- Panel, emails to you and the CLI follow the new
FORMD_LANGsetting:en(default) orpl. New forms get default field labels and email texts in that language; existing forms keep their own. - Visitors get messages in the language of your page.
formd.jsreads thelangattribute nearest to the form (usually<html lang>), shows its messages in English or Polish, and passes the language to the server so that field errors match. A plain form post without JavaScript uses the browser'sAccept-Language. No configuration is needed on a Polish or an English site. - Other languages still work through the
data-formd-*attributes on the form. - Polish mode shows exactly the same texts as before: every English message has a Polish entry, and a test fails if one is missing.
- The example form is now in English (
examples/contact.html), with the Polish one inexamples/contact.pl.html.
Upgrading from v0.2.0
The panel is now in English by default. To keep it in Polish, add this to /etc/formd/formd.env:
FORMD_LANG=plThen replace the binary and restart: sudo systemctl restart formd. There are no database changes. Existing forms keep their labels and email texts.
Visitor messages on Polish pages (<html lang="pl">) stay Polish. If your pages have no lang attribute, or an English one, visitors now get English messages; set lang="pl" on the page to keep Polish.
Install
# Linux x86-64 (for ARM use formd-linux-arm64)
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.3.0/formd-linux-amd64
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.3.0/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
sudo install -m 0755 formd-linux-amd64 /usr/local/bin/formd
formd version # v0.3.0Or from source: go install github.com/dc9-dev/formd/cmd/formd@v0.3.0 (Go 1.27.2+). Full guide: formd.top.
Files
| File | Platform |
|---|---|
formd-linux-amd64 |
Linux x86-64, statically linked |
formd-linux-arm64 |
Linux ARM64, statically linked |
SHA256SUMS |
checksums |
Built from commit f5a7f5c with Go 1.27.2 (CGO_ENABLED=0, -trimpath).
formd v0.2.0
formd is a self-hosted form backend for static sites: one Go binary next to your site that accepts submissions, filters out bots without a captcha, stores them in SQLite and sends email through your SMTP server or Amazon SES.
Website with a live demo: https://formd.top
What's new
Content assessment with a Polish model on your own hardware
- New
JEV_PROVIDER=basal: formd sends content assessment to a self-hosted basal-serve instead of Jev on OpenRouter. It speaks the same System One API, so the questions, thresholds, holding and fail-open work the same. - Defaults to
Remek/basal-omni-1.0-ultraathttp://127.0.0.1:8000/v1/systemone. The lighter Bielik-basedRemek/basal-2.0-4.5Balso runs on a Mac or a CPU; setJEV_MODELto the name you serve. - Form content stays on your infrastructure and requests cost nothing, so the panel hides the cost tile. The form settings show which model scores submissions and whether content leaves the server.
- Security: basal-serve has no authentication, so plain
httpis still accepted only for a loopback address; a remote model needshttps.OPENROUTER_API_KEYis never sent to a basal endpoint; an optionalBASAL_API_KEYis sent to a gateway in front of it. An unknownJEV_PROVIDERstops startup with a clear error. - Step-by-step setup: README.
The integration is tested against the API format documented by basal, not against a GPU deployment. If something does not match, submissions go through without a score and the panel shows the error.
Website and docs in English and Polish
- formd.top is now in English at
/and in Polish at/pl/, chosen from the browser language on the first visit, with a switch that remembers the choice. - The README is in English; the Polish version moved to README.pl.md. Both have a comparison with hosted form services and an FAQ.
- The English install guide sets English visitor messages through the
data-formd-*attributes. formd's built-in messages and the admin panel are still Polish.
Install
# Linux x86-64 (for ARM use formd-linux-arm64)
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.2.0/formd-linux-amd64
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.2.0/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
sudo install -m 0755 formd-linux-amd64 /usr/local/bin/formd
formd version # v0.2.0Or from source: go install github.com/dc9-dev/formd/cmd/formd@v0.2.0 (Go 1.27.2+). Full guide: formd.top.
Upgrading from v0.1.0
Replace the binary and restart: sudo systemctl restart formd. There are no database changes and no required configuration changes; without JEV_PROVIDER, formd keeps using Jev on OpenRouter as before.
Files
| File | Platform |
|---|---|
formd-linux-amd64 |
Linux x86-64, statically linked |
formd-linux-arm64 |
Linux ARM64, statically linked |
SHA256SUMS |
checksums |
Built from commit ffb9d62 with Go 1.27.2 (CGO_ENABLED=0, -trimpath).
formd v0.1.0
Pierwsze wydanie formd: samodzielnego backendu formularzy dla stron statycznych. Jedna binarka w Go, którą instalujesz na tym samym serwerze co stronę. Przyjmuje formularz, waliduje go, zapisuje do SQLite i wysyła powiadomienie oraz potwierdzenie przez Twój SMTP albo Amazon SES. Bez SaaS-ów i bez captchy od firm trzecich.
Strona projektu: https://formd.top
Co nowego
Ocena treści przez Jev (opcjonalna)
- Każde zgłoszenie może dostać ocenę modelu Jev (TypeSafe, przez OpenRouter): kategorię, prawdopodobieństwo spamu, oszustwa lub phishingu, treści obraźliwej i pilność.
- Powyżej progu ryzyka (domyślnie 70%) formularz:
- wstrzymuje zgłoszenie do zatwierdzenia w panelu, razem z mailami (domyślnie),
- oznacza maile prefiksem
[SPAM?], - albo odrzuca je bez zapisu.
- Jev jest pytany dopiero po wszystkich tanich filtrach. Ma dzienny budżet (
JEV_DAILY_BUDGET_USD) i timeout 4 s. Gdy nie odpowie, zgłoszenie domyślnie przechodzi bez oceny. - Prywatność: funkcja jest wyłączona, dopóki nie ustawisz
OPENROUTER_API_KEYi nie włączysz jej w formularzu. Adresy e-mail są zastępowane samą domeną. - Treść od użytkownika trafia tylko do opisu sytuacji, w osłoniętych blokach, oznaczona jako niezaufana. Klucz API nie pojawia się w logach.
Nowy panel administracyjny
- Jasny, lekki wygląd z wyraźnym logo; font Geist wbudowany w binarkę (bez zasobów z zewnątrz).
- Strona główna z podsumowaniem (zgłoszenia, wstrzymane, nieudane maile, dzisiejszy koszt Jev) i listą formularzy.
- Zakładka Wstrzymane z przyciskiem „Zatwierdź i wyślij” oraz ocena Jev przy każdym zgłoszeniu.
- Wyraźny fokus, link „Przejdź do treści”, ruch wyłączany przy
prefers-reduced-motion.
Komunikaty formd.js w innych językach
- Atrybuty
data-formd-sending,-success,-error,-network-errornadpisują domyślne polskie komunikaty dla danego formularza. data-formd-server-errors="off"ukrywa szczegółowe komunikaty walidacji z serwera.- Bez tych atrybutów działanie się nie zmienia.
HTTPS i reverse proxy
- Pełne konfiguracje nginx dla dwóch wariantów, z certyfikatem, przekierowaniem 80→443 i HSTS:
- formularz na tej samej domenie co strona,
- osobna subdomena, gdy strona leży na GitHub Pages, Netlify albo S3.
- Ten sam zestaw dla Caddy.
- W README: dlaczego formularz musi trafiać na HTTPS, kroki z certbotem i komendy curl do sprawdzenia wdrożenia.
Bezpieczeństwo
- Wymagane Go 1.27.2: usuwa 12 podatności biblioteki standardowej (m.in. w
html/template) zgłoszonych przezgovulncheck. - Zaktualizowane moduły
golang.org/x(crypto, net, sys, term). - Naprawione logowanie do panelu w przeglądarkach wysyłających
Origin: null. Takie żądanie przechodzi tylko wtedy, gdy przeglądarka potwierdziSec-Fetch-Site: same-origin.
Co jest w środku
- API formularzy
POST /f/{id}: urlencoded, multipart (bez plików) i JSON. Bez JS przekierowanie 303, zfetchodpowiedź JSON. - Ochrona przed masową wysyłką:
- podpisany, jednorazowy token HMAC z proof-of-work zamiast captchy,
- minimalny czas wypełnienia liczony na serwerze,
- limity per IP, per formularz i globalne,
- limit potwierdzeń na adres na dobę,
- honeypot, filtr linków i fraz, odrzucanie duplikatów.
- Sieć: nasłuch tylko na konkretnym IP (
0.0.0.0jest odrzucane), allowlista IP,X-Forwarded-Forhonorowany wyłącznie od zaufanego proxy. - Panel na osobnym porcie (przez tunel SSH):
- argon2id, sesje po stronie serwera, CSRF,
SameSite=Strict, ochrona przed DNS rebinding, ścisły CSP,- dziennik zdarzeń.
- Kolejka maili: zgłoszenie i maile zapisują się w jednej transakcji. Ponowienia od 1 min do 24 h, globalny limit maili na godzinę.
- Wdrożenie: utwardzony unit systemd,
install.sh, filtr fail2ban, retencja danych w dniach.
Instalacja
# Linux x86-64 (dla ARM pobierz formd-linux-arm64)
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.1.0/formd-linux-amd64
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.1.0/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
sudo install -m 0755 formd-linux-amd64 /usr/local/bin/formd
formd version # v0.1.0Albo ze źródeł: go install github.com/dc9-dev/formd/cmd/formd@v0.1.0 (Go 1.27.2+).
Dalej: Szybki start i HTTPS i reverse proxy.
Aktualizacja
Schemat bazy migruje się sam przy starcie (dochodzą kolumny statusu i oceny zgłoszeń oraz tabela kosztów Jev). Przed aktualizacją zrób kopię formd.db.
Pliki
| Plik | Platforma |
|---|---|
formd-linux-amd64 |
Linux x86-64, statycznie linkowana |
formd-linux-arm64 |
Linux ARM64, statycznie linkowana |
SHA256SUMS |
sumy kontrolne |
Zbudowane z commita cd96ade przez Go 1.27.2 (CGO_ENABLED=0, -trimpath).


