<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Buran Host</title>
    <description>The latest articles on DEV Community by Buran Host (@buran_host).</description>
    <link>https://dev.to/buran_host</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4212689%2F8c84c8f0-5127-4502-87c9-d53319260d0a.png</url>
      <title>DEV Community: Buran Host</title>
      <link>https://dev.to/buran_host</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/buran_host"/>
    <language>en</language>
    <item>
      <title>How to Secure SSH on a Fresh VPS in 10 Minutes (Keys, Firewall, Fail2ban)</title>
      <dc:creator>Buran Host</dc:creator>
      <pubDate>Thu, 29 Oct 2026 18:14:29 +0000</pubDate>
      <link>https://dev.to/buran_host/how-to-secure-ssh-on-a-fresh-vps-in-10-minutes-keys-firewall-fail2ban-1njc</link>
      <guid>https://dev.to/buran_host/how-to-secure-ssh-on-a-fresh-vps-in-10-minutes-keys-firewall-fail2ban-1njc</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I run Buran.host, a VPS hosting service. The steps below work on any Debian or Ubuntu server, no matter where it is hosted.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A new VPS is scanned by bots within minutes of getting a public IP address. Open the log of a fresh server and you will already see hundreds of failed root logins. None of this is dangerous if you spend ten minutes on setup first. Here is the short checklist I use on every new server.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create a normal user
&lt;/h2&gt;

&lt;p&gt;Do not work as root. Create a user and give it sudo rights:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser deploy
usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Log in with a key, not a password
&lt;/h2&gt;

