Hosting a WordPress Site on Digital Ocean using Laravel Forge

Last Updated October 29, 2016

So, what is Forge?

Forge

Before I answer that, let me explain what Laravel is. Laravel is a PHP framework. — It gives you an excellent starting point if you want to build your own custom web applications. I speak from personal experience, when I say it’s fantastic.

Coming back to the initial question, the same person (Taylor Otwell) behind Laravel, created Forge to help developers get their web apps online faster. While Forge was built with Laravel in mind, they don’t “discriminate.” You can use it with Symfony, WordPress (HEY OH!), Statamic, Craft, or any other PHP application.

Why do we even need Forge?

I really like Digital Ocean as a hosting platform.

  • The interface is clean and intutive
  • It’s cheap and fast

Just to prove my point, here’s their pricing chart:

Digital Ocean Pricing

Against, Site Ground’s cloud hosting prices are almost tripled:

SiteGround Pricing

Seems like a no brainer to me.

The only “problem” with Digital Ocean is that you have to do all the set up yourself. There’s no cPanel. You literally have to install PHP and MySQL.

Now, I know I’m pretty geeky, OK a lot geeky, but even I’m not that geeky. Running all those installations (from a command line no less) doesn’t sound fun, not to mention time consuming.

Remember, how I said the whole point of Forge was to make it easier for developers to get their apps up and running faster? Well, this is the moment where Forge shines.

Forge works as a middle man to set your server for you.


A few other benefits in Forge’s favor

Forge handles automatic deployment

From a workflow standpoint, if you’re using git, you simply commit and push your files to the repository and Forge handles the rest! No more FTPing!

Forge manages your SSL Certificates with Let’s Encrypt

Recently, it came out that Google is giving priority to sites with SSL certificates. Depending on the provider and type of certificate you’re using, this can get costly. So, what are my options?

There’s a service called Let’s Encrypt that provides free SSL certificates. Awesome! So, what’s the catch? The keys only last 90 days. Forge to the rescue (again). Forge handles the renewal for you.

NOTE:

Let’s count the cost.

Forge is $10 / mo: unlimited servers, sites, and deployments.

Then, if you sign up for the $10 / mo Digital Ocean droplet (which is really all you need, for one WordPress site), then you’re spending $20 / mo total. Compared to a similar plan on SiteGround? You’re still coming out ahead, saving $40 / mo. #FTW


Let’s Get Started

If you go to the Forge site, you can set up a free trial:

Forge Free Trial

Provide your information:

provide-information

Connect to git

You should see a success message at the top. Scroll down and click on the link to connect your account to GitHub (or another git repository):

Connect GitHub

When you click the button, it will load a separate screen asking you to enter your credentials.

Once, it’s successfully connected, it will load the Forge screen again. Except, this time, there will be a check next to the connected service.

Connect to Digital Ocean

Scroll down a little further and click the link to connect your Digital Ocean account. (Yes, you’ll already need a Digital Ocean account set up.)

Connect Digital Ocean

NOTE:

You’ll also notice tabs to connect a Linode or Amazon S3 accounts. (Comparable services to Digital Ocean). Pretty cool that it offers those services as options, but I’ve only used Digital Ocean.

Similar to when you connected your GitHub account, you’ll be taken to another page to enter your Digital Ocean credentials. Once Forge is able to successfully authenticate, you’ll be redirected back to the Forge screen with a prompt to “Create Something Amazing.” (How nice.)

Create Server on Forge

Create Server

You’ll enter the information for your servers. Even though Forge provides some fun name combinations, I like to keep mine simple and boring: web1, web2, web3. I’m also running a staging server under the name createdbyahha.

For our purposes, here, I’ve named the server “selfteachme” and changed the server size to a 1 GB droplet.

When you click Create Server your information will be replaced with information for creating another server. If you scroll further down on the page, you’ll find an Active Servers information box. The content will update automatically as it runs through its process. I’ll forewarn you, it can take a while. (~ 5 minutes)

Active Servers Building

When it’s done setting everything up, you’ll receive an email with the credentials you need:

