Today I learned

Setting up an Arch Linux dev box in the cloud

Arch Linux is a great distro for getting dev work done on the cloud

Unrelated photo of servers

I do a lot of my day-to-day development work on a Linux VPS in the cloud. This lets me, say, run very taxing Rails projects without thrashing my laptop. For this, I use the same OS as I use on my workstation: Arch Linux!

Here's what I did to set up my on-the-cloud development box.

Get an Arch Linux box

There are 3 providers I can suggest. They more or less have the same offerings; pick one that has the best latency to/from where you live and where you work.

$5 a month

For $5 a month, you can get 1GB RAM. This is okay to play around in, but for day-to-day use, I suggest getting the $10 or $20 plans.

Linode1 GB1x25 GB
Vultr1 GB1x25 GB
DigitalOcean1 GB1x25 GB

$10 a month

For $10 a month, you can get 2GB RAM. CPU is limited to 1x though. It's alright for light day-to-day use.

Linode2 GB1x50 GB
Vultr2 GB1x40 GB
DigitalOcean2 GB1x50 GB

$20 a month

For $20 a month, you can get 4GB RAM and 2x CPU. This is enough for most cases! While 4GB is a bit limited, you can set up a swap file on their really-fast SSD's.

Linode4 GB2x80 GB
Vultr4 GB2x60 GB
DigitalOcean4 GB2x60 GB

Add user

Create your everyday user. For me, that's rsc, but change that as you need. You'll also want to set up sudo, of course, so let's do that.

# As root, add the user
useradd -Nm -g users -G wheel,sys rsc
passwd rsc
# Might as well change the root password.
# Later, you can use `su` to elevate your permissions.

SSH setup

Make sure you can connect to it! After doing this, you can start connecting to your devbox via SSH, and do the rest of this setup via SSH.

# Let's assume the user `rsc`, if you're not that user yet.
su rsc
# Add ssh authorized key to ~/.ssh/authorized_keys
echo "ssh-rsa AAAAAHHLOLPUTYOURKEYHERE" | tee -a ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# Generate our own key for later use

Set up sudo

Arch Linux has no sudo by default. You can use the built-in su, but sudo is much more convenient.

# Set up sudo
pacman -Syu sudo
echo "%wheel ALL=(ALL) NOPASSWD: ALL" | EDITOR="tee -a" visudo

Install packages

Install the packages you'd use on a day-to-day basis. Protip: mosh is a great way to connect to your devbox.

sudo pacman -Syu \
  base-devel git mosh \
  yarn nodejs tmux fish exa vim neovim \
  fzf tig the_silver_searcher


Set up OpenVPN. I'm using the installer script Angristan/OpenVPN-install which will set up everything for you: openVPN, certificates, iptables, generate .ovpn files, and so on.

# OpenVPN setup
curl -O
chmod +x

Tip: Keep this script around, you'll use it to create more VPN credentials.

UFW firewall

We'll be using Uncomplicated Firewall to set up rules. We only want to expose 3 things to the outside world: SSH, Mosh, and OpenVPN.

sudo pacman -Syu ufw

Set up rules

Let's set up some rules. We want to restrict incoming connections, and allow internal traffic to flow freely.

# UFW firewall rules: allow some internal traffic
sudo ufw default deny
sudo ufw allow from  # vpn network
sudo ufw route allow in on tun0 out on tun0  # dont block peer-to-peer

Allow incoming services

Enable the services that you want accessible outside the VPN.

# Allow some services
sudo ufw limit ssh
sudo ufw allow mosh

Make it work with Docker

You will need to add some overrides in /etc/ufw/after.rules. See this article for more info: Solving ufw and Docker issues.

# Read the linked article for the edits
# you will need to make here.
sudo vim /etc/ufw/after.rules
# As mentioned in the article above, you can open
# certain ports to the outside world using:
# (don't do this if you don't plan to open a webserver)
sudo ufw route allow proto tcp from any to any port 80
sudo ufw route allow proto tcp from any to any port 443

Start the firewall

Start and enable your firewall.

# Start and enable
sudo ufw enable
sudo systemctl enable ufw
sudo systemctl start ufw

# Check its status
sudo ufw status

Tip: No need to allow OpenVPN connections yourself. The VPN installer installs its own iptables rules.


Use fail2ban to restrict SSH access to anyone trying to get in and failing to do so.

sudo pacman -Syu fail2ban

Configure fail2ban

Configure fail2ban to "jail" sshd connections. This will shut off SSH access to IP's that try to log in and fail.

nvim /etc/fail2ban/jail.d/sshd.local
enabled = true

Start it

Start fail2ban and auto-start it on boot.

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

NFS server

You can use NFS to access your files from within the VPN. In this example above, we'll be sharing /home/rsc/Dev via NFS.

# Install nfs client and server (do this for your workstation too!)
sudo pacman -Syu nfs-utils

Mount to /srv

Add mount point. We'll be serving things in /srv via NFS.

sudo mount --bind /home/rsc/Dev /srv/Dev

Set up auto-mounting

Edit fstab to auto-mount this path on every boot up.

sudo vim /etc/fstab
/home/rsc/Dev /srv/Dev none rw,bind 0 0

Tell nfsd about it

Edit nfs config to export this path.

sudo vim /etc/exports

Reload your config

Make /etc/exports take effect.

sudo exportfs -arv

Start it

Start and enable server.

sudo systemctl enable nfs-server
sudo systemctl start nfs-server

Git setup

Configure Git like you typically would.

# Configure Git
git config --global url."[email protected]:".insteadOf ""
git config --global "Rico Sta. Cruz"
git config --global "[email protected]"

Secure SSHD config

Secure your SSH server by disabling root login, and only allowing SSH keys.

sudo vim /etc/ssh/sshd_server
PermitRootLogin no
PasswordAuthentication no

Rico's stuff

Here are some other suggestions.

# Install for puppeteer
yay chromium
# Change default shell
chsh -s /usr/bin/fish

Workstation setup

Set up hosts

In your laptop, it'd make sense to add the devbox IP to your /etc/hosts.

# The local one works if you're connected to the VPN.
# Use this when accessing resources, eg `http://devbox.local:4000/`

# The remote one is the public IP address.
# Use this when connecting via mosh or ssh

Set up aliases

Set up an alias so you only have to type A to attach to your working session.

# for fish (type this in a shell)
abbr A 'mosh --experimental-remote-ip=remote [email protected] -- sh -c "tmux attach || tmux"'
# or bash/zsh (add to your .bashrc or .zshrc)
alias A='mosh --experimental-remote-ip=remote [email protected] -- sh -c "tmux attach || tmux"'

Mounting NFS volumes

You can mount the NFS volumes. (Be sure to turn off Git prompts here, it gets slow)

# You also need nfs-utils in the client side
sudo pacman -Syu nfs-utils

# Mount into `/Devbox`
sudo mkdir -P /Devbox
sudo chown -R $(whoami) /Devbox
sudo mount -v devbox.local:/srv /Devbox

You have just read Setting up an Arch Linux dev box in the cloud, written on January 15, 2019. This is Today I Learned, a collection of random tidbits I've learned through my day-to-day web development work. I'm Rico Sta. Cruz, @rstacruz on GitHub (and Twitter!).

← More articles