{"id":40969094,"url":"https://github.com/panubo/bash-container","last_synced_at":"2026-01-22T06:34:43.106Z","repository":{"id":37612014,"uuid":"94942944","full_name":"panubo/bash-container","owner":"panubo","description":"Common container Bash functions","archived":false,"fork":false,"pushed_at":"2026-01-15T06:23:27.000Z","size":100,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-15T12:44:57.157Z","etag":null,"topics":["bash","containerization","containers","docker","docker-entrypoint"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/panubo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-06-20T23:18:00.000Z","updated_at":"2026-01-15T06:23:31.000Z","dependencies_parsed_at":"2022-07-12T16:33:37.657Z","dependency_job_id":null,"html_url":"https://github.com/panubo/bash-container","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/panubo/bash-container","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panubo%2Fbash-container","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panubo%2Fbash-container/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panubo%2Fbash-container/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panubo%2Fbash-container/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/panubo","download_url":"https://codeload.github.com/panubo/bash-container/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panubo%2Fbash-container/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28656965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","containerization","containers","docker","docker-entrypoint"],"created_at":"2026-01-22T06:34:42.446Z","updated_at":"2026-01-22T06:34:43.097Z","avatar_url":"https://github.com/panubo.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bash Container\n\n[![CI Tests](https://github.com/panubo/bash-container/workflows/CI%20Tests/badge.svg)](https://github.com/panubo/bash-container/actions)\n[![Status](https://img.shields.io/badge/status-STABLE-green.svg)]()\n\nCommon container Bash functions used for handling Docker image entrypoint semantics.\n\nAll functions are [Bats](https://github.com/bats-core/bats-core) tested and checked against [ShellCheck](https://github.com/koalaman/shellcheck).\n\n\u003c!-- BEGIN_TOP_PANUBO --\u003e\n\u003e [!IMPORTANT]\n\u003e **Maintained by Panubo** — Cloud Native \u0026 SRE Consultants in Sydney.\n\u003e [Work with us →](https://panubo.com.au)\n\u003c!-- END_TOP_PANUBO --\u003e\n\n## Table of Contents\n\n- [Core Concepts](#core-concepts)\n- [Functions](#functions)\n  - [Process Management](#process-management)\n  - [Service Waiting](#service-waiting)\n  - [File Handling](#file-handling)\n  - [Miscellaneous](#miscellaneous)\n- [Install](#install)\n- [Example Usage](#example-usage)\n- [Bash Strict Mode](#bash-strict-mode)\n- [License](#license)\n- [Status](#status)\n\n## Core Concepts\n\nThis collection of Bash functions simplifies the creation of robust Docker entrypoint scripts. The main goals are:\n\n- **Service-awareness**: Wait for dependent services like databases or message queues to be available before starting the main application.\n- **Dynamic configuration**: Use environment variables to render configuration files at runtime.\n- **Process management**: Manage application processes using `Procfile`-like mechanics.\n- **Filesystem setup**: Handle the mounting of data volumes and template files.\n\n## Functions\n\n### Process Management\n\n| Function                                | Description                                                                    | Usage                               |\n| --------------------------------------- | ------------------------------------------------------------------------------ | ----------------------------------- |\n| `execute \u003cPROCFILE\u003e \u003cCOMMAND\u003e`          | Executes a command from a Procfile. Returns 127 if the command is not found.   | `execute Procfile web`              |\n| `exec_procfile \u003cCOMMAND\u003e`               | A wrapper for `execute` that uses `Procfile` by default.                         | `exec_procfile web`                 |\n| `run_all [PROCFILE]`                    | Runs all commands in a Procfile.                                               | `run_all` or `run_all Deployfile`   |\n| `run_commands \u003cPROCFILE\u003e \u003cCOMMANDS...\u003e` | Runs one or more specified commands from a Procfile.                           | `run_commands Procfile web worker`  |\n| `run_deployfile`                        | Alias for `run_all Deployfile`.                                                | `run_deployfile`                    |\n| `run_procfile`                          | Alias for `run_all Procfile`.                                                  | `run_procfile`                      |\n| `run_procfile_commands`                 | Alias for `run_commands Procfile`.                                             | `run_procfile_commands web`         |\n| `run_deployfile_commands`               | Alias for `run_commands Deployfile`.                                           | `run_deployfile_commands task`      |\n\n### Service Waiting\n\n| Function                                        | Description                                                          | Usage                                     |\n| ----------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------- |\n| `wait_http \u003cURL\u003e [TIMEOUT] [HTTP_TIMEOUT]`      | Waits for an HTTP service to become available.                       | `wait_http http://api:8080 60 5`          |\n| `wait_kubeapi [RETRIES]`                        | Waits for the Kubernetes API to be available. Requires `kubectl`.    | `wait_kubeapi 60`                         |\n| `wait_tcp \u003cHOST\u003e [PORT] [RETRIES] [TCP_TIMEOUT]`| Waits for a TCP port to be open.                                     | `wait_tcp db 5432`                        |\n| `wait_tcp_multi \u003cHOSTS\u003e [MIN] [PORT]...`        | Waits for a minimum number of hosts to have an open TCP port.        | `wait_tcp_multi redis1,redis2 2 6379`     |\n| `wait_mariadb \u003cHOST\u003e [PORT]...`                 | Alias for `wait_tcp` with port 3306.                                 | `wait_mariadb db`                         |\n| `wait_postgres \u003cHOST\u003e [PORT]...`                | Alias for `wait_tcp` with port 5432.                                 | `wait_postgres db`                        |\n| `wait_rabbitmq \u003cHOST\u003e [PORT]...`                | Alias for `wait_tcp` with port 5672.                                 | `wait_rabbitmq rabbit`                    |\n| `wait_redis \u003cHOST\u003e [PORT]...`                   | Alias for `wait_tcp` with port 6379.                                 | `wait_redis cache`                        |\n| `wait_multi_rabbitmq \u003cHOSTS\u003e [MIN] [PORT]`      | Alias for `wait_tcp_multi` with port 5672.                           | `wait_multi_rabbitmq rabbit1,rabbit2 1`   |\n| `wait_multi_redis \u003cHOSTS\u003e [MIN] [PORT]`         | Alias for `wait_tcp_multi` with port 6379.                           | `wait_multi_redis redis1,redis2 1`        |\n| `wait_multi_elasticsearch \u003cHOSTS\u003e [MIN] [PORT]` | Alias for `wait_tcp_multi` with port 9200.                           | `wait_multi_elasticsearch es1,es2 1`      |\n\n### File Handling\n\n| Function                              | Description                                            | Usage                                    |\n| ------------------------------------- | ------------------------------------------------------ | ---------------------------------------- |\n| `import_env \u003cFILE\u003e`                   | Sources an environment file and exports the variables. | `import_env /app/.env`                   |\n| `render_templates \u003cFILES...\u003e`         | Renders template files using `gomplate`.               | `render_templates /app/config.yaml.tmpl` |\n| `run_mountfile [MOUNTFILE] [DATADIR]` | Mounts directories based on a `Mountfile`.             | `run_mountfile`                          |\n\n### Miscellaneous\n\n| Function                  | Description                    | Usage                           |\n| ------------------------- | ------------------------------ | ------------------------------- |\n| `set_timezone [TIMEZONE]` | Sets the container's timezone. | `set_timezone America/New_York` |\n\n## Install\n\nThe main functions require `bash`, `curl` and `coreutils`. These take about 10M of space. The template function requires [gomplate](https://github.com/hairyhenderson/gomplate/).\n\n### Debian\n\n```Dockerfile\n# Install bash-container functions\nRUN set -x \\\n  \u0026\u0026 BASHCONTAINER_VERSION=0.8.0 \\\n  \u0026\u0026 BASHCONTAINER_SHA256=0ddc93b11fd8d6ac67f6aefbe4ba790550fc98444e051e461330f10371a877f1 \\\n  \u0026\u0026 if ! command -v wget \u003e /dev/null; then \\\n      fetchDeps=\"${fetchDeps} wget\"; \\\n     fi \\\n  \u0026\u0026 apt-get update \\\n  \u0026\u0026 apt-get install -y --no-install-recommends ca-certificates curl ${fetchDeps} \\\n  \u0026\u0026 cd /tmp \\\n  \u0026\u0026 wget -nv https://github.com/panubo/bash-container/releases/download/v${BASHCONTAINER_VERSION}/panubo-functions.tar.gz \\\n  \u0026\u0026 echo \"${BASHCONTAINER_SHA256}  panubo-functions.tar.gz\" \u003e /tmp/SHA256SUM \\\n  \u0026\u0026 ( cd /tmp; sha256sum -c SHA256SUM || ( echo \"Expected $(sha256sum panubo-functions.tar.gz)\"; exit 1; )) \\\n  \u0026\u0026 tar --no-same-owner -C / -zxf panubo-functions.tar.gz \\\n  \u0026\u0026 rm -rf /tmp/* \\\n  \u0026\u0026 apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${fetchDeps} \\\n  \u0026\u0026 apt-get clean \\\n  \u0026\u0026 rm -rf /var/lib/apt/lists/* \\\n  ;\n```\n\n### Alpine\n\n```Dockerfile\n# Install bash-container functions\nRUN set -x \\\n  \u0026\u0026 BASHCONTAINER_VERSION=0.8.0 \\\n  \u0026\u0026 BASHCONTAINER_SHA256=0ddc93b11fd8d6ac67f6aefbe4ba790550fc98444e051e461330f10371a877f1 \\\n  \u0026\u0026 if [ -n \"$(readlink /usr/bin/wget)\" ]; then \\\n      fetchDeps=\"${fetchDeps} wget\"; \\\n     fi \\\n  \u0026\u0026 apk add --no-cache ca-certificates bash curl coreutils ${fetchDeps} \\\n  \u0026\u0026 cd /tmp \\\n  \u0026\u0026 wget -nv https://github.com/panubo/bash-container/releases/download/v${BASHCONTAINER_VERSION}/panubo-functions.tar.gz \\\n  \u0026\u0026 echo \"${BASHCONTAINER_SHA256}  panubo-functions.tar.gz\" \u003e /tmp/SHA256SUM \\\n  \u0026\u0026 ( cd /tmp; sha256sum -c SHA256SUM || ( echo \"Expected $(sha256sum panubo-functions.tar.gz)\"; exit 1; )) \\\n  \u0026\u0026 tar --no-same-owner -C / -zxf panubo-functions.tar.gz \\\n  \u0026\u0026 rm -rf /tmp/* \\\n  \u0026\u0026 apk del ${fetchDeps} \\\n  ;\n```\n\n## Example Usage\n\nThe functions are used within a Docker entrypoint script to simplify container initialization and abstract entrypoints.\n\nThis example also uses a [Mountfile](https://github.com/voltgrid/voltgrid-pie/blob/master/docs/mountfile.md) and [Procfile](https://devcenter.heroku.com/articles/procfile#procfile-format).\n\n```shell\n#!/usr/bin/env bash\n\nset -e\n\nsource /panubo-functions.sh\n\n# Set the timezone\nset_timezone \"${TZ}\"\n\n# Wait for services to be available\nwait_postgres \"${DB_HOST}\" \"${DB_PORT:-5432}\"\nwait_redis \"${REDIS_HOST}\" \"${REDIS_PORT:-6379}\"\n\n# Render configuration templates\nrender_templates /etc/my.cnf.tmpl\n\n# Import environment variables from a file\nimport_env /app/.env\n\n# Mount data mounts (specifying an alternate mount point uid/gid)\nMOUNTFILE_MOUNT_UID=33\nMOUNTFILE_MOUNT_GID=33\nrun_mountfile\n\n# Exec Procfile command, or if not found in Procfile execute the command passed to the entrypoint\nexec_procfile \"${1}\" || exec \"$@\"\n```\n\nAlternate Procfile handling:\n\n```shell\n# Try to run a procfile command\nexec_procfile \"$1\"\n\n# exec_procfile returns 127 if the command isn't in the Procfile\nif [ \"$?\" -eq \"127\" ]; then\n\texec \"${@}\"\nfi\n```\n\n### Using gomplate templating\n\nAdd to your `Dockerfile`, to install gomplate (Debian example):\n\n```Dockerfile\n# Install gomplate\nRUN set -x \\\n  \u0026\u0026 GOMPLATE_VERSION=3.8.0 \\\n  \u0026\u0026 GOMPLATE_SHA256=847f7d9fc0dc74c33188c2b0d0e9e4ed9204f67c36da5aacbab324f8bfbf29c9 \\\n  \u0026\u0026 if ! command -v wget \u003e /dev/null; then \\\n      fetchDeps=\"${fetchDeps} wget\"; \\\n     fi \\\n  \u0026\u0026 apt-get update \\\n  \u0026\u0026 apt-get install -y --no-install-recommends ca-certificates ${fetchDeps} \\\n  \u0026\u0026 wget -nv -O /tmp/gomplate_linux-amd64-slim -L https://github.com/hairyhenderson/gomplate/releases/download/v${GOMPLATE_VERSION}/gomplate_linux-amd64-slim \\\n  \u0026\u0026 echo \"${GOMPLATE_SHA256}  gomplate_linux-amd64-slim\" \u003e /tmp/SHA256SUM \\\n  \u0026\u0026 ( cd /tmp; sha256sum -c SHA256SUM; ) \\\n  \u0026\u0026 mv /tmp/gomplate_linux-amd64-slim /usr/local/bin/gomplate \\\n  \u0026\u0026 chmod +x /usr/local/bin/gomplate \\\n  \u0026\u0026 rm -rf /tmp/* \\\n  \u0026\u0026 apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${fetchDeps} \\\n  \u0026\u0026 apt-get clean \\\n  \u0026\u0026 rm -rf /var/lib/apt/lists/* \\\n  ;\n```\n\nOr add to your `Dockerfile`, to install gomplate (Alpine example):\n\n```Dockerfile\n# Install gomplate\nRUN set -x \\\n  \u0026\u0026 GOMPLATE_VERSION=3.8.0 \\\n  \u0026\u0026 GOMPLATE_SHA256=847f7d9fc0dc74c33188c2b0d0e9e4ed9204f67c36da5aacbab324f8bfbf29c9 \\\n  \u0026\u0026 cd /tmp \\\n  \u0026\u0026 wget -nv https://github.com/hairyhenderson/gomplate/releases/download/v${GOMPLATE_VERSION}/gomplate_linux-amd64 \\\n  \u0026\u0026 echo \"${GOMPLATE_SHA256}  gomplate_linux-amd64\" \u003e /tmp/SHA256SUM \\\n  \u0026\u0026 ( cd /tmp; sha256sum -c SHA256SUM || ( echo \"Expected $(sha256sum gomplate_linux-amd64)\"; exit 1; )) \\\n  \u0026\u0026 chmod +x gomplate_linux-amd64 \\\n  \u0026\u0026 mv gomplate_linux-amd64 /usr/local/bin/gomplate \\\n  \u0026\u0026 rm -rf /tmp/* \\\n  ;\n```\n\nA minimal template (`/foo.conf.tmpl`):\n\n```\n# Template example\nFOO={{ getenv \"MYAPP_FOO\" \"default_foo_value\" }}\n```\n\nA minimal entrypoint script:\n\n```shell\n#!/usr/bin/env bash\n\nset -e\n\nsource /panubo-functions.sh\n\nrender_templates /foo.conf.tmpl\n```\n\nThis will render `/foo.conf.tmpl` to `/foo.conf`.\n\n## Bash Strict Mode\n\nAlthough we like [Unofficial Bash Strict Mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/) not all of these functions currently work under strict mode.\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n## Status\n\nStable and used in production.\n\n\u003c!-- BEGIN_BOTTOM_PANUBO --\u003e\n\u003e [!IMPORTANT]\n\u003e ## About Panubo\n\u003e\n\u003e This project is maintained by Panubo, a technology consultancy based in Sydney, Australia. We build reliable, scalable systems and help teams master the cloud-native ecosystem.\n\u003e\n\u003e We are available for hire to help with:\n\u003e\n\u003e * SRE \u0026 Operations: Improving system reliability and incident response.\n\u003e * Platform Engineering: Building internal developer platforms that scale.\n\u003e * Kubernetes: Cluster design, security auditing, and migrations.\n\u003e * DevOps: Streamlining CI/CD pipelines and developer experience.\n\u003e * [See our other services](https://panubo.com.au/services)\n\u003e\n\u003e Need a hand with your infrastructure? [Let’s have a chat](https://panubo.com.au/contact) or email us at team@panubo.com.\n\u003c!-- END_BOTTOM_PANUBO --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanubo%2Fbash-container","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpanubo%2Fbash-container","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanubo%2Fbash-container/lists"}