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!