How to self-host it-tools On FreeBSD
it-tools, from their GitHub, is:
Collection of handy online tools for developers, with great UX.
GitHub: https://github.com/CorentinTh/it-tools
Official Site: https://it-tools.tech/
My self-hosted site: https://tools.eiswanderer.de/
my actual setup steps
simplified TLDR: build the src code and point nginx at the output
On Linux, self-hosting is a bit easier, you can just use docker (see offical GitHub).
Below are the exact steps I took on FreeBSD. The setup in a jail is more for myself to practice and learn - it could just as well be served from the host itself, which would be even easier.
1. Build step
I didn’t want build on my tiny VPS, so I built on my Desktop PC instead.
Instructions for regular distributions are on the projects GitHub.
On NixOS, i did the following, which, as I understand it, builds the version using the inputs defined in my NixOS flake at this point in time - and since Hydra has built this exact derivation already, it just pulls it from there.
mkdir ittools
cd ittools
# build
nix build --inputs-from ~/syscfg/nixos-config/ nixpkgs#it-tools
# optional quick local test - visit localhost:8000 in a browser
nix shell nixpkgs#python3
python3 -m http.server -d result/lib 8000
No matter what, the result should look sth like this:
~/ittools
λ ls -lh
total 4,0K
lrwxrwxrwx 1 ax users 74 6. Aug 15:23 result -> /nix/store/7r8lrvgj0aly7h273niqvfivblinvgxp-it-tools-0-unstable-2026-02-12
~/ittools
λ tree -L1 result/lib/
result/lib/
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── assets
├── banner.png
├── browserconfig.xml
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── humans.txt
├── index.html
├── manifest.webmanifest
├── mstile-144x144.png
├── mstile-150x150.png
├── mstile-310x150.png
├── mstile-310x310.png
├── mstile-70x70.png
├── robots.txt
├── safari-pinned-tab.svg
├── sw.js
└── workbox-3e8df8c8.js
2 directories, 20 files
2. FreeBSD - create the jail and setup mount
doas bastille create ittools 15.1-RELEASE 10.0.0.20/24
doas bastille console ittools
# in jail
pkg install nginx
sysrc nginx_enable="YES"
# outside jail again
doas mkdir -p /usr/local/www/it-tools
doas chown -R ax:www /usr/local/www/it-tools/
doas bastille cmd ittools mkdir -p /usr/local/www/it-tools
# mount from host into jail as read-only
# (nullfs: FreeBSD's bind mount — shows an existing directory at a second path)
doas bastille mount -a ittools /usr/local/www/it-tools /usr/local/www/it-tools nullfs ro 0 0
# verify
doas cat /usr/local/bastille/jails/ittools/fstab
doas bastille cmd ittools df -h /usr/local/www/it-tools
3. copy the build result from NixOS to FreeBSD VPS
(vps is defined in my ~/.ssh/config, contains the IP addr etc to connect to my actual VPS)
The -L flag is important here, since result is a symlink to the /nix/store. So is the --chmod, because the content in /nix/store is owned by root.
rsync -aL --delete --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r result/lib/ vps:/usr/local/www/it-tools/
4. update nginx config in jail
doas bastille console ittools
in /usr/local/etc/nginx/nginx.conf, replace the whole server block with this
server {
listen 10.0.0.20:80;
server_name _;
root /usr/local/www/it-tools;
index index.html;
location / { try_files $uri $uri/ /index.html; }
location /assets/ {
expires max;
add_header Cache-Control "public, immutable";
}
location ~* ^/(index\.html|sw\.js|workbox-.*\.js|manifest\.webmanifest)$ {
add_header Cache-Control "no-cache";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/nginx-dist;
}
}
# test new config
nginx -t
# restart and verify the html output is about it-tools, not the "Welcome to nginx"
service nginx restart
fetch -qo- http://10.0.0.20/ | head
5. outside jail: get cert for https and restart nginx
# first time
doas nginx -t
doas service nginx reload
# Let's encrypt
doas certbot --nginx -d tools.eiswanderer.de
# and again
doas nginx -t
doas service nginx reload
And that’s all there is to it!