Docker is a toy or not? Or is it still?

Hi all!

I really want to get straight to the topic right away, but it would be more correct to tell a little about my story:

Entry

I'm a programmer with experience developing frontend single page applications, scala/java and nodejs on the server.

For quite a long time (for exactly a couple or three years), I was of the opinion that docker is manna from heaven and generally a very cool tool and absolutely every developer should be able to use it. And from here it follows that every developer should have docker installed on the local machine. What is there about my opinion, you look through the vacancies that are posted on the same hh. Every second one contains a mention of docker, and if you own it, it will be your competitive advantage 😉

Along the way, I met many people with different attitudes towards docker and its ecosystem. Some said that this is a convenient thing that guarantees cross-platform. The second ones didn’t understand why they should run in containers and what profit it would make, the third didn’t care at all and didn’t care (they just wrote code and went home - I envy them, by the way 🙂 )

Reasons to use

Why did I use docker? Probably for the following reasons:

  • database launch, 99% of applications use them
  • running nginx to distribute frontend and proxy to backend
  • you can package the application in a docker image, so my application will work wherever there is docker, the distribution problem is solved right away
  • service discovery out of the box, you can make microservices, each container (connected to the public network) can easily reach the other by alias, very convenient
  • it's fun to create a container and "play around" in it.

