The Best Ways To Run a Short Script in a Container
Being able to gracefully network between containers, mount file systems between containers and the host machine, bring up entire config-managed collections of services with one command, and have perfect repeatable builds is a godsend. Docker is the biggest game changer I have seen in my 22 years of professional software development.
The only software a new employee in my team at work has to install on their new MacBook Pro is Docker. Everything else that the team depends on to build, test, and deploy software runs in Docker. All of the Docker commands and configuration are managed in git repositories, so there is a perfect audit trail and precise versioning.
One shortcoming of this approach is when small utilities need to be written and run, the overhead is higher than it should be. For a custom script with custom dependencies that needs to have visibility into the host filesystem, at least three files are needed.
- The script itself.
Dockerfileto choose a base image and install any other dependencies.
docker-compose.ymlfile or another shell script to manage invoking the Docker commands to build the image and run the container.
Three files to manage in source control for one task. Sadface.
There is a better way. Well, two actually...
Following the example below, you can write a single Bash script to define the Dockerfile, Docker build/run commands, and the script to run, all in one. Just replace the
cmd() function content with your own, and change the
FROM line in the
Dockerfile and/or add more dependencies to the container with
Enter The Turdokken
Taking the idea of containerscript even further, Turdokken aims to be your new shebang-line crush. Turdokken is intended to be installed somewhere in the
$PATH of the host it's running on, so that your scripts can use it as their shebang line. The Turdokken utility accepts command-line switches to control installing dependencies, mounting volumes, or options like interactive mode. So it's easy to write a tiny script that runs in a container:
#!/usr/bin/env -S turdokken --install mysql-client mysql --version uname -a echo $HOST_USERNAME echo $@
./myscript.sh foo bar will output:
mysql Ver 15.1 Distrib 10.4.13-MariaDB, for Linux (x86_64) using readline 5.1 Linux 3f73bdfc43c3 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 Linux yourlogin foo bar
NOTE: It is critical that the shebang line starts with #!/usr/bin/env -S turdokken.
In this case, turdokken builds a Docker image with the mysql-client package installed, then runs the container, mounts the script inside the container, then invokes the script using bash inside the container.
You can do anything with any packages, languages, or compilers, even mount local files into the container for reading or modification.
Let me know if you find either of these useful, or if you have any questions.