Hosting
This page explains hosting liblin on your own VPS, which runs Debian / Ubuntu, and Nginx as a reverse proxy.
1. Download liblin JAR
Latest liblin releases could be found here https://codeberg.org/liblin/url_redirect/releases. Download the jar file, and let’s rename it to liblin.jar.
2. Install Java
On your server, run these commands:
sudo apt update
sudo apt install openjdk-25-jre-headless
java -version # verify
3. Upload the JAR
From your local machine:
scp liblin.jar user@your-vps-ip:/home/user/
4. Run it manually first (sanity check)
java -jar liblin.jar
Your app likely starts on port 3000 by default. You can override it:
PORT=8080 java -jar liblin.jar
You can use browser to test your app at http://your-vps-ip:3000, or http://your-vps-ip:8080 if you set a custom port.
5. Set up a systemd service (so it runs forever)
Create a service file:
sudo nano /etc/systemd/system/liblin.service
Paste this:
[Unit]
Description=My Clojure Ring App
After=network.target
[Service]
User=user
WorkingDirectory=/home/user
ExecStart=/usr/bin/java -jar /home/user/liblin.jar
Restart=always
RestartSec=5
Environment=PORT=3000
[Install]
WantedBy=multi-user.target
Enable and start it:
sudo systemctl daemon-reload
sudo systemctl enable liblin
sudo systemctl start liblin
sudo systemctl status liblin
6. Set up Nginx as a reverse proxy
sudo apt install -y nginx
Create a config:
sudo nano /etc/nginx/sites-available/liblin
server {
listen 80;
server_name your-domain.com; # or your VPS IP
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable it:
sudo ln -s /etc/nginx/sites-available/liblin /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
7. Open the firewall
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable
8. Add HTTPS with Let’s Encrypt (optional but recommended)
Visit Certbot’s website for detailed instructions for your OS: https://certbot.eff.org/
Certbot will auto-edit your Nginx config and set up auto-renewal.
9. Setting up ENV variables
liblin reads one env var LIBLIN_DOMAINS which is a path to a edn file containing domain mappings. Lets say you assign /home/user/liblin/domains.edn to it, read the section Domain Slurps for more details.
10. Domain Slurps
liblin is designed to operate with custom domain names or even sub-domains. For that you need a edn file, which maps domains to what it needs to redirect to.
10.1 Redirecting for all codeberg users
For example https://libl.in/liblin/cli will read the content of the file https://codeberg.org/liblin/liblin/raw/branch/main/cli.txt, and will redirect to what ever is present in it.
In https://libl.in/liblin/cli, the liblin is the codeberg user name, and cli is the file name. If there is a repository called liblin by user liblin in codeberg, then the URL will redirect to URL present in https://codeberg.org/liblin/liblin/raw/branch/main/cli.txt.
To achieve it, you need to add the following to your edn file:
{
"libl.in:80"
"https://codeberg.org/{{ paths[0] }}/liblin/raw/branch/main/{{ paths[1] | index-if-empty }}.txt"
}
Where paths is can be considered as vector containing parts of URL after the domain name. In libl.in/liblin/cli, paths will be ["liblin", "cli"] which means paths[0] is liblin and paths[1] is cli. We will be writing about {{ }} in RDL (Redirect Language).
10.2 Redirecting for your domain
Let’s say there is username, or organization in codeberg named yu7 and it has a repository named liblin, and you want to point https://yu7.in/:short to read from the file in https://codeberg.org/yu7/liblin and redirect it to whaterver is present in it, you can configure it as follows.
{
"yu7.in:80"
"https://codeberg.org/yu7/liblin/raw/branch/main/{{ paths[0] | index-if-empty }}.txt"
}
We will soon be writing albout RDL (Redirect Language).
11. Deploying new versions
When you deploy a new version, just scp the new jar over and sudo systemctl restart liblin.
12. Useful commands after deployment
sudo systemctl restart liblin # restart after uploading new jar
sudo journalctl -u liblin -f # tail logs
sudo systemctl status liblin # check status