Docker Shortcuts
One of the great things about docker, is simplifying the installation process for other applications. I recently had a need for a PHP installation, just to run some test scripts. "Wow, I haven't used PHP in a long time, I wonder if it's even installed?" It wasn't.
Docker to the rescue
I decided I just would write some scripts to run the PHP in a docker container:
#!/bin/bash
VERSION=${VERSION:-5}
docker run -v $(pwd):/app -w /app --rm -it --entrypoint 'php' php:$VERSION $@
The value in this was made immediately apparent, when I immediately got the whole "I know I asked for 5.6, but I now realize I need 7.1" spiel. But that was as simple as changing the VERSION
parameter (or I could have let them run VERSION=7.1 <command>
every time, but I'm a merciful sysadmin).
To break down the command into pieces.
docker run
- run a docker container-v $(pwd):/app
- copy the current directory on the host into /app in the container-w /app
- user /app as the working directory in the container. This combined with the volumzing parts just before it make it so your working directory in the container mirrors your working directory on the host.--rm
- delete the container when done running (no loss, since we're just here for processing and the working directory is just a mirror of the host)-it
- docker interactive terminal mode--entrypoint 'php'
- makes it so every command issued to the container starts withphp
php:$VERSION
- use the php docker image of the version specified in the bash variable$@
- this is where the command to glue to the entrypoint goes, and$@
is standard bash for 'everything that was entered on the commandline'
Putting it all together
By putting this script into a file named php
and running chmod +x php
, I now have a script to run php. It gets called through ./php --help
and --help
becomes the $@
parameter, which combined with the entrypoint runs php --help
inside the container. Exactly what we wanted. Except the ./
part. That means the script has to be in the local directory, which means it's going to get copied into the container too.
This time, it's shell to the rescue. I copy the script over ~/docker/bin/php
and add a line to my .zshrc
(or .bashrc
, I'm not here to judge!):
[ -d ~/docker/bin ] && export PATH=~/docker/bin:$PATH
This one simply checks if ~/docker/bin
is a directory, and if so, add it to your PATH
(which is where your shell checks for commands to run). You now have php
available from everywhere on the system, and can run php --version
and see that you are running php without it being installed directly. If you need run an older version (for testing maybe?), simply run VERSION=5 php --version
and after a quick download, you'll see that the php version has changed.
Going further
PHP historically hasn't had issues with version conflicts on a single machine, but ruby and python have. rvm and virtualenv exist purely because of those conflicts. With dockerization, a host machine can stay pristine, while having the ability to run any version of any language on demand. By simply replacing the proper version numbers and swapping php
for python
/ruby
/whatever
, the above script can be used for a whole variety of other languages. A word of warning though, python is pretty rampant in a lot of systems these days. Since I already had python, I named my python script dpython
(for docker-python) to avoid conflicts (my python vim plugins immediately got confused for instance).
This can be extended to many different things. If you want an application sandboxed, it can be run through docker. Do note that I haven't updated these in a while, and I'm sure these aren't the current best practices for building an alpine docker image.
Dockerfile
:
FROM alpine:edge
RUN apk add --no-cache speedtest-cli
ENTRYPOINT ["/usr/bin/speedtest"]
CMD ["--simple"]
~/docker/bin/speedtest
:
#!/bin/bash
VERSION=${VERSION:-latest}
docker run --rm -it speedtest:$VERSION $@
Build using docker build -t speedtest .
and run using speedtest
.
In this example, the speedtest is run from inside the docker container with no volumes. It wouldn't be able to affect anything on the host system. While this may be overkill for speedtest, other programs that you don't FULLY trust, may be properly quarantined in this way, assuming you have a good way to build an image around them.
This also helps keep a server uncluttered if you install lots of programs. You may wind up with a lot of docker images, but those don't cause lingering dependency issues or conflicts in the future. And uninstallation is as simple as deleting the image, no worrying about cleaning up stray orphan libraries.
Conclusion
The upsides here are that it is a super quick, easy "installation" process (I would assume the official PHP image is configured pretty well, better than I could have set up, and assumes that an official image is available for applications you might want to run), version management is simple, and the PHP script is sandboxed (miss a variable and accidentally unlink("/"."")
, no worries, /
in the container is just in the container. You didn't wipe out your entire system!). Plus, once set up, anyone else using these scripts might not even know that their language isn't even installed.
The downsides are having stuff sandboxed. Libraries installed outside the working directory are not going to be available. If you are running a quick webserver, its ports aren't available by default (gotta extend the script in that case). If something goes wrong, it's a non-standard way of doing things, and help may not be available.
The biggest potential downside, is that for this to work for other users, you have to trust someone with docker. Docker is very potent. On macOS or Windows, it is sandboxed inside a VM, but on most Linux installs, it is part of the base OS and has a lot of power. Never give anyone access to docker commands if you wouldn't trust them with root. That's a pretty big step up just to be able to run PHP scripts. If you are using this for yourself, or a group of people who would have root anyway, this is less of an issue.
In all, I would say that it is great way to keep your host in a pristine state, while providing quick access to lesser used, but still sometimes needed languages.