January 16, 2024
A short introduction into phabalicious
Phabalicious helps developers in their daily live to interact with their projects. For example setting it up locally and get it running, getting data from a remote instance, inspect a remote instance, etc. With this article we’d like to show you how phabalicious works — with a practical approach.
About phabalicious
Phabalicious is an open-source project, created to abstract away the inner workings of a configuration. It is a command line utility written in PHP/Symfony which can be downloaded from GitHub and installed on your local computer. It is using configuration stored in a special file in the root of your project (the fabfile.yaml
) to run tasks in a shell. This shell can be provided by a docker-container, a ssh-connection, a Kubernetes-pod or a local shell. This means, you can store all your devops-scripts in the fabfile and apply it to a list of configurations.
Phabalicious started as a shell-script to reset a Drupal-installation and is now already on its third release. Now it still supports the fabfile-format from version 2, but the command-line syntax changed a lot, and is now more compliant with posix, using a Symfony console as a base for it.
Let’s try it out
For this demo we will install phabalicious in the current folder so it’s easy for you to remove it later. You can find the installation documentation here. Let’s create a demonstration folder:
This should print out
Congratulations! Phab is installed and working! (If not please have a look at the system requirements)
A simple vue-based example
Let’s start with a simple example using a vue hello-world project. First of all we need to create the vue project. Let’s assume you are still in the phab-demonstration
folder:
Vue should have scaffolded a new project into the folder hello-world
. Let’s create a file to store project’s related configuration:
Configuration
One central place to store all project relevant configuration as part of the project, is the .fabfile.yaml
.
The project-configuration is composable and tinkerable from multiple, even remote sources. Here’s a schema describing the inheritance-mechanism from phabalicious:
It describes all possible ways to inherit data with phabalicious. You can inject global configuration available somewhere on a remote server, parts overridden from configuration-files from your local and merged with the actual project-configuration in your fabfile.yaml.
Let’s start with a simple host-config:
Running ../phab list:hosts
should list your config:
Before we continue our demo let’s have a look into the needs
-section. Every config can claim what methods
it needs to work properly.
Methods
Methods know how to deal with certain aspects of your application, e.g. how to interact with a database, how to install your dependencies or how to reset or install a Drupal installation.
Here’s an example for a typical Drupal application:
On the other hand, a vuejs application might look like this:
Every enabled method for a host-configuration can react to the available commands. Let’s have a look.
Commands
Phab provides a bunch of commands (you can list them all via phab list
). One of the most often used commands is reset
, which will make sure, that your local app respects the latest changes from your code and configuration. Usually you run the reset
-command after you switched to a new branch or pulled new code into your local installation.
As we can see in the screen-recording phab will build the yarn application when executing the reset
-command. It’s because of our needs
-declaration in the fabfile.yaml
Scripts
Phabalicious makes it easy to create and modify scripts which can be executed on different instances and from mostly every stage of your task execution. That means you can reuse the same script to configure your environment regardless where it is deployed.
Let’s add a custom script to our project:
Now let’s try this out:
Shells
Shells can interact with a multitude of environments: local or remote servers, even behind jump hosts, dockerized or kubernetized apps. As long as phabalicious can create a shell to your application it can interact with it. So a perfect fit for your local dev-environment and your production hosting.
In the previous example the script was executed in a local shell. Let’s add docker into the mix and create a new configuration, which will build a docker image from our hello-world example and run it. Here’s the adapted .fabfile.yaml
, notice the new host-configuration and a list of docker-tasks:
This is our dockerfile:
So, let’s try this out:
Let’s recap what is happening behind the scene:
phab docker run
will execute the script snippet from the fabfile sectiondockerHosts.dockerized
. The script itself executes another phab command, namelydocker build
which will trigger the compilation of the docker image.- the second line
execute(docker, rm)
will execute the docker taskrm
, which will stop and remove any pending docker container. - After that the docker container will be started.
- Now you should be able to get the output of the app from http://localhost:8080
Now, let’s get into the container and inspect the app:
How does phabalicous know what shell is needed? Most of the time it can be inferred from the used methods for a configuration, but you can explicitly override it via the shellProvider
-config, in our case we use docker-exec
.
Summary
This short intro showed you some key concepts of phabalicious:
- Modular
methods
to adapt the configuration to the needs of your application (in our short example namelyyarn
anddocker
) - How scripts and the replacement-patterns work together to use host-specific configuration in scripts
- How we can interact with our application with the
shell
-command - If you are curious what phabalicious executes under the hood, add
-v
to the command
Hopefully this gave you a rough idea what phabalicious is capable of. We didn’t talk about scaffolders or secrets, jump into the documentation to find out more. There is also a more theoretical blog-post about the architecture of phabalicious. Or wait for the next episode where we try to add a fabfile to an existing drupal project.