Initialize

Commands listed here are used to boost productivity. Within this page you will see my preferred method of initializing a new headless instance and also a GUI desktop box.

Headless 17.10

Consider the new instance being Ubuntu 17.10 Aartful Aardvark (headless server). First and foremost, update the package list. Typically for a new instance, a user logs in as root. We will change this to something else later. Then, install some essential packages.

apt update; apt upgrade, apt dist-upgrade
apt install git htop zsh tmux vim ncdu tree

Create a user name aizan (usually with the uid/guid of 1000) and grants the ability to use sudo. Then, use ssh-copy-id on local computer to place local computer's ~/.ssh/id_rsa.pub SSH public key to the server.

adduser aizan
nano /etc/sudoers
    >> aizan ALL=(ALL:ALL) ALL
ssh-copy-id [email protected]

Now log in with the user aizan.

Then, proceed with installing zsh-prezto and Vundle.vim. Immediately after cloning Vundle.vim's repository, proceed with initializing vim with my version of the ~/.vimrc (see config:vimrc).

Next is securing SSH daemon with my config (less crowded, less comments, but still awesome) and activating the UFW daemon. First, back up the supplied sshd_config in the /etc/ssh and copy my config (see config:ssh). Let's start with activating the UFW daemon first before changing the settings for sshd_config.

sudo apt install ufw
sudo allow ssh; sudo allow http; sudo allow https
sudo ufw enable; sudo ufw status

From the config:ssh, you see that I am using non-standard port for incoming ssh connections. Make sure that before enabling the UFW daemon, the appropriate port for the SSH daemon is allowed, or you will be locked out.

Next is to enable swap by using a swapfile. Run these commands:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile; sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

In some situations, I really like using Docker to run services (e.g. PostgreSQL database) since it eliminates the annoying process of installing and securing them. Thus, let's install Docker and docker-compose. Be sure to log out after running sudo usermod in order for it to take effect. The command to install docker-compose assumes latest available version is v1.18.0 (as of January 2018).

wget -qO- https://get.docker.com/ | sh
sudo usermod -aG docker aizan
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

As for my HTTP server of choice, I would either go with Nginx or Caddy. Nowadays I tend to go with Caddy because of its automated SSL generation (certificate provided by Let's Encrypt) and its super simple configuration. So let's install Caddy. This assumes that you have downloaded Caddy binary from its vendor website and copied to the /usr/local/bin (see the first command).

sudo cp caddy /usr/local/bin; hash -r
sudo setcap cap_net_bind_service=+ep caddy

See my config:systemd-units to use the systemctl to manage Caddy.

And the last part! Sometimes I run services based on Python, so I need to use pip to manage the python packages. Assume python3. I like not invoking sudo when using the pip3 so there is an additional step for that. I also like to use pip-autoremove to remove a package and its dependencies.

And also, let's install Glances.

sudo apt install python3-pip
pip3 install --user glances bottle
PATH=$PATH:~/.local/bin; hash -r
glances -w -p 8880 --username --password

It is better to run Glances with tmux. Also, we need to make sure that the PATH we set above (/.local/bin for python binaries when installed with --user option) is persistent, so let's edit ~/.zshrc.

vim ~/.zshrc
    >> export PATH=$HOME/.local/bin:$PATH

And with Git, we need to run some global configurations:

git config --global core.editor "vim"
git config --global user.name "Aizan Hensem"
git config --global user.email "[email protected]"

GUI 17.10 (Xubuntu)

Common packages as follows:

sudo apt install zsh git htop vim ncdu gnumeric font-manager inkscape synaptic python3.7 python3-pip r-base r-base-dev mkvtoolnix mkvtoolnix-gui

Make the GUI prettier with Numix GTK theme.

sudo apt-add-repository ppa:numix/ppa; sudo apt update
sudo apt install numix-gtk-theme numix-icon-theme-square

Remove useless packages:

sudo apt-get purge pidgin xfburn gnome-mines sgt-puzzles gnome-sudoku

For running Emacs (Evil Mode in Spacemacs) for Org-Mode. Requires Adobe Source Code Pro font for best experience (download from FontSquirrel).

sudo apt install emacs
git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d

Bash Functions

I use zsh as my daily driver for shell operation. Here are some functions I have in my ~/.zshrc to better retain sanity.

function run() { nohup "[email protected]" > /dev/null 2>&1 & disown; }
function control() { sudo systemctl "$2" "$1" }
  1. The run() function allows me to execute GUI application inside my headless VM with run command, provided there is an X-server (e.g. XQuartz or VcXsrv) that can accept and draw the window. All outputs are suppressed and terminal isn't locked.
  2. The control() function allows me to use control as the command to invoke systemctl, such that it takes the name of the service as the first variable and status as the second variable, just like using the good old service command on Ubuntu before the era of systemd. For example, control nginx stop issues a stop signal to nginx via systemctl, instead of sudo systemctl stop nginx. Better semantics!