Logo Cyca

I have a problem with Docker


Call me a boomer, crazy old dude or whatever less friendly words you want, but I am going to bitch about Docker in this post.

This is not an educational post. It just reflects my mind at the time I write it and in Cyca’s specific case, and depends on my current - limited - knowledge of Docker. Things could change in the future…

Where this is coming from

Background story

I’m almost 40, on a computer since I’m 5, and I wrote code ever since. My first programs were written in BASIC on an Amstrad CPC464, and I’ve never stopped since then, in so many languages, on so many different platforms, including Windows, OSX, GNU, BSD, .Net, PHP, for the desktop, for the web, even for personal assistants back in the days, you name it.

Long story short: I’m not just a PHP developer. I’m not stuck on previous century technologies. I’m just pragmatic here. And yes, I love PHP. And a lot of other languages (although, Javascript is not one of them…).

The case of Cyca

I wanted to integrate Docker early in Cyca’s development, so it would be easy to install and upgrade it, widely available, etc. However, nearly each version increment brought some new issues with Cyca’s Docker images.

I dont’t say it’s entirely Docker’s fault. Of course, with time and personal investment, I would fix these issues. And this is exactly my point.

The promises

Same code everywhere

For all that time I’ve been writing code, I’ve seen countless technologies supposed to ease the burden of development. “You should focus on code, not system-management”, The chase for a truly universal code, able to run everywhere the same way, no matter the OS or hardware, is a never-ending one. For a long time, Java was the closest to this ideal, if it wasn’t for that Virtual Machine … but it literally ran on billions of devices. You still had to adapt your code to your target specificities, but Java’s core could be called universal.

Microsoft brought .Net, which was supposed to make code more consistent across all devices. Well, devices running Microsoft Windows, at least. Of course we had Mono on GNU-Linux computers, for a while, but I think its use was marginal compared to the original framework.

And for few years now, we even speak about “serverless” technologies, and even “no-code”. Well, hum, yeah.

With a - theoretical - “universal” programming language, a developper could focus on code, not the environement it would be executed. That’s theory…

Same “platform” everywhere ?

That would be true in a world where all the operating systems would follow the same rules, whether they are open or closed source. Of course, the reality is a lot different.

So we looked at the universality of code from a different angle. What if we don’t abstract the code but the whole platform it’s executed on ? Again, long story short: containers were born (yeah I know, it wasn’t their main purpose at first, keep reading).

The new promise of containers: as long as the orchestrator runs on your platform so will the containers. Again, that’s for the theory. And, yes, it sounds a lot like Virtual Machine, and not just Java’s.

The lies

Should we speak about a virtual machine, a framework, a container system, the speech towards the developpers is the same: write it once, runs everywhere. That was actually Sun’s slogan for the Java language back in 1995.

What they never told us (developpers) about, is that: yes, we have the tools to write an application once and run it everywhere, but we still can’t really focus on code. Being a developper is still being a developper and something else.

The case of Docker

Original purpose of containers was to have the benefits of a virtual machine (limitation and prioritization of resources) while improving security (by isolating processes). But with Docker, we ended using them very differently. Today, on top of everything else, Docker containers have a packaging purpose. We use Docker to build easily redistributable applications. We use Docker to give another try to code’s universality, which, by itself, could be a good thing, if only it was done right. And I wouldn’t call embeding a whole operating system (even as small as Alpine) to run a 30KB code a good solution.

Yes, and sorry for that, it’s a simple “it should have been done differently but I won’t tell how” kind of sentence.

I may have a long history in writing code, this is it: I’ve only written code.

I’m not an operating system engineer.

Writing code is not the only thing to do, it’s just one out of many

Nowadays, calling someone a “webmaster” is practically an insult. That’s because as computing evolved so the jobs around it. We split up tasks used to be devoted to one knowledgeable to a group of people, each being very specific about what she or he knows. Knowing a bit of everything is less well-perceived as knowing a lot about something specific, especially in a professional environment.

So, when working on Cyca, I am a “hobbyist” PHP developper (I do this without being paid for, on my private time).

Yet, I also need to be a system administrator. Because I need to setup a webserver, with everything that this implies for security. Which means I also have to take care about my whole personal network security, from my modem to the computer I used to write code, through the router, the reverse-proxy, the server, and everything in-between like cables and cabinets, enclosures and power supplies, UPS and storage drives, etc. And you should keep in mind that it has a cost: the hardware of course, and the electricity.

Thankfully, I only have to do this for my own network, for computers I know very well for being mine. I know the hardware, I know the network, and being a geek, I know a bunch of this stuff. Probably not enough for being considered to be very good, but good enough to keep things working and relatively secured, in a well-known environment not subject to regular or unexpected changes.

