Last time we learned how to get set up with the Google Compute Engine, how to bring up an instance and how to log into it. This time we need to configure the network so the instance can serve data and software so that there is something to serve data.
Setting up the network
By default, all access to your instance is blocked (except for ssh access to log in, of course). This is not very useful for a web server which should be contactable by clients to retrieve web pages.
When we started our instance it was assigned to the default
network. Google's model is that you can have multiple networks;
each network can contain multiple firewall rules and a machine is
assigned to one of those networks which then determines what sort
of web traffic can and cannot reach or leave our machine.
For our web server we will set up a dedicated network that will be more lenient and will allow incoming HTTP/HTTPS traffic. And since this is a new network, we also need to add the ssh exception that is in the default network so that we will be able to ssh into our server.
hdurer@home:~$ gcutil --project=myvps addnetwork webtraffic INFO: Waiting for insert of network webtraffic. Sleeping for 3s. Table of resources: +------------+------------+----------+ | name | addresses | gateway | +------------+------------+----------+ | webtraffic | 10.0.0.0/8 | 10.0.0.1 | +------------+------------+----------+ Table of operations: +---------------------------------------------------------+--------+-------------------------------+----------------+ | name | status | insert-time | operation-type | +---------------------------------------------------------+--------+-------------------------------+----------------+ | operation-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxx-xxxxxxxx | DONE | 2014-04-15T01:23:45.678-07:00 | insert | +---------------------------------------------------------+--------+-------------------------------+----------------+ hdurer@home:~$ gcutil --project=myvps addfirewall httptraffic --description="Allow incoming http" --allowed="tcp:http,tcp:https" --network=webtraffic INFO: Waiting for insert of firewall httptraffic. Sleeping for 3s. Table of resources: +-------------+------------+ | name | network | +-------------+------------+ | httptraffic | webtraffic | +-------------+------------+ Table of operations: +---------------------------------------------------------+--------+-------------------------------+----------------+ | name | status | insert-time | operation-type | +---------------------------------------------------------+--------+-------------------------------+----------------+ | operation-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxx-xxxxxxxx | DONE | 2014-04-15T01:33:55.777-07:00 | insert | +---------------------------------------------------------+--------+-------------------------------+----------------+ hdurer@home:~$ gcutil --project=myvps addfirewall sshtraffic --description="Allow incoming ssh" --allowed="tcp:ssh" --network=webtraffic INFO: Waiting for insert of firewall sshtraffic. Sleeping for 3s. Table of resources: +-------------+------------+ | name | network | +-------------+------------+ | httptraffic | webtraffic | +-------------+------------+ Table of operations: +---------------------------------------------------------+--------+-------------------------------+----------------+ | name | status | insert-time | operation-type | +---------------------------------------------------------+--------+-------------------------------+----------------+ | operation-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxx-xxxxxxxx | DONE | 2014-04-15T01:55:33.111-07:00 | insert | +---------------------------------------------------------+--------+-------------------------------+----------------+
At any point in time you can use gcutil getnetwork webtraffic
and
gcutil getfirewall httptraffic
to check what you have configured.
Next we will have to get us a static ip address so that the server will remain with the same address even if we stop and restart it at some point in the future. This is not strictly necessary, I guess you could implement something that will update your DNS listings from within the instance or have some outside polling going on. But addresses that are in use don't cost anything so there is no loss in getting one.
Google calls static addresses "reserved". As usual, you should
read the he docs to get the full picture. Note amongst other
things that here we need to specify a region whereas we specified
a zone when creating the instance. Zones and regions are
different things, a region consists of multiple zones but overall
you only have to look up in the docs when to give a zone and when
a region. We created our instance in zone us-central1-a
so we
need to get an address in region us-central1
.
hdurer@home:~$ gcutil --project=myvps reserveaddress --region=us-central1 webserveraddress INFO: Waiting for insert of address webserveraddress. Sleeping for 3s. Table of resources: +------------------+-------------+----------+-----------------+ | name | region | status | ip | +------------------+-------------+----------+-----------------+ | webserveraddress | us-central1 | RESERVED | 162.222.111.222 | +------------------+-------------+----------+-----------------+ Table of operations: +---------------------------------------------------------+--------+-------------------------------+----------------+ | name | status | insert-time | operation-type | +---------------------------------------------------------+--------+-------------------------------+----------------+ | operation-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxx-xxxxxxxx | DONE | 2014-04-15T02:02:02.020-07:00 | insert | +---------------------------------------------------------+--------+-------------------------------+----------------+
Again, should you ever forget the details of your addresses, you
can use gcutil listaddresses
and gcutil getaddress <address>
.
At this point it might be a good idea to create a DNS entry for
your server. This is obviously out of the scope of this tutorial
as it depends on how/where you manage your DNS. For the moment I
created the name webserver.hdurer.net
to point to the address
assigned to me.
Now network related things should be set up and we are ready to restart our server with the correct network and ip address. Note that you have to give the actual ip address instead of using the name of the address.
hdurer@home:~$ gcutil \ --project="myvps" \ addinstance "webserver" \ --authorized_ssh_keys="wwwuser:$HOME/cloud/gcekey.pub" \ --zone="us-central1-a" \ --machine_type="f1-micro" \ --network="webtraffic" \ --external_ip_address="162.222.111.222" \ --disk="webserver,mode=rw,boot" \ --noauto_delete_boot_disk INFO: Waiting for insert of instance webserver. Sleeping for 3s. Table of resources: +-----------+----------------+-----------------+---------------+---------+ | name | network-ip | external-ip | zone | status | +-----------+----------------+-----------------+---------------+---------+ | webserver | 10.170.xxx.xxx | 162.222.111.222 | us-central1-a | RUNNING | +-----------+----------------+-----------------+---------------+---------+ Table of operations: +---------------------------------------------------------+--------+-------------------------------+----------------+ | name | status | insert-time | operation-type | +---------------------------------------------------------+--------+-------------------------------+----------------+ | operation-xxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxxx-xxxxxxxx | DONE | 2014-04-15T02:02:03.040-07:00 | insert | +---------------------------------------------------------+--------+-------------------------------+----------------+
Getting the software ready
From now on we need to work on the server:
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/cloud/gcekey -A -p 22 wwwuser@162.222.111.222 -- Warning: Permanently added '162.222.111.222' (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. Last login: Tue Apr 15 07:42:04 2014 from 74.125.61.150 wwwuser@webserver:~$
All we will need for a minimum viable server is a web server. I personally am used to nginx so let's use that:
wwwuser@webserver:~$ sudo apt-get install nginx-light Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: libpcre3 nginx-common The following NEW packages will be installed: libpcre3 nginx-common nginx-light 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. Need to get 634 kB of archives. After this operation, 1271 kB of additional disk space will be used. Do you want to continue [Y/n]? Get:1 http://gce_debian_mirror.storage.googleapis.com/ wheezy/main libpcre3 amd64 1:8.30-5 [242 kB] Get:2 http://gce_debian_mirror.storage.googleapis.com/ wheezy/main nginx-common all 1.2.1-2.2+wheezy2 [73.2 kB] Get:3 http://gce_debian_mirror.storage.googleapis.com/ wheezy/main nginx-light amd64 1.2.1-2.2+wheezy2 [319 kB] # a few boring lines omitted Setting up libpcre3:amd64 (1:8.30-5) ... Setting up nginx-common (1.2.1-2.2+wheezy2) ... Setting up nginx-light (1.2.1-2.2+wheezy2) ...
Create /etc/nginx/sites-available/webserver
with the following content:
server { server_name webserver.hdurer.net; access_log /var/log/nginx/webserver.access.log; location / { alias /home/wwwuser/www/; autoindex on; charset utf-8; expires 5d; add_header Pragma public; add_header Cache-Control "public"; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/nginx-default; } }
Finally, let nginx know about that new configuration and add some contents:
# link that into the enabled sites wwwuser@webserver:~$ sudo ln -s ../sites-available/webserver /etc/nginx/sites-enabled/webserver= # create the directory wwwuser@webserver:~$ mkdir $HOME/www # and add simple =index.html= file. wwwuser@webserver:~$ cat > $HOME/www/index.html <<EOF <html> <head> <title>Testing</title> </head> <body> <h1>It worked!</h1> <p>My web page running on Google's Cloud Engine! </body> </html> EOF # and make sure everything is world readable wwwuser@webserver:~$ chmod -R a+rX $HOME/www # finally, reload the server configurations: wwwuser@webserver:~$ sudo service nginx reload Reloading nginx configuration: nginx.
On your own desktop/laptop/phone you can now surf to you new server (in my case http://webserver.hdurer.net/ as that was the name I assigned the ip address) and see that sample page created.
Voilà! We're done! I won't bore you with the exact details of how I set up my blogs, but given that they are all static sites, things are very similar to that little test page.