Forge Server Provisioned Email

Now that the server is set up, you’ll need to set up your site.

If you go back to Forge, you’ll notice that the Active Servers box will have changed to green, with a status of active.

Click on the manage button.

Active Servers Active

Create Site

The page that loads contains information about all that sites for that specific server. Right now, the only thing that’s there is the default server. Even if I only have 1 site on a server, I still like to set it up separately, just in case it needs to grow in the future.

For the root domain, I’m going to use yourahhamoment.com. I left the Web Directory as the default value (public).

Forge Server Details

Click the “Add Site” button.

Below the form, is an Active Sites section. As soon as you click the “Add Site” button, your site appears within this section. This part doesn’t take nearly as long for Forge to set up.

Once it’s complete, click on the Manage button.

Active Sites

This page contains information specific to your site. Here, we can connect the repository that contains all your site files.

NOTE:

If you’re interested in more information about git, I’ve written a post, “Getting Started with git.”

Enter your repository name and branch.

If I had to guess, you’re not using Composer, so you can uncheck that.

NOTE:

I actually use Composer to install WordPress plugins. annnddd I’ve written about that. — And, if you do end up using Composer, then you can obviously leave that box checked.

Click install repository.

Install Repository

NOTE:

Occassionally, I’ve tried to set up a site with a blank repository. — I’m just getting started and want to jump the gun. Inevitably, I get this error message:

Invalid Repository Name

As soon as I actually put something in my repository and enter my repository details within Forge (again), that message goes away.

The screen should update to read Installing Repository.

Installing Repository

Once it’s done installing, you’ll see a pane with the site’s details.

Site Details

You’ll need to click on the edit deploy script button.

Edit deploy script button

Remove the last two lines:

composer install --no-interaction --no-dev --prefer-dist
php artisan migrate --force

Let me explain what you’re doing.

This line composer install --no-interaction --no-dev --prefer-dist runs Composer every time you deploy your site. So, again, if you’re using Composer, leave this line, otherwise remove it.

The other line, php artisan migrate --force runs Artisan. This is specific to Laravel. Since, we’re using WordPress, we don’t need this line.

Then, click on the save deploy script button.

Save Deploy Script Button

Still under the deployment section, click on the Enable Quick Deploy button

Enable Quick Deploy Button

Now, anytime you push new code to your repository, your site automatically updates! From a workflow stand point, what does this mean? Well, you don’t have to FTP to your server and try to remember which files you updated, drag, drop, and wait. Everything becomes seamless. Plus, did I mention, git transfers files SO MUCH FASTER than FTP!

Scroll down a little bit further on the page. There’s a section for Slack Deployment Notifications. I have a Slack account set up specifically for my freelance company. There’s a channel there for each active client. Then, I can enable Slack Notifications so anytime Forge is done deploying files, it will send a notification via Slack, letting me know everything went through successfully.

Keep scrolling down, to the very bottom of the page, you’ll find a row of buttons in the bottom right corner. Click on the Edit Files button and select “Edit Nginx Configuration.

Edit Nginx

On line 8, you’ll notice a similar line:

root /home/forge/yourahhamoment.com/public;

Remove public from the address.

Nginx Configuration

Click the Save Button

Everything should be in place. Click the Deploy Now button near the top.

Deploy Now

Now, that everything is set up with Forge, go to your URL:

GoDaddy Notice

Oops! What happened?

True. We have everything set up within Forge, but there’s nothing to tell the Internet that our domain (yourahhamoment.com) is on Digital Ocean’s servers.

Your Site’s DNS

There are 2 ways to go about doing this:

  1. You can go to the service where you registered your domain name (in this case, GoDaddy) and change the CNAME record to point to the server’s IP address.
  2. Or, you can go to the service where you registered your domain name (again, GoDaddy) and point the Nameservers to DigitalOcean. Then, within Digital Ocean, make sure the CNAME record is pointing to the correct IP address.

