What's new in Pistacy.io
We can manage, update, restart, and scale each Docker container separately. That's the beauty of containerization. Each container should have a single responsibility. PHP, Nginx, Postgres - each of those does one obvious thing. Creating containers that include multiple services is considered an anti-pattern. The Single Responsibility Principle doesn't apply only to our codebase.
But does it mean that we must not create such anti-pattern containers just because it violates SRP? I believe there is a one good reason why we can violate it, and let me show you that.
Let me describe the problem I encountered. I built a Software Architecture Platform on top of the Symfony framework. I wanted to have integrated Structurizr inside my system. My platform is delivered as a SaaS, Structurizr is an open-source solution. I wanted to combine both to allow users to have a single place to manage the Software Architecture, and their C4 Model made using the Structurizr DSL.
I needed two pieces to integrate:
Docker image is a piece of cake. Pull, mount and ready to use. But the Structurizr CLI was a little problematic. I could use a Java container, but the CLI is used in the terminal. Connection between PHP and Java container would have to be done using at least SSH. That would require a lot of configuration in both containers (PHP as a client, Java as a server), and also requires a lot of code inside the application itself, to connect with SSH server and execute the CLI command.
I wondered - is there a faster way to handle that?
Instead of SSH connection, I could just install Java inside the PHP container. That would allow me to execute the Structurizr CLI just using the shell, in the same container. I could simply use the Symfony Process component as an abstraction. This solution would allow me to save a lot of time!
But there is a catch! Java and PHP are now connected to each other. I cannot scale, update, manage and restart those independently. But, should I care? Let's think about each.
As you can see, there is no reason to avoid installing Java in PHP. But there is a good reason to install it - the time and cost! I can save a lot of time. Instead of configuring all those things, I can just execute shell command directly. And it works like a charm!
Pistacy.io uses php:8.3-fpm image as a base for PHP container. The image is built using a Dockerfile, because I need to install custom extensions and libs. Somewhere inside it, there's just one line that installs Java.
FROM php:8.3-fpm AS base
# ...
RUN apt-get install -y default-jre
# ...
In the codebase, I need to execute the CLI command in the shell to validate the Structurizr DSL syntax, and finally transform it into JSON. As mentioned above, Pistacy.io uses the Symfony Process component to do that. The solution looks like the following:
$process = new Process([
$this->projectDir . '/services/structurizr-cli/structurizr.sh',
'export',
'-workspace', $workingDirectory . '/workspace.dsl',
'-format', 'json',
]);
$process->run();
if (!$process->isSuccessful()) {
// Parse response error and decide what to do in case of error
}
The structurizr.sh
is a official Structurizr CLI release from https://github.com/structurizr/cli. It is installed during deployment and mounted inside the Docker image to be available for the PHP process.
That's all! No additional services, no configuration, no SSH connection. Just old-school shell execution. I saved a lot of time, and it was worth it!
Remember, such approach is an anti-pattern. In some circumstances, it is worth using:
But you need to take the potential problems into consideration:
Such solution works like a charm in my system. But it does not mean that it will work in yours. Remember to always take pros and cons into consideration, to avoid creating a fragile solution, to not create huge Tech Debt.
If you are interested in how this solution works live, I can recommend you to visit https://pistacy.io/, and import the popular Big Bank PLC workspace, which can be found in here: https://github.com/structurizr/examples/blob/main/dsl/big-bank-plc/workspace.dsl. Saving the DSL executes the Structurizr CLI (in Java) to validate it, and executes the Structurizr On-Premises (in Node) to render the diagrams at the background. Everything runs in a single Docker container, using Symfony Process.
If you are looking for the solution for Software Architecture documentation, Pistacy.io allows you to create C4 Models, manage and vote for ADRs and RFCs, create technical documentation, define Architectural Drivers and many more. Try it!
Try Pistacy.io platform - it is free of charge!
It's free - Try it!