There are many times we have Bootstrapping scripts to manage a highly custom docker setup, while tools like docker-compse and Dockerfile are good for many things, and even when we can just rely on those tools, we often find ourselves writing scripts for repeated actions during development.
These often contain complex one-liners in the form of docker exec
commands. I was hoping to find a more legible way to write these without condensing things in to one line or across multiple exec commands. What I found was I could not only solve for that, but I could include information from the Host computer in to the environment and even stack these Heredoc commands for more advanced usages. I will show a simple one where wed like to inject a simple variable in to the Container's environment (for this one run) as well as execute a Python command within Djangos Admin (manage.py
) console, so it can execute not only with this new information but with full access to django-admin
.
This executes a python script within my Docker conatiner (my-sample.app
) without requiring complex Inline syntax escaping while providing details about the container host to the container.
docker exec -i my-sample.app bash << EOBASH
export HOST_SYSTEM="$(uname -a)"
python /opt/app/my-sample/manage.py shell << EOPYTHON
import os
print("\n\n\n")
print('inside?')
for k, v in os.environ.items():
print(f'{k}={v}')
EOPYTHON
EOBASH
In this case my Host, processes the outer Heredoc (EOBASH
) as, and pipes that to the container via Docker's exec
functionality, here is what its processed form looks like:
export HOST_SYSTEM="Darwin QA3B6S3KJF 21.6.0 Darwin Kernel Version 21.6.0: Thu Sep 29 20:13:56 PDT 2022; root:xnu-8020.240.7~1/RELEASE_ARM64_T6000 arm64"
python /opt/app/my-sample/manage.py shell << EOPYTHON
import os
print("\n\n\n")
print('inside?')
for k, v in os.environ.items():
print(f'{k}={v}')
EOPYTHON
Within the Container, Django's Management Shell (via Python) simply sees (which was the EOPYTHON
heredoc):
import os
print("\n\n\n")
print('inside?')
for k, v in os.environ.items():
print(f'{k}={v}')
The whole process Outputs:
inside?
_=/usr/bin/python
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LC_ALL=en_US.UTF-8
SHLVL=1
DJANGO_SETTINGS_MODULE=my_sample.settings.development
HOST_SYSTEM=Darwin QA3B6S3KJF 21.6.0 Darwin Kernel Version 21.6.0: Thu Sep 29 20:13:56 PDT 2022; root:xnu-8020.240.7~1/RELEASE_ARM64_T6000 arm64
LANG=en_US.UTF-8
HOME=/home/app
PWD=/opt/app/my-sample/
LANGUAGE=en_US:en
HOSTNAME=72e4db3893b2
TZ=UTC