Skip to content

Instantly share code, notes, and snippets.

@grmartin
Last active October 28, 2022 18:57
Show Gist options
  • Save grmartin/c7145b519f049df71dc806cbdaea7da9 to your computer and use it in GitHub Desktop.
Save grmartin/c7145b519f049df71dc806cbdaea7da9 to your computer and use it in GitHub Desktop.
Execute Piped Scripts in a Docker Container with Content from the Host

Overview

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.

Example

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment