Craft CMS – Dev to Production with Nanobox

Craft CMS is a popular PHP content management system used by some well-known companies. It's flexible, simple to use, and easy to get up and running with Nanobox. In this article, I'm going to walk through configuring Craft CMS for Nanobox, working on it locally, and deploying it to production.

If you're not familiar with Nanobox, Nanobox is a "micro-platform" that builds and configures your app anywhere using settings defined in your boxfile.yml. It provides fully virtualized/containerized development environments on your local machine as well as flexible, scalable infrastructures in production.

What is Nanobox?

Download & Install Nanobox

If you haven't already, go ahead and create a free Nanobox account and download and run the Nanobox installer.

Download Craft CMS

Go ahead and download Craft CMS. At the time of writing this, 2.x is the most recent release, but 3.0 is in beta. This article is specific to Craft CMS 2.x, but I'm planning on doing another walkthrough for 3.0 later.

UPDATE: The contents of this article only apply to Craft CMS <2.x. If using Craft CMS 3, check out my Craft 3 walkthrough.

Add a boxfile.yml

Nanobox uses the boxfile.yml to build and configure your app's runtime and environment. Create a boxfile.yml in the root of your project with the following contents:

run.config:
  engine: php
  engine.config:
    runtime: php-7.1
    document_root: public
    webserver: apache
    extensions:
      - ctype
      - pdo
      - pdo_mysql
      - mcrypt
      - gd
      - mbstring
      - json
      - curl
      - dom
      - iconv
      - imagick
      - session
      - zlib

web.craft:
  start:
    php: start-php
    apache: start-apache
  network_dirs:
    data.storage:
      - craft/storage
  log_watch:
    craft[error]: craft/storage/runtime/logs/craft.log
    craft[stacktrace]: craft/storage/runtime/logs/phperrors.log

data.db:
  image: nanobox/mysql:5.6

data.storage:
  image: nanobox/unfs:0.9

This boxfile.yml will get a fresh Craft CMS install up and running. A full explanation of these settings is provided below. Depending on what plugins and/or PHP functions are introduced, you may need to add additional extensions. Those listed correlate with the list of required extensions provided in Craft CMS's minimum server requirements.

Update Your Database Config

Nanobox automatically generates environment variables for required database connection credentials. With the data.db > mysql component in the boxfile.yml, the following environment variables will be generated:

DATA_DB_HOST
DATA_DB_USER
DATA_DB_PASS

The default name of your database will always be gonano. Update your database connection config in craft/config/db.php to use the provided environment variables and database name.

craft/config/db.php

return array(

	// The database server name or IP address.
	'server' => $_ENV['DATA_DB_HOST'],

	// The name of the database to select.
	'database' => 'gonano',

	// The database username to connect with.
	'user' => $_ENV['DATA_DB_USER'],

	// The database password to connect with.
	'password' => $_ENV['DATA_DB_PASS'],

	// The prefix to use when naming tables. This can be no more than 5 characters.
	'tablePrefix' => 'craft',

);

Rename public/htaccess

The base Craft CMS install comes with a public/htaccess file. In order for Apache to recognize it, you need to rename this file to .htaccess.

mv public/htaccess public/.htaccess

Run the App Locally

With your boxfile.yml in place, your database connection updated, and a renamed .htaccess, you're ready to run your app locally. From the root of your project, run:

# add a convenient way to access the app from a browser
nanobox dns add local craftcms.local

# start local virtual environment and run the app
nanobox run php-server

Nanobox will fire up a virtual environment on your local machine, build your app's runtime, provision your data components, then start PHP and Apache, allowing you to access your running app from a browser.

Run the Craft CMS Installer

Visit your running app at craftcms.local/admin and run through the Craft CMS installer. Once installed, you'll be dropped into the Craft dashboard.

Hack Away!

You now have a fully working Craft CMS install running on your local machine. Go ahead and add whatever plugins you need, add and update templates, whatever you want.


Feel free to stop here if you just want to dive into your local dev environment. Nanobox mounts your local codebase into the Nanobox VM so any changes you make to the code will be reflected in your running app. When you're ready to deploy to production, continue on.


Stage the App Locally

(Optional but recommended) Nanobox includes functionality that will fully simulate a production deploy on your local machine with dry-run. It takes your app through a full build/compile/deploy process, but all inside your Nanobox VM. If it works in dry-run, it'll work in production.

Note: The dry-run app is completely separate from your dev app, so you'll have to run through the Craft installer again.

# add a convenient way to access the staged app locally
nanobox dns add dry-run craftcms.st

# deploy to a local dry-run environment
nanobox deploy dry-run

Once the deploy completes, visit the dry-run app and run through the Craft installer: craftcms.st/admin.

Deploy to Production

Nanobox makes deploying Craft CMS to live servers easy. You don't need an FTP client or have to worry about setting up PHP and Apache. Nanobox will do it all for you on your cloud provider of choice.

Note: Deploying to live servers does require a paid Nanobox account.

Add a Provider & Launch an App

In your Nanobox dashboard, under Account Admin > Hosting Accounts, you can link your Nanobox account to your provider of choice. There are official integrations with AWS, Digital Ocean, and Linode, with more on the way. This allows Nanobox to create and manage servers on those providers on your behalf.

If there isn't an official integration with your provider of choice, you can use the open provider spec and create a custom integration.

With a provider added you're ready to launch a new app.

Add the App as a Remote

Add your newly created app as a remote on your local project. From the root of your project, run:

nanobox remote add [app-name]

Deploy!

Now deploy to your live server:

nanobox deploy

Nanobox will package up your code and runtime, ship it up to your live server, build your app's environment and services, then start your app. Every app deployed with Nanobox gets a unique domain following the pattern: username-appname.nanoapp.io. You'll be able to access your live app there or you can use a custom domain.

Run the Craft CMS Installer

To finish setting up your live app, just visit the /admin path on whatever domain you choose to use and run through the Craft CMS installer.

Workflow Changes

When deploying Craft CMS apps with Nanobox, you may need to adjust your workflow somewhat due to the fact that, for security reasons, live environments are read-only. Since PHP is an interpreted language, writable, executable PHP files amount to significant security vulnerability.

Make Config Changes Locally

Craft CMS stores many of it's configuration options in PHP files and will try to update those files when configs are changed. It will not be able to in the read-only production environment. If you're going to make configuration changes, make them locally, and deploy the updated files to your live app.

Update Craft Locally

Using the Craft's built-in updater requires writable permissions and therefore, can't be used in the live, read-only environment. Update Craft in your locally running app, then deploy the updated files.

Update/Install Templates & Plugins Locally

Same problem as above. You won't be able to do this in your live, read-only environment, so templates and plugins need to be installed locally and deployed.


So if you've made it this far, your app is already in production. Everything below is for the sake of providing clarity and information. If you're interested in the details, here we go.


Explanation of the boxfile.yml

Not everybody is too interested in the specifics of what settings in the boxfile.yml actually do, but if you are one who is, here you go.

run.config

The run.config section of the boxfile.yml defines your app's runtime environment and it's configuration.

run.config:
  engine: php
  engine.config:
    runtime: php-7.1
    document_root: public
    webserver: apache
    extensions:
      - ctype
      - pdo
      - pdo_mysql
      - mcrypt
      - gd
      - mbstring
      - json
      - curl
      - dom
      - iconv
      - imagick
      - session
      - zlib

This setup does the following:

  • Specifies the PHP engine, a simple set of scripts that build and configure your PHP runtime based off other settings in the boxfile.
  • Sets the PHP version to 7.1
  • Sets Apache as the webserver with the public directory as the document root. You can also use Nginx if you'd like.
  • Includes all the PHP extensions required by Craft CMS

web.craft

The web.craft section of the boxfile.yml tells Nanobox to create a publicly accessible web component when deployed to production. This is where your app will actually run.

web.craft:
  start:
    php: start-php
    apache: start-apache
  network_dirs:
    data.storage:
      - craft/storage
  log_watch:
    craft[error]: craft/storage/runtime/logs/craft.log
    craft[stacktrace]: craft/storage/runtime/logs/phperrors.log

This config does the following:

  • Starts your app with two helper scripts provided by the PHP engine – start-php and start-apache. These scripts start PHP-FPM and your webserver, accounting for settings used in the boxfile.yml.
  • Sets craft/storage as a network directory. This directory is writable in production, but in order for its contents to persist between deploys, they need to be stored in a separate storage component. This setting mounts that directory into the storage component.
  • Pipes Craft CMS's logs into your app's aggregated log stream.

data.db

The data.db section of the boxfile.yml tells Nanobox to provision a MySQL 5.6 database with your app.

data.db:
  image: nanobox/mysql:5.6

data.storage

The data.storage section of your boxfile.yml tells Nanobox to include a UNFS (User-space Network File System) server that acts as a persistent filesystem for directories that need to be writable in production. Network directories specified in your web component are stored here.

data.storage:
  image: nanobox/unfs:0.9

Posted in PHP, Craft CMS