Setting Up a Dedicated Bot VPS
It's Virtually Private!
First off, thank you to several readers who reminded me that I promised a guide to setting up a VPS for botting at the end of THIS post, but then never wrote it!
Using a VPS is a life skill, so I’ve made this a free post and opened comments to everyone.
What is a VPS?
VPS is an acronym meaning Virtual Private Server. They are commonly create-on-demand virtual machines running inside a powerful server, hosted in a high-availability data center. “Virtual” refers to the fact that your particular server exists inside a virtual machine, which is a software or quasi-hardware separated environment for running an isolated operating system. “Private” refers to the fact that your server is not accessible to other users with servers running on that particular physical machine. Each VPS will come with a dedicated IP (or IPs), storage, and some defined claim on processing time.
Often when you see the term “cloud computing”, what is being described is a VPS. I pay some provider for a slice of their available computing power, and in return I get access to low latency, high availability, and the promise that my data is kept secure in their facility.
Who Offers VPS?
Many of the larger web3 players use Amazon Web Services (AWS) for infrastructure. There are several others, including DigitalOcean, Hetzner (popular for European users), and Linode.
Typically a VPS on a shared server costs between $5 - $10 per month.
🚨🚨🚨 SHILL ALERT 🚨🚨🚨
I will provide several links below to the VPS providers I just mentioned. The link to Linode contains a referral code connected with my account. If you sign up with it, you’ll get a $100 credit, good for 60 days. If you remain a customer for another 6 months or so, they will give me a $25 credit to offset my own server bills.
If you’re turned off by referral codes, feel free to sign up with someone else or visit linode.com the old-fashioned way to bypass that completely. I don’t use AWS, DigitalOcean or Hetzner, and have no referral codes on those links.
I host my VPS on Linode, and this guide will demonstrate the process for setting up with them. If you choose another VPS provider that’s OK. They all offer similar configuration choices for operating systems, storage, and remote access.
In the end, Linux is Linux. Once you have the OS handled, everything else is easy to replicate across multiple providers. If you use the Linode credit to practice setting up and tearing down servers, you’ll have the skills to move your infrastructure around without much trouble at any time.
From this point, I assume you’ve created an account and have access to the control panel at cloud.linode.com.
Create a Server
When you access the control panel, you’ll see a prominent option labeled Create. Click it, then click the option to create a “Linode” High Performance SSD Linux Server (this is a VPS).
You will be presented with several options for the new server. I am configuring this example server with the following options:
Distribution Image: Ubuntu 22.04 LTS
Region: Newark, NJ
Most web3 infrastructure (including my preferred RPC, Moralis and Avalanche mempool service Snowsight) have their servers on the US East region. Choosing a VPS data center nearby will reduce latency.
Linode Plan: Shared CPU / Nanode 1 GB
Linode Label: degenbot-vps
Root Password: [redacted]
Write this down or save it in a password manager, you’ll need it to access the server remotely.
SSH Keys: None (if you have an SSH key already, add it here. Otherwise disregard, we will set one up manually later.)
Private IP: Disabled
Once this is done, click Create and your VPS will begin to provision (the virtual machine is created, operating system copied to its storage, and an IP is assigned at the server firewall).
If you click the various headers (Analytics, Network, Storage, Configurations, Backups, Activity Feed, Settings) you’ll find useful information about your VPS.
Wait until the server finishes provisioning (a minute or two), then you will see the status change to RUNNING with a green light.
Now we’re ready to access the server.
Connecting to the Server With SSH
I will not cover SSH in great detail. I’ve already written a lot about it on my free Linux-specific blog at bowtieddevil.com, so please check that out and do some web searches if you want to learn more.
If you’re using Windows and need an SSH client, I recommend PuTTY.
If you’re using MacOS or Linux, SSH is probably pre-installed so you won’t need to install a separate package.
Open a terminal and connect to your new VPS:
devil@hades:~$ ssh email@example.com The authenticity of host '126.96.36.199 (188.8.131.52)' can't be established. ED25519 key fingerprint is SHA256:l1dJaiChif4RSRrG1LOM07VzEfzIXSoNniW7p1huFEo. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '184.108.40.206' (ED25519) to the list of known hosts. firstname.lastname@example.org's password: Welcome to Ubuntu 22.04 LTS (GNU/Linux 5.15.0-27-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Wed May 25 03:34:02 AM UTC 2022 System load: 0.080078125 Usage of /: 9.8% of 24.05GB Memory usage: 15% Swap usage: 0% Processes: 96 Users logged in: 0 IPv4 address for eth0: 220.127.116.11 IPv6 address for eth0: 2600:3c03::f03c:93ff:feac:2f9b The list of available updates is more than a week old. To check for new updates run: sudo apt update The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@localhost:~#
Note that when you’re prompted for the password, the console will not display anything. Type it by hand, or paste your password from the clipboard using
Ubuntu tells me that there are some package updates, so I’ll apply them:
root@localhost:~# apt update [...] root@localhost:~# apt upgrade [...]
It tells me also that a kernel update is available, so I plan to restart. I choose “Cancel” when presented with the option of restarting services, which takes me back to the command line.
Now I reboot the VPS.
[...] Restarting services... Service restarts being deferred: systemctl restart ModemManager.service /etc/needrestart/restart.d/dbus.service systemctl restart packagekit.service systemctl restart polkit.service systemctl restart ssh.service systemctl restart systemd-logind.service systemctl restart unattended-upgrades.service systemctl restart email@example.com No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host. root@localhost:~# reboot root@localhost:~# Connection to 18.104.22.168 closed by remote host. Connection to 22.214.171.124 closed.
After the VPS comes back up, I can resume my work by SSHing into the VPS again.
Maintaining A Session Without Being Logged In
A critical tool for running scripts without maintaining an active login is
screen. It comes pre-installed with Ubuntu, but other distributions may not include it inthe base install. If not, simply add it using the similiar instructions below.
screen will allow you to create a virtual shell that you can attach and detach from. This virtual shell allows all programs running inside it to maintain operation even if you disconnect from it.
It is controlled via keyboard shortcuts, usually prefixed with
screen immediately, then press “space” to dismiss the welcome message. From within
screen, you’ll notice that the terminal looks the exact same. I want you to type some text, then use the shortcut
CTRL+a+c. You’ll notice that a new terminal appears. You now have two virtual shells running inside your
screen session. You can move between them with the shortcut
CTRL+a+n. You can also split the window by using
CTRL+a+S (splits horizontally) or
CTRL+a+| (splits vertically). When you have a split window like this, you can move between panes using
Here is an example of a horizontally split session, showing two virtual shells.
Finally, you can detach from
CTRL+a+d, and then re-attach to it with the command
You can close a virtual shell with the shortcut
CTRL+d, or by the built-in command
exit. When the last virtual shell within a
screen session is closed, it will close that session and return you to the terminal.
Since we will be working with Brownie and the degenbot codebase, we need to intall the necessary Python development libraries, then the package installer
root@localhost:~# apt install python3-dev [...] root@localhost:~# apt install python3-pip [...]
Creating a Local User
It’s always best to work in Linux as a normal user. Always operating as
root is dangerous, because nothing is restricted. Any compromised executable or script can wreck your day.
Here I will create a dedicated
devil user, then add it to a special group
sudo that allows me to perform “superuser” actions, like package installation, when needed.
root@localhost:~# adduser devil Adding user `devil' ... Adding new group `devil' (1000) ... Adding new user `devil' (1000) with group `devil' ... Creating home directory `/home/devil' ... Copying files from `/etc/skel' ... New password: Retype new password: passwd: password updated successfully Changing the user information for devil Enter the new value, or press ENTER for the default Full Name : Bowtied Devil Room Number : Work Phone : Home Phone : Other : Is the information correct? [Y/n] Y root@localhost:~# gpasswd -a devil sudo Adding user devil to group sudo
Now I will disconnect from the VPS and reconnect over SSH as my new user.
devil@hades:~$ ssh firstname.lastname@example.org email@example.com's password: Welcome to Ubuntu 22.04 LTS (GNU/Linux 5.15.0-33-generic x86_64) [...] devil@localhost:~$
Whenever you see the number symbol, this indicates that the current user has regular privileges. When you see the pound / hash symbol, this indicates that the current user has superuser privileges.
Superuser and Python Package Installation
Now I’ll demonstrate how to gain “superuser” privileges using
sudo (a reference to “superuser do”).
devil@localhost:~$ sudo apt install python3-venv [sudo] password for devil: Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: python3-pip-whl python3-setuptools-whl python3.10-venv The following NEW packages will be installed: python3-pip-whl python3-setuptools-whl python3-venv python3.10-venv 0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded. Need to get 2,474 kB of archives. After this operation, 2,888 kB of additional disk space will be used. Do you want to continue? [Y/n] Y [...]
Now I’ll create a dedicated directory for storing the bot scripts, then make a new virtual environment to keep everything clean.
devil@localhost:~$ mkdir bots devil@localhost:~$ cd bots devil@localhost:~/bots$ python3 -m venv .venv devil@localhost:~/bots$ source .venv/bin/activate (.venv) devil@localhost:~/bots$
Now I’ve created and activated a virtual environment to store my bot-related Python packages. With this active, it’s time to install the familiar
devil@localhost:~/bots$ source .venv/bin/activate (.venv) devil@localhost:~/bots$ pip install eth-brownie scipy requests Collecting eth-brownie Downloading eth_brownie-1.18.2-py3-none-any.whl (230 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 231.0/231.0 KB 10.6 MB/s eta 0:00:00 [...] (.venv) devil@localhost:~/bots$ pip install --upgrade websockets [...] Successfully installed websockets-10.3
Pip will complain about a package incompatibility, but I’ve verified that
websockets version 10.3 works perfectly with Brownie 1.18.2. Also it’s required to use
websockets’ very helpful asynchronous iterator functionality —
async for websocket in websockets.connect() — which version 9 did not offer.
Sync With Git
You can use the command line tool
git to synchronize with my
degenbot GitHub repo.
(.venv) devil@localhost:~/bots$ git clone https://github.com/BowTiedDevil/degenbot Cloning into 'degenbot'... remote: Enumerating objects: 405, done. remote: Counting objects: 100% (88/88), done. remote: Compressing objects: 100% (64/64), done. remote: Total 405 (delta 48), reused 62 (delta 24), pack-reused 317 Receiving objects: 100% (405/405), 72.43 KiB | 4.53 MiB/s, done. Resolving deltas: 100% (189/189), done. (.venv) devil@localhost:~/bots$ ls degenbot
Set Up SSH Keys
I recommend using SSH keys for authentication. If you’re using Linux or MacOS, generate a public-private keypair using
ssh-keygen, protected with a password if you choose, then copy the public key to your VPS.
devil@hades:~$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/devil/.ssh/id_rsa): [...] devil@hades:~$ cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZOenjE1Dvb364XfduiRgJUqOOZN8jyqtIw7TyvnvhrK5ata44n7lc3ta9QvVP/3vhx8oWq234LNF0RRbo144NDbBwcFzi+Yb8WJPu8kRZCAkYSGS0mnLvCuyEFnIvy7d78wFiu4k68ic4Spz0V4iXKim91BY0bXo3Eo8TrhK3az7LCowLP37l0jloAv8z9XS5G4mD34q28KzYj9fgNpNYonQ+YTubokp2Jgdk7V+JJKcyWAzMcJgRN2sCoVK3+25uRxnIIEi28CRrcuq/Of/jTJDg4b3P4LtdhlrZyWlhlrCw8VJbxu/r5cYynZWS6ioJD50iyhEdhzznyA7jnI9NQrgd7tis4wHKmEZMSb7lCoC1r6Y49J26yxi0A9XgwX4G431PsB7CBP8pjfx/5WxNfRbqT9JUCL8L0+h3nf4pJe+7fPQzDaMD5adCgOLbnbldOzgqf9Fol977dmOO0NxyJ+HbUQBMeD7qiwkjTwPFKOFGseoSR/v7Woys+FEEi6U= devil@pop-os
On the VPS, you can use
vim or the more user-friendly
nano to paste the contents of
id_rsa.pub into a file named
authorized_keys inside your
devil@localhost:~$ mkdir .ssh devil@localhost:~$ nano .ssh/authorized_keys [paste the key] [save with CTRL+k] devil@localhost:~$ exit logout Connection to 126.96.36.199 closed.
Now reconnect and confirm that you are not prompted for a password (unless you set one using
Once you’ve confirmed that SSH is using keys instead of login passwords, you can disable the password option within the SSH server.
devil@localhost:~$ sudo nano /etc/ssh/sshd_config [find the line that reads: PasswordAuthentication yes] [change it to no] [save and exit] devil@localhost:~$ sudo systemctl restart ssh
Obviously, don’t lose your SSH key! Also never share your private key, which is saved in
Moving Files Around
With SSH running, copying files around is incredibly easy. You can use
scp (secure copy) to copy files to & from your VPS. For example, now I’ll copy a bot off my workstation to the VPS.
devil@hades:~$ scp bots/snowsight.py firstname.lastname@example.org:~/bots snowsight.py 100% 60KB 230.4KB/s 00:00
If you have Brownie networks and users already created, now is a good time to copy them over as well.
devil@hades:~$ scp -r .brownie/accounts/ email@example.com:~/.brownie test_account.json 100% 487 4.7KB/s 00:00 degenbot.json 100% 487 4.3KB/s 00:00 devil@hades:~$ scp -r .brownie/network-config.yaml firstname.lastname@example.org:~/.brownie network-config.yaml 100% 11KB 94.8KB/s 00:00
Now you’re free to create a new
screen session, start your bots, then disconnect at any time.
Degen Code is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.