Seamless usage of docker in any apps

Just a ship
Photo by Ian Taylor / Unsplash

One of the barriers to using docker these days for some developers is the burden to interact with it daily instead of using the usual tools directly. Let's see how we can ease things.

Table of Contents

  1. What's this about ?
  2. How does it works ?
  3. How to use it ?
  4. Help wanted

What's this about ?

In 2022, I believe a lot of us are using docker & docker compose on daily basis. We see a lot of ways on how to interact with it. Some use the raw command line, some wrap it up in Makefile's and there may be other ways.

Here are the constraints we have :

  • MUST work on multiple machine (ARM / AMD, Ubuntu, MacOS, ...)
  • MUST accept parameters
  • SHOULD not affect the current user setup too drastically
  • MUST be on a per project basis to avoid side effects
  • MUST be opt-in
  • SHOULD make the developper forget about docker
functions.sh Makefile Vanilla
Multi-Platform
Per-Project
Accept parameters
Daily usage easy partial hard
Learning curve easy medium hard
Extensibility easy hard -

Now I'll present what I've been using for 5+ years now. First here is the script then I'll explain. (sources).

functions.sh

How does it works ?

Guessing the current bash

This is the tricky part that does the heavy magic. Basically we try to guess the current directory the functions.sh file is in. But because shell script : we have to guess using different methods depending on the shell of your choosing. Here I "support" only bash and zsh.

This script should work on any mac / ubuntu based distribution.

Path helpers

Firstly I assume that you have a .env in the same directory as the functions.sh file. Usually it is the same as the docker compose one (see https://docs.docker.com/compose/env-file/).

The __getSubPath function is to detect if you are in a subdirectory of the APP_PROJECT_PATH. If so we use the relative subdirectory, empty otherwise.

The __docker_exec function is to facilitate the use of the previous function and the working directory (here I assume /var/www/html).

The PHP function

Finally we declare the alias we want. This is the simple part. First we make sure that nothing prevents us from declaring a php function by running the unalias. Then we declare the php which is what you would type (almost) if you were not using any wrapper of some sort. Except that we accept an infinite number of parameters thanks to $*. Finally we make it globally available.

How to use it ?

Once you created the file you will have to run the following every time you open a new bash session (new window, new tab, ...).

$ source ./functions.sh

From now on if you type

user@server:~/myapp
$ php --version;

is equivalent to

user@server:~/myapp
$ docker exec -it -w '/var/www/html/' myapp_php bash -c "php --version";

and

user@server:~/myapp/src/Bundle/SomeBundle
$ php --version;

is equivalent to

user@server:~/myapp/src/Bundle/SomeBundle
$ docker exec -it -w '/var/www/html/src/Bundle/SomeBundle' myapp_php bash -c "php --version";

It will be running inside the container itself so you won't have to think about it anymore.

Help wanted

There are still some things I couldn't figure out yet :

  1. auto source / unsource when entering the project directory. I tried ondir but it is not well maintained so I didn't stick to it.
  2. When running $ php <TAB><TAB> it will use your host autocomplete instead of the container one.
Mastodon