You still can’t focus on code

As a developper of a publicly released application, I can only wish for it to be installed on as many computers as possible. It’s nothing but in my interest to build such an application. I could have chosen to write it in a truly universal language, which is yet to exist or something close, or use a universal platform, which Docker tries to offer. I decided to write Cyca in PHP, which could be considered as universal as Java or .Net, considering the number of platforms it actually runs on, and give Docker a try on top of it.

But doing so, I faced a problem I feared: almost everything I already did on my home network, security, server management, etc. I have to do it all over again, just to build, test and redistribute a Docker image for Cyca. Not just for me this time, but for everyone. I became responsible of a remote network I know nothing about (yours, the one Cyca needs when you install it on Docker on your own server). And if it doesn’t work, it’s my fault as a developper, not yours as an administrator.

The time I spent on Docker, trying to do all of this, to produce an image that can’t be used in the end, surpasses by an order of magnitude the time I actually spent writing Cyca’s code.

As written in PHP, Cyca needs php-fpm, which is a server, but php-fpm needs a proxy, which could be nginx, apache, or whatever you might think of. It also needs to run a queues supervisor, so the documents and feeds are updated regularly, and a websocket server, so you can have real-time notifications. So, my Docker image needs to take care of that, and that everything works nicely together. But not just for me, for everybody. Because Docker by itself cannot do it.

The problem is no different than running Cyca on a bare-metal server of course. Without Docker, I still need to be sure that Cyca could work on any computer running a specific set of software (this version of nginx, that version of PHP, etc.). But on a bare-metal server, it’s sysadmin responsibility to maintain server’s software up-to-date and secured. If it’s not, he just wouldn’t or couldn’t install Cyca.

I’m a PHP developper. End-users should expect PHP code from me, not a full-blown operating system. Every application has needs for running properly, and while it is my responsibility to inform about these dependencies and respective versions, regardless they are high-level (php-imagick) or low level (Unix-like operating system), it must not be my responsibility to ship my application with these dependencies. And that’s exactly what we do with Docker.

The geek paradox

If, as a geek writing software just because I like it, I release a Docker image for my application, people expect it to be working, at the very least, and to be secured by default. In other words, end-users expect from a simple unpaid developper a lot more (free of charge) than just pure code.

This has deep implications, origins, and consequences which I am not willing to discuss here because it’s already a long post I believe few would entirely read, but in the end, the - long lasting - “hype” around Docker is not a good thing to me. The concept itself is good, and needed at some point, but we gave Docker too much importance, deviating it from its original purpose, and ultimately making it a packaging software rather than a “simple” container solution, bringing to developpers a lot more work than they probably expected. At least, that’s the way I see it.

Not to mention that applications natively available on some architecture (I mainly have ARM in mind) are not always available as a Docker container, recent changes in pulls limitations, etc., which are problems specific to the platform and/or the software mainteners, not the tool by itself.

A lack of freedom

Ultimately, I realised that Docker doesn’t give me more freedom, it takes some away from the end users.

As a laravel application, Cyca could store data in MariaDB, PostgreSQL or SQLServer, can make use of redis, memcached, etc.

I can’t imagine making a Docker image for each combination of database server, caching solution, session handling, etc. So Docker required me to make some choices. Defaults, preventing end-users to use whatever software they like. Not because it’s not technically possible, but because defaults feel safe, in particular when you consider a new, not well-known application, you just want to test and maybe forget tomorrow.

These defaults have considerable implications, and if you just want to use PostgreSQL instead of MariaDB, it’s not just a matter of switching a config variable: you have to take care of installing PostgreSQL by yourself and correctly linking it to Cyca.

On a bare-metal installation, it is actually just a matter of switching a config variable. Even while application is running.

Oh, and there is another consideration: Cyca’s Docker image is a 370MB download, and weights around 1.1GB once running inside your Docker instance. Cyca weights less than 4MB once the code archive is extracted. So, basically, Docker makes you install a fully-fledged operating system on top of your actual operating system, and you don’t have control over it, I do. So, are we still really talking about containers ?

Being - just - a developper again

For these reasons, and more that I may be willing to discuss here or on the microblog, I decided to end activities related to Docker with Cyca for now.

I don’t have the resources (being time, money or interest) to justify spending more time on a viable Docker image for Cyca right now. It may change as time goes by, but I want to focus on code, which is about solving problems, not create new ones, neither to me or my end-users.

I will update everything is needed to reflect this change during this week, including documentation.

Anyone willing to contribute to the project with Docker images of her/his own is still welcome.