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"
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
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
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
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
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
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:
- Sync Database & Files from Remote (with local asset strategy)
- Sync Database & Files from Remote (with AWS S3 asset strategy
- Sync Database & Files between Remotes (with local asset strategy
- Sync Database & Files between Remotes (with AWS S3 asset strategy)
- Livestream Logs
- Replicate a Deploy Locally
- SSH into Platform Container
- Dump Local Database
- Activate Custom Git Hooks
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)