[{"data":1,"prerenderedAt":188},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-kutt-vps-url-shortener-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-kutt-vps-url-shortener-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":32,"intro":35,"sections":36,"ctaTitle":128,"ctaBody":129,"ctaButton":130,"ctaUrl":131,"relatedPosts":132},561,"self-host-kutt-vps-url-shortener",{"fr":12,"en":10,"ar":13,"es":14},"self-host-kutt-vps","استضافة-kutt-على-vps-اختصار-الروابط","autoalojar-kutt-vps-acortador-de-url","Kutt on a VPS: a self-hosted URL shortener with an API","Install Kutt on a VPS: short links on your own domain, REST API, custom aliases, expiry, password protection and private click statistics.",7,0,false,"2026-11-02T00:00:00+00:00","2026-11-02T13:48:09+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[28],{"id":17,"name":23,"slug":24,"color":25,"icon":26},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-kutt-vps-poster.svg",{"categorySlug":33,"appSlug":34},"automation-workflows","kutt","A bit.ly link in a text-message campaign is a click that goes through a service you do not control, a statistic you do not own and a domain that is not yours. Kutt, an open-source URL shortener under the MIT licence, brings all of that back home: every short link carries your domain, every click stays in your database, and a REST API lets your tools shorten their own links. This guide installs Kutt with Docker Compose on a VPS, publishes it over HTTPS behind nginx, closes public sign-up, then shows how to create links through the API.",[37,41,51,87,90,106,110,113,116,119,122,125],{"type":38,"title":39,"body":40},"h2","Why host your own URL shortener","A public shortener decides for you: it can change its terms, cap the number of links, insert an interstitial page or shut down, and your printed links stop working. Its statistics belong to it, and its shared domain is regularly blocked by anti-phishing filters because other people abuse it.\n\nWith Kutt on your VPS, the link go.your-domain.com\u002Foffer is yours for good: you can change its destination without reprinting the poster, see who clicked and from where, and no third party sees your campaigns. For an agency, it is also a service to offer every client, on their own domain.",{"type":42,"title":43,"items":44},"ul","What Kutt brings",[45,46,47,48,49,50],"**Links on your domain** — every short link carries your brand and stays valid even if you change tools later.","**Custom aliases** — `\u002Flaunch`, `\u002Fwebinar`, or a generated six-character code without ambiguous characters.","**Password and expiry** — a protected link for a client document, a link that stops redirecting when an offer ends.","**Private statistics** — visits over time, browsers, operating systems, countries and referrers, visible only to the owner.","**REST API** — one key per user to create, update and delete links from your scripts and tools.","**Administration** — team account creation, review of every link, banning an abusive link or domain.",{"type":52,"title":53,"headers":54,"rows":58},"comparison","Kutt, Shlink and a public service",[5,55,56,57],"Kutt","Shlink","Public service (bit.ly…)",[59,64,69,73,77,82],[60,61,62,63],"Web interface","Built in","Separate web client","Yes",[65,66,67,68],"REST API","Yes, one key per user","Yes, keys managed from the command line","Yes, often paid",[70,71,71,72],"Your own domain","Yes, included","Paid option",[74,75,75,76],"Statistics","In your database","With the provider",[78,79,80,81],"Team accounts","Yes, created by the administrator","No, access by API key","Depends on the plan",[83,84,85,86],"Storage","SQLite, PostgreSQL or MySQL","SQLite, PostgreSQL, MySQL or SQL Server","Managed by the provider",{"type":38,"title":88,"body":89},"Prerequisites","An Ubuntu 24.04 VPS with 512 MB of RAM and 5 GB of disk is enough: Kutt runs in a single Node.js container and uses about 200 MB of memory. You need Docker with the Compose plugin, nginx and certbot for HTTPS, and a DNS name pointing to the VPS.\n\nChoose that name carefully, because it forms every link: the shorter it is, the shorter your links. A subdomain such as `go.your-domain.com` or a small dedicated domain works very well. Kutt writes it into every link it creates, so changing it later does not rewrite links already shared.",{"type":91,"title":92,"steps":93},"steps","Install Kutt with Docker Compose",[94,97,100,103],{"title":95,"body":96},"Prepare the directory and the secrets","Create the application directory and a `.env` file holding the secret key (it signs sessions) and the short-link domain. Replace `go.example.com` with your own name.\n```bash\nmkdir -p \u002Fopt\u002Fkutt && cd \u002Fopt\u002Fkutt\nprintf 'SECRET_KEY=%s\\nDOMAIN=go.example.com\\n' \"$(openssl rand -hex 32)\" > .env\nchmod 600 .env\n```",{"title":98,"body":99},"Write the compose file","Create `compose.yaml`. The port is published on the loopback interface only: nginx alone reaches it. Public sign-up and anonymous links stay closed, and the SQLite database lives in a named volume.\n```yaml\nservices:\n  kutt:\n    image: kutt\u002Fkutt:v3.2.6\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:8107:3000\"\n    environment:\n      JWT_SECRET: ${SECRET_KEY:?SECRET_KEY requis}\n      DEFAULT_DOMAIN: ${DOMAIN:?DOMAIN requis}\n      DB_CLIENT: better-sqlite3\n      DB_FILENAME: \u002Fvar\u002Flib\u002Fkutt\u002Fdata.sqlite\n      TRUST_PROXY: \"true\"\n      DISALLOW_REGISTRATION: \"true\"\n      DISALLOW_ANONYMOUS_LINKS: \"true\"\n    volumes:\n      - kutt-data:\u002Fvar\u002Flib\u002Fkutt\n      - kutt-custom:\u002Fkutt\u002Fcustom\nvolumes:\n  kutt-data: {}\n  kutt-custom: {}\n```",{"title":101,"body":102},"Start and check","Start the stack. Kutt applies its migrations at start-up, then the health probe must answer 200.\n```bash\ndocker compose up -d\ndocker compose ps\ncurl -s -o \u002Fdev\u002Fnull -w '%{http_code}\\n' http:\u002F\u002F127.0.0.1:8107\u002Fapi\u002Fv2\u002Fhealth\n```",{"title":104,"body":105},"Publish Kutt over HTTPS","Declare an nginx virtual host that forwards requests to the local port, then request the certificate with certbot. The `X-Forwarded-For` header lets Kutt record the real visitor address (`TRUST_PROXY`).\n```nginx\nserver {\n    server_name go.example.com;\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:8107;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}\n```\n```bash\ncertbot --nginx -d go.example.com\n```",{"type":107,"title":108,"body":109},"tip","Create the administrator account straight away","Kutt creates no account in advance: as long as no user exists, the home page redirects to the **create admin** form, and the first visitor becomes administrator. Open your domain as soon as HTTPS works and create your account with a strong password. The form then refuses any further creation.",{"type":38,"title":111,"body":112},"Create links through the API","In your account settings, generate an API key, then send it in the `X-API-KEY` header. The JSON body accepts `target` (the long address) and, optionally, `customurl`, `password`, `description` and `expire_in` (a duration such as `7 days`).\n```bash\ncurl -s -X POST https:\u002F\u002Fgo.example.com\u002Fapi\u002Fv2\u002Flinks \\\n  -H \"X-API-KEY: $KUTT_API_KEY\" \\\n  -H 'Content-Type: application\u002Fjson' \\\n  -d '{\"target\": \"https:\u002F\u002Fexample.com\u002Fune\u002Fadresse\u002Ftres\u002Flongue\", \"customurl\": \"promo\", \"expire_in\": \"7 days\"}'\n```\n\nThe response contains the `link` field, the full short link. The same endpoint with `GET` lists your links with their visit count, and `\u002Fapi\u002Fv2\u002Flinks\u002F\u003Cid>\u002Fstats` returns the detailed statistics of one link. That is what lets you wire Kutt into a CRM, an invoicing script or an email campaign: every outgoing link is shortened and measured without manual work.",{"type":38,"title":114,"body":115},"Working as a team","Sign-up is closed: the administrator creates accounts from the admin page. Each member has their own links, private statistics and API key, revoked by generating a new one. The administrator sees every link on the instance and can ban an abusive one; this matters, because a shortener carrying your domain puts its reputation at stake.\n\nKutt also accepts additional domains, added in the settings. Each must point to the VPS and have its own certificate: start with a single domain, then add the others one by one.",{"type":38,"title":117,"body":118},"Enable email","Kutt is installed with email disabled: no password reset by email and no address verification. To enable them, add `MAIL_ENABLED: \"true\"` and the `MAIL_HOST`, `MAIL_PORT`, `MAIL_USER`, `MAIL_PASSWORD` and `MAIL_FROM` variables of your SMTP server to the container environment, then restart with `docker compose up -d`. Keep the administrator password safe in the meantime: without email, losing it has to be fixed in the database.",{"type":38,"title":120,"body":121},"Sizing the VPS","For a team and a few thousand links, 512 MB of RAM and one vCPU are plenty: a redirect is a simple database read. The SQLite database grows with recorded visits, in the order of a few hundred bytes per click. Beyond hundreds of thousands of clicks a day, move to PostgreSQL (`DB_CLIENT: pg`) and enable Redis (`REDIS_ENABLED`) for caching.",{"type":38,"title":123,"body":124},"Backup and updates","All the data lives in the `kutt-data` volume: the SQLite database holds accounts, links and statistics. Stop the container for a moment to get a consistent copy, then archive the volume.\n```bash\ndocker compose stop kutt\ndocker run --rm -v kutt_kutt-data:\u002Fdata -v \"$PWD\":\u002Fbackup alpine \\\n  tar czf \u002Fbackup\u002Fkutt-$(date +%F).tar.gz -C \u002Fdata .\ndocker compose start kutt\n```\n\nTo update, read the project's release notes, change the image tag, then pull the new image: migrations run at start-up. Always take a backup right before.\n```bash\n# changer l'étiquette de l'image dans compose.yaml, puis :\ndocker compose pull && docker compose up -d\n```",{"type":38,"title":126,"body":127},"One-click install from the ServOrbit Marketplace","On a ServOrbit VPS, Kutt installs from the Marketplace in your client area: choose the address — a short subdomain of one of your domains or the VPS's free subdomain, HTTPS included — and click Install. The script deploys the container, generates the secret key, sets the link domain and configures nginx. All that is left is to open your domain to create the administrator account, then your first API key.","Your short links, on your domain","A ServOrbit Ubuntu 24.04 VPS with 512 MB of RAM is enough for Kutt. One-click install from the Marketplace, secret key generated for you, HTTPS on your domain or on the VPS's free subdomain.","Discover Kutt","\u002Fmarketplace\u002Fautomation-workflows\u002Fkutt",[133,150,169],{"id":134,"slug":135,"slugs":136,"title":140,"excerpt":141,"readTime":17,"views":18,"isPinned":19,"publishedAt":142,"updatedAt":143,"category":144,"categories":145,"featuredImage":29,"bgImage":30,"posterImage":147,"relatedSolution":148},87,"host-listmonk-on-your-own-vps",{"fr":137,"en":135,"ar":138,"es":139},"heberger-listmonk","استضافة-listmonk-على-خادمك-الافتراضي-الخاص-vps","alojar-listmonk-en-un-vps","Host Listmonk on Your Own VPS","Deploy Listmonk on your VPS: Docker installation, advanced SMTP configuration, bounce management, updates, common troubleshooting and PostgreSQL backups.","2026-03-25T00:00:00+00:00","2026-09-20T21:13:53+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},[146],{"id":17,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fheberger-listmonk-poster.svg",{"categorySlug":24,"appSlug":149},"listmonk",{"id":151,"slug":152,"slugs":153,"title":157,"excerpt":158,"readTime":159,"views":160,"isPinned":19,"publishedAt":161,"updatedAt":162,"category":163,"categories":164,"featuredImage":29,"bgImage":30,"posterImage":166,"relatedSolution":167},249,"self-host-mautic-on-a-vps-open-source-marketing-automation",{"fr":154,"en":152,"ar":155,"es":156},"self-host-mautic-vps","استضافة-mautic-على-vps-أتمتة-التسويق-مفتوحة-المصدر","alojar-mautic-en-un-vps-automatizacion-marketing","Self-host Mautic on a VPS: open-source marketing automation","Self-host Mautic on your VPS: replace Mailchimp or HubSpot with a GPL platform — email campaigns, lead scoring, segmentation, no per-contact fees.",11,1,"2026-01-17T00:00:00+00:00","2026-10-13T14:10:29+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},[165],{"id":17,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fself-host-mautic-vps-poster.svg",{"categorySlug":33,"appSlug":168},"mautic",{"id":170,"slug":171,"slugs":172,"title":176,"excerpt":177,"readTime":178,"views":18,"isPinned":19,"publishedAt":179,"updatedAt":180,"category":181,"categories":182,"featuredImage":29,"bgImage":30,"posterImage":184,"relatedSolution":185},251,"self-host-linkwarden-on-a-vps-team-bookmark-management",{"fr":173,"en":171,"ar":174,"es":175},"heberger-linkwarden-vps","استضافة-linkwarden-على-vps-إدارة-الإشارات-المرجعية-للفريق","alojar-linkwarden-en-un-vps","Self-host Linkwarden on a VPS: team bookmark management","Deploy Linkwarden on your VPS to centralize your agency's shared research: team collections, per-member permissions, shared annotations and multi-user browser extension.",8,"2026-08-13T00:00:00+00:00","2026-09-21T15:22:04+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},[183],{"id":17,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fheberger-linkwarden-vps-poster.svg",{"categorySlug":186,"appSlug":187},"collaboration-productivity","linkwarden",1793627886192]