Deploy Craft CMS to DigitalOcean

Eugene Fedorenko August 29th, 2015
Craft

This guide explains how to launch a website powered by Craft CMS with a proper development environment and workflow behind it. You’ll set up a local development environment, put Craft theme and config files under version control with Git, create and configure a new DigitalOcean droplet, install Craft on it, and then deploy your theme and configs to a live website with DeployBot.

Never heard about Craft before? It’s a superb content management system that provides an incredible amount of control to developers, while staying simple and elegant for users. Recently, we migrated our very own Wildbit website and blog to it and couldn’t be happier.

Setting up a local environment

First things first — you need to set up a local development environment. That’s where you will work on the website and preview changes before deploying them for the rest of the world to see. There are a few excellent guides on setting up a Craft development environment, so I won't cover this part:

Craft setup screen

You’re going to deploy a Craft website to a DigitalOcean droplet. By default its document root is located at /var/www/html/, so it's important to ensure that development environment matches this by renaming the public directory to html. (Don't forget to point MAMP to a new html directory as a document root.)

Once that’s done, there should be a setup screen with a monkey on it at http://‌localhost:8888/admin. This is where you complete a basic setup, creating database tables for Craft and generating a license key.

Committing theme and configs to a repository

Before you start making any changes to the website let's get its files under version control. Start with creating a new blank repository on GitHub, Bitbucket, Beanstalk, or any other Git hosting service.

Craft has one-click updating, so you won’t need to download and update it manually. Normally you should keep both local and production environments up to date to avoid misconfigurations and security issues. It may sound like a good idea to update your local environment, commit changed files, and then deploy them to a production server, but some updates involve database migrations that will inevitably break your live website. A better strategy is to update your local environment first, make sure that everything works, and then update production environment (in this case, a DigitalOcean droplet) separately.

As you won’t copy updated Craft app files to a server it’s better to exclude them from a repository and store only directories and files that you may change, like templates, configs, and public files. For better security the file craft/config/db.php also shouldn’t be kept in a repository as it contains the login credentials for database, and that is not exactly something you want to accidentally share. As such, create or edit a .gitignore file in the root of your project and add these exclusions to it:

craft/app/
craft/plugins/
craft/storage/
craft/config/db.php

Using the Terminal, run the following commands to go to your project directory, create a local repository, add and commit existing files, and finally push them to a remote repository. (Of course you can also use a Git client of your choice for this process.)

# Go to your working copy and create a Git repository:
cd ~/Sites/craft-project
git init
    
# Add and commit all files in working copy:
git add .
git commit -m "Initial commit"
    
# Add a Git remote (change the URL!) and push repository to it:
git remote add origin https://github.com/wildbit/craft-project.git
git push -u origin master

Creating the DigitalOcean droplet

Now it’s time to create a LAMP (Linux, Apache, MySQL & PHP) droplet at DigitalOcean and prepare it for deployments that will come from DeployBot.

Integrate DeployBot with DigitalOcean

In DeployBot go to SettingsIntegrations and connect your DigitalOcean account. DeployBot’s SSH key will be added to a list of public keys at DigitalOcean, so you can easily add it to any new droplet.

Create a new droplet in DigitalOcean. Craft sites will run just fine on their $10/month option with 1 GB RAM. In the Image section switch to the Applications tab and select LAMP on 14.04. I recommend enabling their weekly backups in Available settings. Weekly backups cost 20% of a monthly droplet bill, but getting peace of mind for $2 a month is totally worth it. Under Add SSH Keys enable your personal key and DeployBot’s key.

Create a DigitalOcean droplet

Installing Craft on the droplet

It shouldn’t be too hard as you already went through a similar process in your local environment, although there are some notable differences.

Copy files to droplet

Use an FTP client to copy craft and html directories into /var/www/.

Configure droplet

SSH into a droplet to configure it. You should be able to access it without a password thanks to the SSH key-based authentication configured earlier. For example, this should work (replace the IP with the IP of your own droplet):

ssh root@12.34.56.78

Then, set the correct permissions on the document root and Craft files and directories within:

chown -R www-data:www-data /var/www
chmod -R 770 /var/www
chmod -R 775 /var/www/craft
chmod -R 775 /var/www/html
chmod 774 /var/www/craft/app
chmod 774 /var/www/craft/config
chmod 774 /var/www/craft/storage

Configure Apache, PHP, and MySQL:

1. Enable mod_rewrite in Apache:

a2enmod rewrite

2. Enable Mcrypt in PHP:

php5enmod mcrypt

3. Restart Apache:

service apache2 restart

