Running a Script in Docker ========================== Here is a simple example of a wrapper script to call a docker image using the `docker python library `_. .. code-block:: python import argparse import docker parser = argparse.ArgumentParser(description="Docker test script") parser.add_argument("--phrase", type=str) if __name__ == "__main__": args = parser.parse_args() client = docker.from_env() print(client.containers.run("docker/whalesay", f"cowsay {args.phrase}").decode('utf-8')) When running in this configuration, whatever environment the worker is running in must have access to docker. Additionally, if you want assets generated by a dockerfile, you should mount the current working directory to wherever the docker image outputs files to. For example, if a docker image output files to `/output`, the above invocation would be changed to: .. code-block:: python import argparse import os import docker from docker.types import Mount parser = argparse.ArgumentParser(description="Docker test script") if __name__ == "__main__": args = parser.parse_args() client = docker.from_env() # IMPORTANT # # This assumes we have a host directory for media storage (the MEDIA_ROOT setting) that has the same # path inside the container as the host (e.g. volume: /host/path:/host/path) wooey_data_dir = os.getcwd() print( client.containers.run( image="busybox", command=f"dd if=/dev/urandom of=/output/test.garbage bs=1M count=1", mounts=[Mount(target="/output", source=wooey_data_dir, type='bind')], ).decode( "utf-8" ) ) If you are running Wooey inside Docker, then this becomes a bit more complicated as the data directory may be on a mount point different on the host than inside the container. The following script shows how to handle these scenarios: .. code-block:: python import argparse import os import django django.setup() from django.conf import settings import docker from docker.types import Mount parser = argparse.ArgumentParser(description="Docker test script") if __name__ == "__main__": args = parser.parse_args() client = docker.from_env() # our volume is called `wooey_user_uploads`. If we had a NAS, then we could simplify this by ensuring the path # inside the container matches the path on the host -- in which case the above snippet is all that is needed. volume = client.volumes.get('wooey_user_uploads') volume_mount = volume.attrs['Mountpoint'] current_dir = os.getcwd() wooey_data_dir = os.path.join(volume_mount.rstrip('/'), current_dir.replace(settings.MEDIA_ROOT, '').lstrip('/')) print( client.containers.run( image="busybox", command=f"dd if=/dev/urandom of=/output/test.garbage bs=1M count=1", mounts=[Mount(target="/output", source=wooey_data_dir, type='bind')], ).decode( "utf-8" ) )