DEV Community

Cover image for CraftCMS & Docksal: A Local Dev Match Made in Heaven
mattbloomfield
mattbloomfield

Posted on

CraftCMS & Docksal: A Local Dev Match Made in Heaven

If you've ever joined a new team you know the pain it can be to get a project successfully running locally on your machine. Without Docker there will be an untold number of non-documented configurations and it will inevitably take days to complete your setup. With docker, future updates can be complex and difficult with a myriad of options you don't need.

Having recently found myself in this conundrum I decided to find ways to make local development easy to setup and easy to maintain. After a search across various solutions, Docksal was the clear winner.

If you're not familiar with it, Docksal allows you to simply and easily setup a dockerized, orchestrated environment without ever having to deal with docker compose. In addition, their CLI container comes pre-installed with many of the tools you will need to run common CMSs on popular hosting platforms.

In my case, I am using platform.sh for hosting. Platform.sh is a non-opinionated linux hosting solution that essentially gives you yaml-based configuration to spin up new environments and works seamlessly with git to spin up new environments for PRs and branches. Docksal has platform, Platform.sh's CLI, pre-installed so it works great out of the box.

Docksal also has a CLI, fin, which is easily customizable to suit your needs.


Basic Setup

Our setup uses MySQL 5.7, Redis, & PHP 7.4.

To get started using docksal create a .docksal directory at the root of your CraftCMS repo. Within it you'll need a docksal.yml and docksal.env.

Docksal comes standard with three containers: A database, a web server, and a CLI. You can specify which versions of PHP, MySQL, etc. within your docksal.env. To add new services, use your docksal.yml.

Here is a simple docksal.env. Any variable created here will be accessible within your cli container and within any custom commands you write.

# .docksal/docksal.env

# Run `fin restart` anytime you change these values

PROJECT="project_name"

# Docksal Defaults
DOCKSAL_STACK=default
DOCROOT="web"
DB_IMAGE="docksal/mysql:5.7"
CLI_IMAGE="docksal/cli:php7.4"
COMPOSER_DEFAULT_VERSION=2

# Platform.sh
HOSTING_PLATFORM=platformsh
HOSTING_SITE=xxxxxxxxxx
HOSTING_ENV=production

# MySQL
MYSQL_DATABASE='db_name'
MYSQL_PORT_MAPPING='33061:3306'
MYSQL_ROOT_PASSWORD="root"
Enter fullscreen mode Exit fullscreen mode

And here is a simple docksal.yml that brings in redis as a service.

# .docksal/docksal.yml

version: "2.1"

services:
  redis:
    hostname: redis
    image: wodby/redis:4.0
    environment:
      - REDIS_MAXMEMORY=256m
Enter fullscreen mode Exit fullscreen mode

In my case we use S3 for asset storage, so I'm leveraging the AWS CLI in my cli container. To pass the environment variables into the cli container I add this to my docksal.yml under services

services:
  ...
  cli:
    environment:
      - AWS_ACCESS_KEY_ID
      - AWS_SECRET_ACCESS_KEY
Enter fullscreen mode Exit fullscreen mode

You probably also have secrets you don't want committed to your repository because they are either sensitive or personalized. For that you can use a docksal-local.env. Add this to your .gitignore and use it just as you use the previous file.

# .docksal/docksal-local.env

# Run `fin restart` anytime you change these values
SECRET_PLATFORMSH_CLI_TOKEN=""
DEV_USER=""
INTERNAL_API_KEY=""
DB_PW_STAGING=""
DB_PW_PROD=""
AWS_ACCESS_KEY_ID="" # note how these are used in the yml above
AWS_SECRET_ACCESS_KEY="" # note how these are used in the yml above
Enter fullscreen mode Exit fullscreen mode

Once you have your configuration intact, go ahead and run fin project start. fin is the Docksal CLI and is quite powerful.

If you are going my route of using AWS for asset storage, you'll also want to add a .docksal/services/cli/startup.sh script to install the AWS CLI.

# .docksal/services/cli/startup.sh

sudo apt-get update
sudo apt-get install awscli -y
sudo apt-get install groff -y
aws configure set region us-east-1 --profile default
Enter fullscreen mode Exit fullscreen mode

Anytime you make changes to your configuration files you can run fin restart to restart your containers. If you make changes to the images referenced you may need to run fin project reset <container> e.g. fin project reset cli.

Custom Commands

This is all fine and dandy, but the real magic comes in the form of custom commands. We use these ALL THE TIME.

Go ahead and create a commands directory under .docksal. Any file you place in this directory will be a new command that fin can run.

You can pretty much use any language to write these commands, but I have stuck with bash for now.

One example could be to have an init command that gets docksal running, then installs composer and npm dependencies within the CLI container. Note that these commands will not be dependent on your local npm/composer installs but on what exists in the cli container.

# .docksal/commands/init

#!/bin/sh

BLUE=\\x1B[34m
YELLOW=\\x1B[33m
GREEN=\\x1B[32m
RED=\\x1B[31m
RESET=\\x1b[0m

## Removes any previous containers this preject may have created, then starts and executes npm install/composer install
## Usage: fin init

# Forces whole job to error on failure
set -e

echo "${YELLOW}REMOVING ANY OLD CONTAINERS${RESET}"
fin project rm -f

echo "${YELLOW}STARTING PROJECT CONTAINERS${RESET}"
fin project start

echo "${YELLOW}RUNNING NPM INSTALL${RESET}"
fin exec npm install

echo "${YELLOW}RUNNING COMPOSER INSTALL${RESET}"
fin exec composer install
Enter fullscreen mode Exit fullscreen mode

The most useful of these commands is probably the setup command which allows new devs to get up and running within minutes. It leverages a lot of the jobs below.

Other custom commands I have written and use often:

We use a lambda function to store our local .env file for CraftCMS since it can securely hold secrets. We then request it using a custom command and secure key - basically minimizing the number of tokens we are passing around in Slack/Email. This custom command is found here:

And the node.js-powered Lambda Function is here.

Accessing the CLI container

Sometimes you need to ssh into the CLI container to run certain things, e.g. craft commands like php craft db/migrate

This can be done using the fin bash command.

Platform.sh Token confusion.

It's always best to run platform commands within the CLI container. This is done by prepending the command with fin. This is because the CLI container comes pre-installed with the platform CLI. If it prompts you to log in, generate an API token and store it in your .docksal/docksal-local.env


And there you have it! You're all ready to start developing on CraftCMS using Docksal to supercharge your local setup.

If you like this approach let me know in the comments! If you've found something better, let me know that as well.

Top comments (0)