What I have always NOT liked about docker:

  • in order for my application to work, docker itself is needed on the server. Why do I need this if my applications work on jre or nodejs and the environment for them is already on the server?
  • if I want to run my (private) locally built image on a remote server, then I need my own docker repository, I need a registry to work somewhere and I also need to configure https, because docker cli only works over https. Oh damn… there are options, of course, to save the image locally via docker save and through scp just throw off the image ... But this is so much gestures. And besides, it looks like a “crutch” solution until its own repository appears
  • docker-compose. It is only needed to run containers. And that's all. He can't do anything else. Docker-compose has a bunch of versions of its files, its own syntax. As declarative as it is, I don't want to read their documentation. I won't need it anywhere else.
  • when working in a team, for the most part people write a Dockerfile very crookedly, do not understand how it is cached, add everything that is necessary and not necessary to the image, inherit from images that are not in dockerhub or a private repository, create some docker-compose files with databases and do not persist anything. At the same time, the developers proudly declare that docker is cool, everything works locally for them, and HR importantly writes in the vacancy: “We use docker and we need a candidate with such work experience”
  • thoughts about raising everything and everything in docker are constantly haunted: postgresql, kafka, redis. It is a pity that not everything works in containers, not everything is easy to configure and run. It is supported by third-party developers, not by the vendors themselves. And by the way, the question immediately arises, vendors do not worry about maintaining their products in docker, why is this, maybe they know something?
  • there is always a question about container data persistence. and then you think, I just mount the host directory or create a docker volume or make a data container which is now deprecated? If I mount a directory I need to make sure that the uid and gid of the user in the container matches the id of the user running the container, otherwise the files created by the container will be created with root ownership. If I use volume then the data will simply be created in some /usr/* and there will be the same story with uid and gid as in the first case. If you launch a third-party component, then you need to read the documentation and look for the answer to the question: “what container directories does the component write files to?”

I've always hated taking too long to fiddle with docker. at the initial stage: I figured out how to run containers, what images to run from, made a Makefile that contained aliases to long docker commands. I hated docker-compose because I didn't want to learn yet another tool in the docker ecosystem. AND docker-compose up I was strained, especially if there were still met build designs, rather than already assembled images. All I really wanted was to just make a product efficiently and quickly. But I could not sort through the use of docker.

Introduction to Ansible

Recently (three months ago), I worked with a DevOps team, almost every member of which had a negative attitude towards docker. For reasons:

  • docker rules iptables (though can be disabled in daemon.json)
  • docker is bad and we won't run it in production
  • if the docker daemon crashes, then all infrastructure containers will crash accordingly
  • no need for docker
  • why docker if there is Ansible and virtual machines

At the same job, I met another tool - Ansible. Once I heard about it, but did not try to write my own playbooks. And now I started writing my tasks and then my vision changed completely! Because I understood: Ansible has modules for running the same docker containers, image assemblies, networks, etc., while containers can be launched not only locally, but also on remote servers! My delight knew no bounds - I found a NORMAL tool and threw away my Makefile and docker-compose files, they were replaced with yaml tasks. The code was reduced by using constructs like loop, when, etc.

Docker to run third party components like db

Recently I got acquainted with ssh tunnels. It turned out that it is very easy to "forward" the port of the remote server to the local port. The remote server can be either a machine in the cloud or a virtual machine running in VirtualBox. If me or my colleague needs a database (or some other third-party component), you can simply start the server with this component and shut it down when the server is not needed. Port forwarding has the same effect as a database running in a docker container.

This command forwards my local port to the remote postgresql server:

ssh -L 9000: localhost: 5432 [email protected]

Using a remote server solves the problem with team development. Several developers can use such a server at once, they do not need to be able to configure postgresql, deal with docker and other sophistications. On a remote server, you can install the same database in docker itself, if it is difficult to install a specific version. All developers need to do is give ssh access!

Recently I read that SSH tunnels are a limited functionality of a normal VPN! You can simply set up OpenVPN or other VPN implementations, set up the infrastructure, and give it to developers to use. It's so cool!

Fortunately, AWS, GoogleCloud and others give a year of free use, so use them! They are cheap if extinguished when not in use. I've always wondered why I would need a remote server like gcloud, I think I found them.

As a virtual machine on the locale, you can use the same Alpine that is actively used in docker containers. Well, or some other lightweight distributions to make the machine boot faster.

Bottom line: you can and should run the database and other infrastructure goodies on remote servers or in virtualbox. I don't need docker for these purposes.

A little about docker images and distribution

I already wrote Article in which I wanted to convey that the use of docker images does not give any guarantee. Docker images are only needed to create a docker container. If you are sewing up on a docker image, then you are sewing up on the use of docker containers and you will only be with them.

Have you seen anywhere that software developers port their products only in a docker image?
The result of most products is binary files for a specific platform, they are simply added to the docker image that is inherited from the desired platform. Have you ever wondered why dockerhub has so many similar images? Type in nginx for example, you will see 100500 images from different people. These people did not develop nginx itself, they just added the official nginx to their docker image and seasoned it with their configs for the convenience of running containers.

In general, you can simply store it in tgz, if someone needs to run it in docker, then let them add tgz to the Dockerfile, inherit from the desired environment and create additional goodies that do not change the application itself in tgz. The one who will create the docker image will know what kind of tgz it is and what it needs to work. This is how I use docker here

Bottom line: I don’t need a docker registry, I’ll use some kind of S3 or just file storage like google drive / dropbox

Docker in CI

All the companies I have worked for are the same. They are usually grocery. That is, they have some kind of one application, one technology stack (well, maybe a couple or three programming languages).

These companies use docker on their servers where the CI process runs. Question - why do you need to build projects in a docker container on your servers? Why not just prepare the build environment, for example, write an Ansible playbook that will install the required versions of nodejs, php, jdk, copy ssh keys, etc. to the server where the build will take place?

Now I understand that this is shooting myself in the legs, because docker does not bring any profit with its isolation. Issues with CI in docker that I encountered:

  • again need a docker image to build. you need to look for an image or write your own dockerfile.
  • 90% that you need to forward some ssh keys, secret data that you don’t want to write to the docker image.
  • the container is created and dies, all caches are lost along with it. the next build will re-download all the dependencies of the project, which is long and inefficient, and time is money.

Developers do not build projects in docker containers (I used to be such a fan though, I feel sorry for myself in the past xD ). In java, it is possible to have several versions and change with one command to the one that is needed now. In nodejs the same thing, there is nvm.

Hack and predictor Aviator

I think that docker is a very powerful and flexible tool, this is its disadvantage (sounds strange, yes). With the help of it, companies easily "sit down" on it, use it where necessary and not necessary. Developers launch their containers, some kind of environment, then it all smoothly flows into CI, production. The DevOps team writes some kind of bicycles to run these containers.

Only use docker on most recent step in your workflow, don't drag it into the project at the start. It will not solve your business problems. He will only move the problems to ANOTHER level and will offer his own solutions, you will be doing double work.

When docker is needed: came to the conclusion that docker is very good at optimizing the delivered process but not at building the basic functionality

If you still decide to use docker, then:

  • be extremely careful
  • don't force docker on developers
  • localize its use in one place, don't spread it across all the Dockefile and docker-compose repositories

PS:

Thank you for reading, I wish you transparent decisions in your affairs and productive working days!

Source: habr.com

Add a comment