15

Setting up a small web server on Google's Compute Engine — Part 1

qr-code for this page's url

As mentioned in a recent post it struck me as an interesting idea to see if I can create a small vps on Google's Compute Engine (GCE) and host my web sites there.

The following heavily draws from the quickstart guide and other docs there which I followed myself.

Full disclosure: I have a financial interest in Google's wellbeing. While I don't think this influences my writing here you have been warned.

Step 1: Installing the tools

You'll need to install the command line tools. The graphical console is quite powerful, but I personally feel more comfortable with a shell anyway and eventually you will want to write some scripts; at that point you either need the command line tool for a shell script or some helper library to do the work from your scripting language of choice.

The suggested install method (piping a script downloaded from the internet directly into a shell) was a bit too daring for my taste, so I instead downloaded the zip file, unpacked and installed that. The security difference might be marginal but I still felt better that way.

You will once have to authenticate to Google to allow your command line tools to do work on your behalf:

hdurer@home:~$ gcloud auth login --no-launch-browser
Go to the following link in your browser:

    https://accounts.google.com/o/oauth2/auth?scope=....


Enter verification code:

# Open this url in a browser, confirm the access, and enter the
# verification code (some long gibberish text)

You can view your existing projects and create new ones in the Google
Developers Console at: https://console.developers.google.com. If you
have a project ready, you can enter it now.

Enter your Google Cloud project ID (or leave blank to not set): myvps

You are logged in as me@hdurer.net.

To check if all is fine you can list the disk created for you (there should be none as you haven't created any yet — but to find that out the tool need to access your private data, so this is a good test):

hdurer@home:~$ gcutil listdisk
+-----------+---------------+--------+---------+
| name      | zone          | status | size-gb |
+-----------+---------------+--------+---------+

We will need to log into our virtual machine via ssh and for that we will need a key pair. For simplicity we shall have one key pair just for this purpose:

hdurer@home:~$ mkdir /home/hdurer/cloud
hdurer@home:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hdurer/.ssh/id_rsa): /home/hdurer/cloud/gcekey
Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /home/hdurer/cloud/gcekey.
Your public key has been saved in /home/hdurer/cloud/gcekey.pub.

# ... more output which is omitted here

Step 2: Getting a machine up and running

Go to the developer console and create a new project. This will require you to set up payment even if so far nothing will be charged. Let's call our project myvps. When creating it, make sure you have the GCE component activated.

Now we should be ready to start up an instance (a virtual machine). We will take a shortcut and let the GCE add a disk for us. We could first add a disk with the adddisk command and then use that. But we can also skip that step and let the GCE do it — we don't get to control the size of the disk but for the moment that is ok.

Instances are created via the addinstance command:

hdurer@home:~$ gcutil \
    --project="myvps" \
    addinstance "webserver" \
    --authorized_ssh_keys="wwwuser:$HOME/cloud/gcekey.pub" \
    --zone="us-central1-a" \
    --machine_type="f1-micro" \
    --network="default" \
    --external_ip_address="ephemeral" \
    --image=projects/debian-cloud/global/images/debian-7-wheezy-v20140408 \
    --noauto_delete_boot_disk
INFO: Waiting for insert of instance webserver. Sleeping for 3s.
INFO: Waiting for insert of instance webserver. Sleeping for 3s.
...
INFO: Waiting for insert of instance webserver. Sleeping for 3s.
Table of resources:

+-----------+----------------+----------------+---------------+---------+
| name      | network-ip     | external-ip    | zone          | status  |
+-----------+----------------+----------------+---------------+---------+
| webserver | 10.240.xxx.xxx | 23.251.xxx.xxx | us-central1-a | RUNNING |
+-----------+----------------+----------------+---------------+---------+

Table of operations:

+---------------------------------------------------------+--------+-------------------------------+----------------+
| name                                                    | status | insert-time                   | operation-type |
+---------------------------------------------------------+--------+-------------------------------+----------------+
| operation-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxx-xxxxxxx2 | DONE   | 2014-04-14T11:23:45.567-07:00 | insert         |
+---------------------------------------------------------+--------+-------------------------------+----------------+

You may want to check via the gcutil listimages command which images are actually up-to-date when you do this and use the most recent one instead of projects/debian-cloud/global/images/debian-7-wheezy-v20140408 which happened to be the recent one when I wrote this.

Oh, and don't worry about the ephemeral ip address; we'll sort that out later when we need to sort out the firewalling as well.

