PHP - - By Bruno Skvorc

Deploying PHP apps to DigitalOcean with Deploybot

In this tutorial, we’ll take a look at how to deploy a PHP application with Dploy Deploybot, a tool that’s free (and full-featured) for a single application, which makes for a perfect test case on whether or not it’s worth paying for. Before continuing, go ahead and sign up for a free account.

Deploybot logo

Specifically, we’ll deploy a simple app I made on DigitalOcean.

Configuring the Droplet

Before proceeding, we should make sure we have a DigitalOcean droplet created and configured (here’s my DigitalOcean referral link if you’d like a head start with some credits). You should also have the API key at the ready (can be obtained here).

In order to be compatible with the app in question, we need to have Nginx and PHP installed on the Droplet, and the virtual host pointing to a folder that will hold subfolders for various releases, like current etc. As per Deploybot documentation:

Description Path Shell Var
Active version link /data/myapp/current
Release being deployed /data/myapp/releases/1434307860 $RELEASE
Application base /data/myapp $BASE
Shared files /data/myapp/shared $SHARED
All releases /data/myapp/releases $RELEASES

So, first order of business: create an Ubuntu 14.04 x64 Droplet in a location near you. It is recommended you tune it up, security wise. A good tutorial is here.

Next, let’s connect to the Droplet and install Nginx. Connect either via the HTML5 console under “Access” in the Droplet’s GUI, or via your own machine’s terminal and then (partially as per this tutorial) execute:

sudo add-apt-repository ppa:ondrej/php5-5.6
sudo apt-get update
sudo apt-get install nginx php5-fpm
curl -sS | php
mv composer.phar /usr/local/bin/composer

Note that I’m skipping the MySQL step because I don’t need it for this particular app. I’m also importing the PHP 5.6 repository, because Ubuntu installs an older version of PHP by default. Finally, I install Composer so it becomes globally available on the Droplet.

The app we’re deploying has a typical setup of having a public subfolder with an entry file called index.php in there. A default Nginx setup will look for files to serve in /usr/share/nginx/html. Let’s make a new folder for our app:

sudo mkdir /usr/share/nginx/spsearch

Then, let’s set up the virtual host. Edit the file /etc/nginx/sites-available/default

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/spsearch;
    index index.php;


    location / {
        try_files $uri $uri/ =404;

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

After restarting Nginx with sudo service nginx restart, the server should be successfully configured. If you try to put a phpinfo file into usr/share/nginx/spsearch/current, you should see the PHP information printed on screen if you visit the Droplet’s IP address in your browser.

Basic DeployBot Setup

I’ll assume you have a repository on Github with an app ready for deployment, like mine. If not, just make one and put a phpinfo file in there if you’d like to follow along and test. You can always change the app’s contents later and deploy a proper app.

Next, connect a repo.

Connecting a repository

Then, we add an environment. Since we’re making a production environment, we’ll leave it at the default values – manual deployment.

Configuring an environment

Under deployment, we choose DigitalOcean under Web Applications. Give those question marks a read if you’re interested in what’s what.

Choosing a destination

On the next setup screen, we have some additional fields to fill out. Most importantly:

  • we need to set the application path to /usr/share/nginx/spsearch.
    Application path changed
  • we need to provide a static file, because the application in question uses a token.php file to provide a Diffbot token, but this file is not in version control as to prevent leakage and theft.
    Static file added
  • we need to tell DeployBot to launch composer install once the deployment is complete. We do this with the pre-launch script because we want the app ready when a new release is symlinked into the current release, rather than suffering downtime post-launch while Composer finishes installing. This is done by just putting composer install into the pre-launch window:
    Pre-deploy command added


We also need to change the deployment user from root (which is no longer allowed, if you followed the security instructions I linked to above) to our newly made one (in my case swader), but we know swader has no access to write in /usr/share/nginx. We need to fix that first.

In the droplet run su - root to log in as root, and then:

usermod -a -G www-data swader
chown -R root:www-data /usr/share/nginx
chmod -R g+rwX /usr/share/nginx

This adds the user to the www-data group, then makes the group own the folder in question, and then allows the group to perform necessary actions on said folder. Finally, we exit back into the regular user, out of root. If you’d like to test this, you need to log out with exit and log back in for group membership to take effect.

We’re now ready to deploy.

Ready screen


To deploy, click one of the many suggested Deploy buttons around the DeployBot GUI.

On the next screen, you get the chance to write a deployment note – just in case you want to let your team know something, or want to put down a reminder for yourself in the future.

Deployment pre-launch screen with note field

Once you hit “Start Deployment”, DeployBot will get down to business.


Depending on the size of your application and possible binary files it contains, this process might take a while, but once it’s done you should be able to notice the files are all where you want them to be:

Deployed app

Let’s see if it works in the browser.

Working site

Sure enough, it works like a charm!

Updating / redeploying

It wouldn’t be much of an efficient deploy process if we had to go into the GUI every single time we want to make an update to the site and trigger the deploy process manually. That’s why there’s the trigger phrase in commit messages. If we make a new commit the message of which contains [deploy: production], this will force DeployBot to deploy to the environment called “production”. Let’s try it out.

I’m making a change to the about page of my app, and committing.

git add -A
git commit -m "Made some changes to the about page. [deploy: production]"
git push origin master

Before I could reload the live site, the DeployBot dashboard already claimed it was done. The deployment was impressively fast due to the minor differences between the two releases.


In this tutorial, we saw what a straightforward tool Deploybot was. While it may not be up there in popularity with the hottest deployment tools, it’s an underdog possibly worth considering. Coupled with reports from tools like Scrutinizer and Travis in the pre-launch scripts, it can be turned into a truly powerful and safe workflow.

Have you tried it? Will you? What tools do you use for your deploy chain? Let us know in the comments!