4. Log into MySQL (root password is shown in Terminal after you SSH into a droplet), and create a new user and database for Craft. Be sure to make a note of whatever password you choose for the craftcms user:

mysql -u root -p
CREATE USER craftcms@localhost IDENTIFIED BY 'ComplexPasswordGoesHere';
CREATE DATABASE craft;
GRANT ALL PRIVILEGES ON craft.* TO craftcms@localhost;
FLUSH PRIVILEGES;
exit

5. Restart MySQL:

service mysql restart

6. Run mysql_secure_installation to prepare MySQL for use in production.

Configure Craft

Let’s configure the production environment. Craft has great built-in support for multiple environments. I recommend you read their guide, then add production environment details to both general.php and db.php.

Here is what an example general.php looks like:

return array(
  'localhost' => array(
    'devMode' => true,
    'siteUrl' => 'http://localhost:8888/',
    'environmentVariables' => array(
      'basePath' => '/users/eugene/Sites/craft-project/html/',
      'baseUrl'  => 'http://localhost:8888/',
    ),
    'testToEmailAddress' => 'dev@email.com',
  ),

  // Use IP address of your droplet below
  '12.34.56.78' => array(
    'siteUrl' => 'http://12.34.56.78/',
    'environmentVariables' => array(
      'basePath' => '/var/www/html/',
      'baseUrl'  => 'http://12.34.56.78/',
    )
  )
);

And here is an example db.php:

return array(
  '*' => array(
    'server' => 'localhost',
    'database' => 'craft',
    'tablePrefix' => 'craft',
  ),

  'localhost' => array(
    'user' => 'root',
    'password' => 'root',
  ),

  // Use IP of your droplet and MySQL credentials of a user you created
  '12.34.56.78' => array(
    'user' => 'craftcms',
    'password' => 'ComplexPasswordGoesHere',
  )
);

Commit configs

Commit and push your updated general.php file into a repository. (Remember that you set Git to ignore db.php, so it won’t show up as changed in Git.)

Configuring the DeployBot environment

In DeployBot connect your repository with Craft files and create a new environment. In general it’s better to keep your production environment in Manualmode to avoid unintended deployments, but while setting things up it’s convenient to keep it in Automatic. You can always change it later.

Environment page

Time to add a target server — choose Files deployment to DigitalOcean. (While we generally recommend using our Atomic deployments, in this case you’re only deploying theme and configs so Files deployment is a simpler option.) Choose your droplet and set Remote Path to /var/www/ — DeployBot’s SSH key was already added during the droplet creation. When you save server we’ll make sure that DeployBot can connect to it, but nothing will be deployed at this point.

DigitalOcean server configuration page in DeployBot

You’ll need to upload the db.php file to the server during the next deployment, and DeployBot's Configuration Files feature was designed specifically for that. It lets you store configs in DeployBot and upload them into a pre-defined location on the server. Go to Configuration Files inside your environment, create db.php file and insert its content from the local file you previously updated.

Configuration file editor

Now return to your server configuration and in the “Upload configuration files”panel choose db.php and specify the destination as craft/config/.

"Upload configuration files" panel

Deploying

Drumroll… It’s time to deploy! Click on the Deploy button in your environment and wait for it to complete. After that point your browser to http://‌‌12.34.56.78/admin/ or http://‌‌12.34.56.78/index.php/admin (use your droplet’s IP) — you should see Craft’s setup screen with a monkey.

Congratulations, now you have a live Craft website and a proper development environment to work with!

What’s next?

There are a few things you might need to take care of before considering this project finished. They’re not directly related to the topic of this guide, but still worth mentioning.

Can’t get rid of index.php? Check the help article ”How do I remove index.php from my URLs?”. Most likely you’ll need to set AllowOverride to All in /etc/apache2/apache2.conf to enable .htaccess directives.

Connect a domain. When a website is ready for prime time, point DNS of your domain name to a droplet’s IP address. Just remember to also replace the IP address with your domain name in general.php and db.php.

Emails. DigitalOcean droplets don’t have a mail server by default, so Craft can’t send any emails to you or other users in your account. I recommend trying Postmark, our other product — it provides unmatched email delivery rates and comes with 25,000 free emails that should last you a long time. Create a Postmark account and server first, then go to your Craft’s admin and enter Postmark SMTP credentials in SettingsEmail.

Staging. A development environment and workflow can’t be considered complete without a staging server. Luckily it’s very easy to create one with DigitalOcean and DeployBot — clone your droplet, add a new environment in DeployBot, and then update your Craft config files with a new environment IP address or a host name.

Security. Talk to a systems engineer or Craft’s support team to make sure that your setup follows best security practices such as using a non-root user.

Comments