DNS Hosting at Digital Ocean
In November 2014, Digital Ocean announced its newly upgraded DNS hosting service. In addition to being fast and reliable, users have experienced near instantaneous updates to DNS records. Any developer or system administrator can appreciate the advantages of this: no more waiting for IP address updates during system migrations. In this tutorial, we're going to expand the functionality of the console application we built last time to include management of Digital Ocean's DNS service.
Again, you can download the free console application from the Tuts+ Github repository. I've posted a detailed installation guide for the console application on my website. You can also explore my generic installation guide for Digital Ocean apps.
While you can use the Digital Ocean web console to manage your DNS records, you may find it advantageous to programmatically manage them via the API.
Documentation for Digital Ocean's DNS API services is located across two main areas:
We'll focus first on configuring your domains and then on adding the individual DNS records.
Point Your Name Services to Digital Ocean
Before you can activate Digital Ocean's own DNS services, you need to transfer your domain nameservers to the Digital Ocean nameservers:
- ns1.digitalocean.com
- ns2.digitalocean.com
- ns3.digitalocean.com
I'm going to add my StarWars.io domain for this tutorial demonstration. Here's my name server change at my domain registrar:
You may find How to Point to DigitalOcean Nameservers From Common Domain Registrars helpful as well.
Using the Digital Ocean Website to Manage DNS
First, let's add a domain to Digital Ocean's DNS through its web user interface. Along the left navigation menu, click on DNS:
Click Add Domain:
Here's how Digital Ocean displays your DNS record. It's nice that it shows you the generated zone file below:
Next, we'll add a domain A record for www.starwars.io:
Now, let's explore the API, beginning by downloading some of the domains and domain records we just created.
Synchronize Your DNS Records
First, let's download the list of our domains using the API. In our console application, click Domains in the navigation bar and click Sync in the right-hand menu.
The DomainController
code looks like this:
public function actionSync() { $domain = new Domain(); $domain->sync(); $this->redirect('/domain/admin'); }
The Domain model then calls our Ocean component functions and adds each domain found to our local database:
public function sync() { $ocean = new Ocean(); $domains = $ocean->getDomains(); foreach ($domains as $d) { $domain_id = $this->add($d); } }
Here's the API code from the Ocean component to retrieve the domain list:
public function getDomains() { // return the action api $action = $this->digitalOcean->domain(); // return a collection of Action entity $actions = $action->getAll(); return $actions; }
Here's the Domain model Add method:
public function add($domain) { $d = Domain::model()->findByAttributes(array('name'=>$domain->name)); if (empty($d)) { $d = new Domain; } $d->name = $domain->name; $d->ttl = $domain->ttl; $d->zone = $domain->zoneFile; $d->active =1; $d->created_at = $d->created_at; $d->modified_at =new CDbExpression('NOW()'); $d->save(); return $d->id; }
You should see something like this after it completes:
Click on the manage icon in the starwars row and you'll see something like this:
Then, let's sync the domain records for starwars.io. Click Sync Domain Records—this will call the SyncRecords
action in DomainController
:
public function actionSyncrecords($id) { $dr = new DomainRecord(); $dr->sync($id); $this->redirect('/domain/view/'.$id); }
The DomainRecord
model sync method looks like this. It makes a request for the domain name's records and adds each to the DomainRecord
table in our local database:
public function sync($id) { // lookup domain $d = Domain::model()->findByPk($id); $ocean = new Ocean(); $records = $ocean->getDomainRecords($d->name); foreach ($records as $r) { $record_id = $this->add($id,$r); } }
Here's the Ocean component getDomainRecords
method:
public function getDomainRecords($name) { $action = $this->digitalOcean->domainRecord(); $actions = $action->getAll($name); return $actions; }
The DomainRecord
add method is a bit more detailed:
public function add($domain_id,$record) { $dr = DomainRecord::model()->findByAttributes(array('record_id'=>$record->id)); if (empty($dr)) { $dr = new DomainRecord; } $dr->domain_id = $domain_id; $dr->record_id = $record->id; $dr->record_name = $record->name; $dr->record_type = $record->type; $dr->record_data = $record->data; if (isset($record->priority)) $dr->priority = $record->priority; else $dr->priority = null; if (isset($record->port)) $dr->port = $record->port; else $dr->port = null; if (isset($record->weight)) $dr->weight = $record->weight; else $dr->weight = null; $dr->active =1; $dr->created_at =new CDbExpression('NOW()'); $dr->modified_at =new CDbExpression('NOW()'); $dr->save(); return $dr->id; }
Here's what it will look like after the domain records sync:
Adding Domains From Our Console
You can also add Domains and Domain Records from our console manually.
Here's the code in the Domain model that invokes the API request to add the domain:
public function remote_add() { $ocean = new Ocean(); $domain = $ocean->createDomain($this->name, $this->ip_address); $this->save(); return true; }
Here's the Ocean component addDomain
method:
public function createDomain($name,$ip_address) { $action = $this->digitalOcean->domain(); $create = $action->create($name,$ip_address); return $create; }
Then, sync the domain records and add your own:
Here's the DomainRecord
model remote_add method
:
public function remote_add($id) { $d = Domain::model()->findByPk($id); $ocean = new Ocean(); $record = $ocean->createDomainRecord($d->name,$this->record_type,$this->record_name,$this->record_data,$this->priority,$this->port,$this->weight); $this->domain_id = $id; $this->record_id = $record->id; $this->active =1; $this->created_at =new CDbExpression('NOW()'); $this->modified_at =new CDbExpression('NOW()'); $this->save(); return true; }
Here's the Ocean component createDomainRecord
method:
public function createDomainRecord($domain_name,$type,$name,$data,$priority,$port,$weight) { $domainRecord = $this->digitalOcean->domainRecord(); if ($priority=='') $priority=null; if ($port=='') $port=null; if ($weight=='') $weight=null; // return the created DomainRecord entity of the domain 'bar.dk' $created = $domainRecord->create($domain_name,$type, $name, $data,$priority,$port,$weight); return $created; }
You should see something like this in our console:
Here's what Digital Ocean's web console will show—notice how our local view and the remote view are now identical:
As you may have noticed, this code lacks robust error checking, synchronization, update, delete, and other bells and whistles. I leave that to you to extend as you wish.
I hope you've found this exploration of the Digital Ocean DNS API to be helpful.
Please feel free to post your questions and comments below. You can also reach me on Twitter @reifman or email me directly. Follow my Tuts+ instructor page to see future articles on related topics.
Comments