Let's check the result:

hdurer@home:~$ gcutil listinstances
+-----------+---------------+---------+----------------+----------------+
| name      | zone          | status  | network-ip     | external-ip    |
+-----------+---------------+---------+----------------+----------------+
| webserver | us-central1-a | RUNNING | 10.240.xxx.xxx | 23.251.xxx.xxx |
+-----------+---------------+---------+----------------+----------------+

Step 3: Logging in

At this point we should be ready to log in:

hdurer@home:~$ gcutil ssh --ssh_user=wwwuser --private_key_file=$HOME/cloud/gcekey webserver
INFO: Zone for webserver detected as us-central1-a.
INFO: Running command line: ssh -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i /home/hdurer/gcekey -A -p 22 wwwuser@162.222.xxx.xxx --
Warning: Permanently added '162.222.xxx.xxx' (ECDSA) to the list of known hosts.
X11 forwarding request failed on channel 0
Linux webserver 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
wwwuser@webserver:~$ ls -la
total 24
drwxr-xr-x 3 wwwuser wwwuser 4096 Apr 15 06:38 .
drwxr-xr-x 3 root    root    4096 Apr 15 06:38 ..
-rw-r--r-- 1 wwwuser wwwuser  220 Dec 30  2012 .bash_logout
-rw-r--r-- 1 wwwuser wwwuser 3392 Dec 30  2012 .bashrc
-rw-r--r-- 1 wwwuser wwwuser  675 Dec 30  2012 .profile
drwx------ 2 wwwuser wwwuser 4096 Apr 15 07:38 .ssh
wwwuser@webserver:~$

This is now your own little working vps:

wwwuser@webserver:~$ ps
  PID TTY          TIME CMD
 2290 pts/1    00:00:00 bash
 2873 pts/1    00:00:00 ps

wwwuser@webserver:~$ ls -la
total 24
drwxr-xr-x 3 wwwuser wwwuser 4096 Apr 15 06:38 .
drwxr-xr-x 3 root    root    4096 Apr 15 06:38 ..
-rw-r--r-- 1 wwwuser wwwuser  220 Dec 30  2012 .bash_logout
-rw-r--r-- 1 wwwuser wwwuser 3392 Dec 30  2012 .bashrc
-rw-r--r-- 1 wwwuser wwwuser  675 Dec 30  2012 .profile
drwx------ 2 wwwuser wwwuser 4096 Apr 15 11:38 .ssh

wwwuser@webserver:~$ sudo apt-get update; sudo apt-get upgrade -y
Hit http://gce_debian_mirror.storage.googleapis.com wheezy Release.gpg
Hit http://gce_debian_mirror.storage.googleapis.com wheezy Release
Get:1 http://security.debian.org wheezy/updates Release.gpg [836 B]
Get:2 http://security.debian.org wheezy/updates Release [102 kB]
# And dozens more output lines removed...

Step 4: Shutting down

For now, we'll shut everything down again to properly set up networking:

wwwuser@webserver:~$ exit
logout
Connection to 162.222.xxx.xxx closed.

hdurer@home:~$ gcutil deleteinstance webserver -f --nodelete_boot_pd
INFO: Zone for webserver detected as us-central1-a.
INFO: Waiting for delete of instance webserver. Sleeping for 3s.
INFO: Waiting for delete of instance webserver. Sleeping for 3s.
INFO: Waiting for delete of instance webserver. Sleeping for 3s.
+---------------------------------------------------------+--------+-------------------------------+----------------+
| name                                                    | status | insert-time                   | operation-type |
+---------------------------------------------------------+--------+-------------------------------+----------------+
| operation-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxx-xxxxxxxx | DONE   | 2014-04-14T12:12:12.123-07:00 | delete         |
+---------------------------------------------------------+--------+-------------------------------+----------------+

hdurer@home:~$ gcutil listinstances
+------+------+--------+------------+-------------+
| name | zone | status | network-ip | external-ip |
+------+------+--------+------------+-------------+

The instance is gone but the disk is still there, ready for us to use it again next time:

hdurer@home:~$ gcutil listdisks
+-----------+---------------+--------+---------+
| name      | zone          | status | size-gb |
+-----------+---------------+--------+---------+
| webserver | us-central1-a | READY  |      10 |
+-----------+---------------+--------+---------+

In the next instalment we need to set up the software, firewall rules and add a static ip address to allow our server to work as a web server to host some content.

Update 2014-04-16: The next part is posted.