&lt;p&gt;On your own computer, create a key (skip this if you already have one):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"my-laptop"&lt;/span&gt;
ssh-copy-id deploy@YOUR_SERVER_IP&lt;span class="sb"&gt;```&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt;
Open a second terminal and check that &lt;span class="o"&gt;{&lt;/span&gt;% raw %&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;ssh deploy@YOUR_SERVER_IP&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt; logs you &lt;span class="k"&gt;in &lt;/span&gt;without asking &lt;span class="k"&gt;for &lt;/span&gt;the account password. Keep the first session open &lt;span class="k"&gt;until &lt;/span&gt;this works. It is your safety net.

&lt;span class="c"&gt;## 3. Turn off root and password logins&lt;/span&gt;

Create the file &lt;span class="o"&gt;{&lt;/span&gt;% raw %&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;/etc/ssh/sshd_config.d/hardening.conf&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;% endraw %&lt;span class="o"&gt;}&lt;/span&gt; with these lines:
&lt;span class="o"&gt;{&lt;/span&gt;% raw %&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;PermitRootLogin no&lt;br&gt;
PasswordAuthentication no&lt;br&gt;
KbdInteractiveAuthentication no&lt;br&gt;
MaxAuthTries 3&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
plaintext

Check the config and reload:



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;sudo sshd -t &amp;amp;&amp;amp; sudo systemctl reload ssh&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
markdown

If `sshd -t` prints nothing, the syntax is fine. Test a new login from a second terminal before closing the first one.

## 4. Enable a firewall

With UFW you allow only what you really need (open 80 and 443 only if you run a website):



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;sudo ufw default deny incoming&lt;br&gt;
sudo ufw default allow outgoing&lt;br&gt;
sudo ufw allow 22/tcp&lt;br&gt;
sudo ufw allow 80,443/tcp&lt;br&gt;
sudo ufw enable&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
markdown

## 5. Add Fail2ban

Fail2ban bans IP addresses that keep failing to log in:



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;sudo apt install fail2ban&lt;br&gt;
sudo systemctl enable --now fail2ban&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
markdown

The defaults already protect SSH. Check it with `sudo fail2ban-client status sshd`.

## 6. Keep the system updated



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;sudo apt install unattended-upgrades&lt;br&gt;
sudo dpkg-reconfigure -plow unattended-upgrades&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Security patches then install by themselves.

## Should you change the SSH port?

Moving SSH from 22 to another port reduces log noise, but it is not real security. Keys and a firewall do the real work. If you change the port, open the new port in the firewall before you reload SSH, otherwise you lock yourself out.

## What if you lock yourself out?

It happens to everyone once. Most providers give you a web console or a rescue mode that does not depend on SSH. Before you start, find where that is in your control panel, so you know it exists.

## Summary

A normal user, key-only login, no root over SSH, a firewall and Fail2ban stop almost all automated attacks. It takes ten minutes, and you only do it once per server.

A longer version with explanations is in our guide: https://buran.host/guides/ssh-hardening

If you are looking for a server to practice on, our plans start here: https://buran.host/vps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ssh</category>
      <category>security</category>
      <category>linux</category>
      <category>vps</category>
    </item>
    <item>
      <title>Run a Telegram Bot 24/7 on a VPS: Python, systemd and Auto-Restart</title>
      <dc:creator>Buran Host</dc:creator>
      <pubDate>Wed, 28 Oct 2026 21:50:38 +0000</pubDate>
      <link>https://dev.to/buran_host/run-a-telegram-bot-247-on-a-vps-python-systemd-and-auto-restart-4l7g</link>
      <guid>https://dev.to/buran_host/run-a-telegram-bot-247-on-a-vps-python-systemd-and-auto-restart-4l7g</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I run Buran.host, a small VPS reseller, so that is the example I use. The steps work on any Ubuntu 22.04 or 24.04 VPS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A Telegram bot that lives on your laptop dies when the laptop sleeps. A small VPS fixes that: it is always on, it has a stable IP, and systemd restarts your bot if it crashes or the server reboots. Here is the whole setup, start to finish.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A VPS with Ubuntu 22.04 or 24.04 (a bot needs very little, 1 GB of RAM is plenty for most bots)&lt;/li&gt;
&lt;li&gt;SSH access&lt;/li&gt;
&lt;li&gt;A bot token from &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt;## 1. Create a user for the bot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not run the bot as root. If the bot has a bug, you want it to be able to damage as little as possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser &lt;span class="nt"&gt;--disabled-password&lt;/span&gt; &lt;span class="nt"&gt;--gecos&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; botuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Install Python and create a virtual environment
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; python3-venv python3-pip git
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; botuser python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv /home/botuser/venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy your bot code to &lt;code&gt;/home/botuser/bot/&lt;/code&gt; (git clone or scp), then install the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; botuser /home/botuser/venv/bin/pip &lt;span class="nb"&gt;install &lt;/span&gt;python-telegram-bot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use whatever library your bot already uses. The systemd part is the same for aiogram, telebot or anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Keep the token out of the code
&lt;/h2&gt;

&lt;p&gt;Put the token in an environment file that only the bot user can read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'BOT_TOKEN=123456:your-token-here'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/botuser/bot.env
&lt;span class="nb"&gt;chown &lt;/span&gt;botuser:botuser /home/botuser/bot.env
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /home/botuser/bot.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Python read it with &lt;code&gt;os.environ["BOT_TOKEN"]&lt;/code&gt;. Never commit the token to git. If it leaks, revoke it in &lt;a class="mentioned-user" href="https://dev.to/botfather"&gt;@botfather&lt;/a&gt; with /revoke.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Write the systemd unit
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;/etc/systemd/system/tgbot.service&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="nt"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;Telegram bot
&lt;span class="nt"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;network-online.target
&lt;span class="nt"&gt;Wants&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;network-online.target

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="nt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;botuser
&lt;span class="nt"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;/home/botuser/bot
&lt;span class="nt"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;/home/botuser/bot.env
&lt;span class="nt"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;/home/botuser/venv/bin/python main.py
&lt;span class="nt"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;always
&lt;span class="nt"&gt;RestartSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;5

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="nt"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two lines that matter are &lt;code&gt;Restart=always&lt;/code&gt; and &lt;code&gt;RestartSec=5&lt;/code&gt;: if the process dies for any reason, systemd starts it again after five seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Start it and enable it on boot
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl daemon-reload
systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; tgbot
systemctl status tgbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;enable&lt;/code&gt; makes the bot start after a reboot. Send your bot a message in Telegram to confirm it answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Read the logs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; tgbot &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This follows the bot output live. Python errors, restarts and crashes all show up here, so it is the first place to look when something goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Updating the bot
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/botuser/bot &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; botuser git pull
systemctl restart tgbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Polling or webhook?
&lt;/h2&gt;

&lt;p&gt;For most small bots, long polling is the simplest choice: no domain, no HTTPS certificate, nothing exposed to the internet. Webhooks make sense when you have many users and want Telegram to push updates to you. Then you need a domain and HTTPS, for example with Caddy in front of the bot.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few mistakes to avoid
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Running as root.&lt;/strong&gt; Use a separate user, as above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard-coding the token.&lt;/strong&gt; Use the env file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No restart policy.&lt;/strong&gt; Without &lt;code&gt;Restart=always&lt;/code&gt; one unhandled exception ends your bot until you notice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running two copies of the same bot.&lt;/strong&gt; Telegram returns a "conflict" error if two processes poll with the same token. Stop the old one first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Want a longer version?
&lt;/h2&gt;

&lt;p&gt;I wrote a step-by-step guide with the same commands here: &lt;a href="https://buran.host/guides/deploy-telegram-bot" rel="noopener noreferrer"&gt;https://buran.host/guides/deploy-telegram-bot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need a server for it, plans start at €12/month with a dedicated IPv4 address: &lt;a href="https://buran.host/vps" rel="noopener noreferrer"&gt;https://buran.host/vps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>python</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>Self-Host Your Password Manager on a VPS: Vaultwarden + Caddy in 15 Minutes</title>
      <dc:creator>Buran Host</dc:creator>
      <pubDate>Wed, 28 Oct 2026 09:54:59 +0000</pubDate>
      <link>https://dev.to/buran_host/self-host-your-password-manager-on-a-vps-vaultwarden-caddy-in-15-minutes-1k93</link>
      <guid>https://dev.to/buran_host/self-host-your-password-manager-on-a-vps-vaultwarden-caddy-in-15-minutes-1k93</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I run Buran.host, a small VPS reseller, so I show everything on my own server. The steps work on any Ubuntu 22.04/24.04 VPS with Docker.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vaultwarden is a lightweight Rust implementation of the Bitwarden server. It works with all the official clients (browser extensions, iOS/Android and desktop apps), and the vault is a single directory with SQLite on your own server. It uses roughly 100–200 MB of RAM, so even the smallest plan is enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Firewall and directory
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; ufw
ufw allow OpenSSH &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw allow 80/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw allow 443/tcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ufw &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nb"&gt;enable
mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /opt/vaultwarden/data &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /opt/vaultwarden
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ADMIN_TOKEN=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 48&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env   &lt;span class="c"&gt;# save this token&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker must be installed (on Ubuntu: &lt;code&gt;curl -fsSL https://get.docker.com | sh&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. docker-compose.yml
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;vaultwarden&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vaultwarden/server:latest&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.env&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DOMAIN=https://vault.example.com&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SIGNUPS_ALLOWED=true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WEB_VAULT_ENABLED=true&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:8085:80"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The port is bound to 127.0.0.1 only: the service reaches the internet through Caddy. Start it with &lt;code&gt;docker compose up -d&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. HTTPS with Caddy
&lt;/h2&gt;

&lt;p&gt;Point an A record for vault.example.com at your server's IP first. Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; caddy
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/caddy/Caddyfile &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
vault.example.com {
    reverse_proxy 127.0.0.1:8085
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;systemctl reload caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caddy obtains and renews the Let's Encrypt certificate by itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Close registration
&lt;/h2&gt;

&lt;p&gt;Open &lt;a href="https://vault.example.com" rel="noopener noreferrer"&gt;https://vault.example.com&lt;/a&gt;, create your account and immediately change &lt;code&gt;SIGNUPS_ALLOWED=true&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; in docker-compose.yml, then run &lt;code&gt;docker compose up -d&lt;/code&gt; again. Otherwise anyone who finds the address can create an account on your server.&lt;/p&gt;

&lt;p&gt;The admin panel lives at &lt;code&gt;/admin&lt;/code&gt;. Here the token is stored in plain form: that is acceptable for a personal server, but the project recommends storing an Argon2 hash in &lt;code&gt;ADMIN_TOKEN&lt;/code&gt; (generated with the &lt;code&gt;vaultwarden hash&lt;/code&gt; command) if you keep the admin panel enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Connect your clients
&lt;/h2&gt;

&lt;p&gt;In any Bitwarden client, choose Self-hosted on the login screen and enter &lt;a href="https://vault.example.com" rel="noopener noreferrer"&gt;https://vault.example.com&lt;/a&gt;. After that, sign in as usual.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Backups — do not skip this
&lt;/h2&gt;

&lt;p&gt;The whole vault is the &lt;code&gt;./data&lt;/code&gt; directory. Keep a copy outside this server: for example an encrypted restic repository on a nightly systemd timer. A copy on the same disk will not save you if the server itself is lost. Test the restore: a backup you have never restored is a hope, not a backup.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;p&gt;Your own password server: your domain, your disk, updates in your hands. The one honest downside: administration is now your job — image updates, backups, monitoring.&lt;/p&gt;

&lt;p&gt;A longer version with FAQ: &lt;a href="https://buran.host/guides/vaultwarden-vps" rel="noopener noreferrer"&gt;https://buran.host/guides/vaultwarden-vps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>selfhosted</category>
      <category>security</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Pay for a VPS with USDT, BTC or TON — No Card, No KYC</title>
      <dc:creator>Buran Host</dc:creator>
      <pubDate>Wed, 28 Oct 2026 09:54:14 +0000</pubDate>
      <link>https://dev.to/buran_host/how-to-pay-for-a-vps-with-usdt-btc-or-ton-no-card-no-kyc-111f</link>
      <guid>https://dev.to/buran_host/how-to-pay-for-a-vps-with-usdt-btc-or-ton-no-card-no-kyc-111f</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I run Buran.host, a small VPS reseller. The steps below are the same for most crypto-friendly hosts, but I use our own checkout as the example.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've ever had a card declined by a hosting provider — or simply don't want to hand over a passport to rent a Linux box — paying in crypto is a practical alternative. Here is how it works end to end, and the mistakes that actually cost people money.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Pick a plan and open an invoice
&lt;/h2&gt;

&lt;p&gt;Choose a server, click "Order" and register with an email address you really read: the invoice, the login details and all renewal reminders go there. The invoice shows an exact amount and a payment address.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Pick the coin — and the right network
&lt;/h2&gt;

&lt;p&gt;Send &lt;strong&gt;the same asset on the same network&lt;/strong&gt; that the invoice names. USDT in particular exists on several networks (TRC-20, ERC-20, TON and others), and they are not interchangeable. USDT sent on the wrong network usually can't be recovered, because the receiving address doesn't control that chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Send the exact amount
&lt;/h2&gt;

&lt;p&gt;Copy the address from the invoice, never retype it, and compare the first and last characters after pasting. If you send too little, the invoice stays open; if you send too much, the difference is normally credited to your account balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Wait for confirmations
&lt;/h2&gt;

&lt;p&gt;TRC-20 and TON usually confirm in under a minute; BTC takes about ten minutes per confirmation. Once the network confirms, the invoice is marked paid and the server is provisioned automatically — typically a few minutes later you receive the IP address, root credentials and a link to the control panel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes that cost real money
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wrong network.&lt;/strong&gt; The classic one. Check twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sending from an exchange and expecting instant arrival.&lt;/strong&gt; Exchanges batch withdrawals; allow extra time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Posting screenshots that show your address and balance.&lt;/strong&gt; Not dangerous, but pointless.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What a legitimate provider never asks for
&lt;/h2&gt;

&lt;p&gt;A seed phrase, a private key, or remote access to your computer. Payment goes to the address on your invoice — nowhere else. If someone claiming to be "support" asks you to send crypto to a different address, it is not the provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do I need ID?
&lt;/h2&gt;

&lt;p&gt;For crypto invoices at our checkout, no documents are required. Card payments go through a payment processor, which may run its own standard checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want the full walkthrough?
&lt;/h2&gt;

&lt;p&gt;A longer step-by-step version, with a short FAQ: &lt;a href="https://buran.host/guides/pay-with-crypto" rel="noopener noreferrer"&gt;https://buran.host/guides/pay-with-crypto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plans start at €12/month for 4 vCPU, 8 GB RAM and 100 GB SSD with a dedicated IPv4 address: &lt;a href="https://buran.host/vps" rel="noopener noreferrer"&gt;https://buran.host/vps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>crypto</category>
      <category>vps</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