People are very opinionated about these 2 options. And while, I’ll probably get some negative feedback for making this recommendation, my preference is option #2. I know it seems like more work because you’re having to update records in two places, but I like having the DNS record in the same place as my server provider. Besides, Digital Ocean’s DNS manager is so much cleaner than GoDaddy’s (or any other service I’ve used for that matter.)

The biggest thing you need to take into consideration and be aware of is email. If it’s a new URL, perfect, you don’t have to worry about messing anything up. But, if the site is older and already has email set up, you may want to go with Option #1. Option #2 is not out of the question, you just need to make sure you set up email within Digital Ocean (If you’re using Google Apps, it’s super easy. Click of a button easy.)


Within GoDaddy

NOTE:

I’m not going to go into as much detail here because there are so many options for service providers. Just remember, regardless of what you’re using the steps are similar. Just remember, you’re looking for “Nameservers.”

Go to your site’s details and click on Manage Nameservers.

Manage Nameservers

Click on the Custom Radio button. It should reveal an Edit Nameservers link above the table. Click on that link.

Custom Nameservers

Fill in the nameservers. Digital Ocean actually has 3:

ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com

Add Nameservers

Then, click the save button.

Save Nameserver Settings

Within Digital Ocean

  1. Login
  2. Click on the Networking link within the main navigation.
  3. Click on the Domains link within the left subnavigation.
  4. Add your domain and IP address into the form. If you’re not sure about the IP address, it’s OK. As soon as you click into the text box, it will give you a dropdown of all the droplets within your account. You should see one with the name of the server that we created within Forge.
  5. Click Create Record
  6. Done!

NOTE:

Since I mentioned Google Apps within Digital Ocean earlier… If you’re looking at the your domain’s DNS record, click on the MX button. (Email is typically handled through the MX record). Then, click the button to the right that says, ”Add Gmail MX records”. I told you it was easy.

MX Record

These last couple of steps can take a while to cycle through the Internet. In fact, it can take up to 72 hours! Personally, I’ve never seen it take that long, but just be aware and give yourself (and your clients) plenty of time. In fact, if it’s a new site, I like to go ahead and set this up as soon as we start a project, so I’m not scrambling on the backend, crossing my fingers (and toes) that it will cycle through quickly.

Now, if we go to yourahhamoment.com … (Drum roll, please)

Error on Database

Not what you were expecting, huh? (cymbal crash).

We forgot to set up our database. Ugh. It’s OK, we’re almost done. This is really is the last step.

Setting up the Database

I like to use a free app called SequelPro to handle my databases.

Sequel Pro

So, if you download, install it, and launch it.

Click on the SSH tab

Remember the email we got at the very beginning of this whole process from Forge, saying our server had been provisioned? All our credentials are in there.

Email for Sequel Pro

Plug all that information into Sequel Pro. Click Connect.

You may get an error message, like I did:

Authenticity of Host

Even if you click OK:

SSH Connection Failed

Even though this is frustrating on the set up side of things, it really is a good thing. It means that your server is secure and everything is working like it should.

To fix it, we just need to set up SSH keys on Forge that match our computer. (really secure, right?)

Go to your Terminal. (UGH, I know).

First, you’ll need to check for existing SSH keys.

In Terminal run:

cd ~/.ssh

This checks to see if there is an existing directory named .ssh in your user directory.

If there is, you’ll want to backup your existing keys.

ls

This lists all the subdirectories in the current directory. You should see something similar to the following:

config id_rsa id_rsa.pub known_hosts

Let’s create a folder to hold our backups

mkdir key_backup

Then, we want to copy all our existing keys into this folder

cp id_rsa* key_backup

Then, get rid of the duplicate files.

rm id_rsa*

Now, we need to generate a new SSH key. If you’re on a Mac, this is already built in (I think). At least, I didn’t have to do anything special.

ssh-keygen -t rsa -C “your_email@youremail.com“

This generates a new SSH key using the email address you provide.

The prompt should then say something like:

Enter file in which to save the key (/Users/you/.ssh/id_rsa):

Simply, press enter.

Now, you’ll want to enter a passphrase. On a Mac, there’s an ssh-agent built in so your keys can be saved in the system’s keychain to make life (a little) easier.

Enter passphrase (empty for no passphrase): [Type a passphrase]
# Enter same passphrase again: [Type passphrase again]

Then, you should see something similar to the following:

Your identification has been saved in /Users/you/.ssh/id_rsa.
# Your public key has been saved in /Users/you/.ssh/id_rsa.pub.
# The key fingerprint is:
# 01:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:dbyour_email@youremail.com

Excellent! Now, you just need to add that key to Forge. Unfortunately, it isn’t as easy as copy and paste…well, kind of. You have to make sure you copy the code exactly. No extra whitespace.

In terminal, type

pbcopy < ~/.ssh/id_rsa.pub

NOTE:

In the future, if you’re adding additional sites or creating additional servers, you don’t have to create new keys every time. You can simply add the keys you already have by going to the Terminal and typing:

pbcopy < ~/.ssh/id_rsa.pub

That will copy your keys to your clipboard for copy and paste, every time.


Within Forge

Go to the Servers Detail page and click on the SSH Keys Tab

SSH Keys tag in Forge

Give your key a name and paste the key from your clipboard into the Public key field.

Public Key in Forge

Whew!

Now, go back to Sequel Pro, and click Connect. No problems.

There’s a dropdown, top left, that says Choose Database. Click it, and select Add Database from the dropdown.

Add Database

Give the database a name. I like give my databases the same name as the site. Then, _wp if it’s a WordPress site. Then, I can tell from a glance, if it’s a WordPress site.

Database Name

NOTE:

If you’ve already been doing local development and have the site ready to go, you can import the database, by going to File > Import and finding your SQL export.

Last thing, I promise

Within your WordPress files, go to wp-config.php

You’ll need to change your variables for the database connection to match what was in Forge’s email.

wp-config.php

NOTE:

You don’t need to worry about SSH information within the wp-config.php file.

Save the code. Commit it to your repository and push it.

Remember, we have auto deploy set up. So, that’s it.

NOW, when we load our site in the browser, we see exactly what we want and expect:

Wordpress Install


The Conversation

  • are you storing your wp-config files in your github repo?

    • Amy Dutton

      I am. — I know there are mixed opinions about this and some people are probably shaking their head as they read this 🙂 but most of my repos are private and will always be private.

      Then, I have a trick for local development: I use a file called local-config.php that has my local configurations inclued. That same file is within my .gitignore, so it doesn’t get committed to the repo or pushed to the site.

      Within, wp-config.php, I check to see if local-config.php exists. If it does, it uses those configurations, otherwise, it uses what’s included within wp-config.php

      If it helps, I’ve created gists of my wp-config.php file (https://gist.github.com/ahaywood/89774cd76c8d252aeb47) and my local-config.php file (https://gist.github.com/ahaywood/c8abfb9c5ac6c88e9402)

  • Rohu

    what happens when there is a database change because of a new or modified plugin? how do you manage that as part of your deployment?

  • Robo1

    You rock, amy !!! Thank you so much, dudette ! 😀

  • What is the structure of your git repo? I mean is it just the wp-content directory or the entire directory containing even WordPress?

    • I have almost everything within the git repo. I don’t keep my uploads directory within the repo. WordPress is set up as a submodule. All plugins are loaded through composer.

      All the repos are private, so I’m not exposing database information within wp-config.php.

      Here’s a gist of my .gitignore file: https://gist.github.com/ahaywood/8f12eee136d9de33fd29

  • Amod_D_Kulkarni

    Nice and elaborate explanation. You might want to also add a sentence or two mentioning about the one click install that forge provides for WordPress nowadays. But definitely having the codebase on git is a major plus if there is an intention to change some code frequently.

    • Amy Dutton

      Thanks for the feedback. I’m not crazy about the one click installs though. I have a friend that used to use that feature out of convenience, but ran into several issues when they tried to change servers. The original host had added quite a bit of code to make it run efficiently on their server, but it caused problems on someone else’s.