{"id":13415845,"url":"https://github.com/icy/bocker","last_synced_at":"2025-03-14T23:31:08.615Z","repository":{"id":32156847,"uuid":"35729935","full_name":"icy/bocker","owner":"icy","description":"Write Dockerfile completely in Bash/Bourne. Extensible and simple.","archived":true,"fork":false,"pushed_at":"2019-12-09T09:12:56.000Z","size":85,"stargazers_count":140,"open_issues_count":8,"forks_count":13,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-07-31T21:54:43.151Z","etag":null,"topics":["bash","bourne","dockerfile","dry","shell"],"latest_commit_sha":null,"homepage":"https://github.com/icy/bocker","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-16T15:55:57.000Z","updated_at":"2024-06-17T03:13:56.000Z","dependencies_parsed_at":"2022-09-03T04:31:47.073Z","dependency_job_id":null,"html_url":"https://github.com/icy/bocker","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icy%2Fbocker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icy%2Fbocker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icy%2Fbocker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icy%2Fbocker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icy","download_url":"https://codeload.github.com/icy/bocker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243663456,"owners_count":20327299,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","bourne","dockerfile","dry","shell"],"created_at":"2024-07-30T21:00:52.504Z","updated_at":"2025-03-14T23:31:07.991Z","avatar_url":"https://github.com/icy.png","language":"Shell","readme":"*WARNING*: I haven't had time to maintain this project. Use them at your own risk. Thank you for your understanding.\n\n## Table of contents\n\n* [Description](#description)\n* [Getting started](#getting-started)\n  * [A minimal example](#a-minimal-example)\n  * [More examples](#more-examples)\n* [Install and Usage](#install-and-usage)\n* [Syntax of Bockerfile](#syntax-of-bockerfile)\n  * [Front matter](#front-matter)\n  * [Main matter](#main-matter)\n  * [Main function ed_bocker](#main-function-ed_bocker)\n* [Dockerfile vs. Bockerfile](#dockerfile-vs-bockerfile)\n* [Bocker.sh script](#bockersh-script)\n* [Important notes](#important-notes)\n* [History](#history)\n* [License. Author](#license-author)\n\n## Description\n\n`Bocker` makes your `Dockerfile` reusable.\nThe name is combined from `B(ash)` and `(D)ocker`.\n\n`Dockerfile` is a mix of shell commands, run-time settings and stuff.\nIt looks simple at first, but in a long run, you'll have some problems:\n\n* Have to `copy` and `paste` common codes between `Dockerfile`s;\n  (Examples: `FROM`, `MAINTAINER`, `ENV`,...);\n* No way to do some basic checks. For example, the `COPY /foo /bar`\n  will raise an error if `/foo` doesn't exist; if that's the case,\n  you have no way to tell `COPY` to continue;\n* It's hard to define and call a `sub-routine` in `RUN` statement,\n  because `RUN` is one-line statement. Yes, you can try to do that\n  with a mess of unreadable and un-maintainable codes;\n* No way to include some useful parts from other `Dockerfile`;\n* No way to create the full `Dockerfile` of an image and its ancestors.\n\nThis project is to solve these problems. It will read some `Bash`\nsource files, and write new `Dockerfile` to `STDOUT`. The output\nis cacheable, and can be executed by `docker build` command.\n\n## Getting started\n\n### A minimal example\n\nTake a look at a quite minimal example in `examples/Bockerfile.alpine`.\n\n```\n#!/usr/bin/env bash\n\n# The default Alpine shell /bin/sh\n\ned_shell  /bin/sh\ned_from   alpine:3.8\ned_env    --later Hello World\n\ned_bocker() {\n  :\n}\n```\n\nTo use this file, type the following commands\n\n````\n$ cd examples/\n$ ../bocker.sh Bockerfile.alpine \u003e Dockerfile.alpine\n````\n\nNew contents are exactly a `Dockerfile` for your build.\n\n### More examples\n\nOverloading? Improve caching with `--later`?\nUse `ship` instead of `ADD / COPY` commands?\n\nSee more from `examples/README.md` at\n  https://github.com/icy/bocker/blob/master/examples/README.md\nor a collection of `Bockerfile` at\n  https://github.com/icy/docker/tree/master/bocker.\n\n## Install and Usage\n\n### Requirements\n\n`Bocker` requires the popular tools:\n\n* On local machine where you run `bocker` script:\n    `Bash`, `base64`, `grep`, `sed`, `gawk`;\n* On base image:\n    `bash` or `sh`, `base64`.\n\n`base64` is a basic tool from `coreutils` package.\n\n### Installation\n\nThere is only one `Bash` script `bocker.sh`. Put this script in\none of your binary directories, and start it with `Bockerfile`\n\n````\n$ bocker.sh MyBockerfile \u003e/dev/null # to see if there is any error\n$ bocker.sh MyBockerfile            # to see Dockerfile output\n````\n\nThe output is written to `STDOUT`. You should check if there is anything\nwrong from `STDERR`, because `Bocker` is unable to check if your source\nfile has problem.\n\n### Command line options\n\n* `-v` (`--version`): Print the script version;\n* `-t` (`--test`): Check if there is any problem with input.\n\n## Syntax of `Bockerfile`\n\nAll `Bockerfile`s are `Bash` source files. That means you can write\nyour source in some small files, and include them in other files.\n\nThe first rule is that every method is started with `ed_`.\n\n### Front matter\n\nThere are some basic methods to define your meta information.\nFor your overview, let's see:\n\n````\ned_from        YOUR_BASE_IMAGE\ned_maintainer  \"YOUR INFORMATION\"\n\ned_env         FOO /bar/\ned_expose      80\ned_volume      /example.net/\ned_cmd         '[\"/supervisor.sh\", \"foo\", \"bar\"]'\ned_ship        foobar\n....\n````\n\nThink of `FROM`, `MAINTAINER`, `EXPOSE`. They are:\n\n* `ed_from`: Define your `FROM` information;\n* `ed_maintainer`: Define your `MAINTAINER` information;\n* `ed_env`: Define new `ENV` instruction; Use `--later` option if\n   your environment is only needed at the run-time;\n* `ed_expose`: Specify a list of exposed ports;\n* `ed_volume`: Specify a list of volumes;\n* `ed_onbuild`: Specify trigger on the descendant image build;\n* `ed_cmd`: Define your `CMD` statement;\n* `ed_user`: Define your `USER` statement; Must use with `--later` option;\n* `ed_copy`: Define your `COPY` statement; If you want to have `ADD`,\n    use `--add` option. Must use with the option `--later`;\n* `ed_entrypoint`: Define your `ENTRYPOINT` statement;\n* `ed_ship`: Define a list of methods to be shipped to the image;\n  That means, you can define a function `ed_foobar`, and call `ed_ship ed_foobar`\n  to make this function available to `Docker` at build time and run time.\n  Actually, functions' definitions are written to the file `/bocker.sh`\n  in the result image, and that will be included at every `RUN`;\n* `ed_ship --later`: Like `ed_ship`, but the contents are shipped at\n  the very end of `Dockerfile`. This is very useful when the functions\n  are only needed at the run-time, because that really speeds up\n  your build process. See example in `examples/lib/debian.sh`.)\n* `ed_reuse`: Load the `Bockerfile`(s) specified in argument,\n  and re-use `ed_docker` from that source if any.\n  All `ed_docker` definitions are additive in order provided.\n\nAll these commands can be used multiple times, and/or be put in\nyour base libraries. (See `examples/lib/core.sh`.)\n\nThe last statement of `ed_from` (`ed_maintainer`, `ed_cmd`, `ed_entrypoint`)\nwill win; other functions have additive effect.\n\n### Main matter\n\nYou can define your set of methods as `Bash` functions, each of them\nhas a name started by `ed_`. For example, in `examples/lib/debian.sh`,\nyou will see `ed_apt_clean` that removes unused `apt-get` variable data\nto minimize the size of your result image.\n\n### Main function: `ed_bocker`\n\nThis is a must-have function. `Bocker` will raise error if you\ndon't define it.\n\nThis function should not contain any function from `PREAMBLE` section.\n\nIt can have some special functions\n\n* `ed_copy`: Define your `COPY` statement;\n* `ed_add`: Define your `ADD` statement;\n* `ed_user`: Define your `USER` statement;\n* `ed_workdir`: Define your `WORKDIR` statement;\n* `ed_run`: Define your `RUN` statement;\n* `ed_group`: Group multiple methods into a single `RUN` statement.\n\n`Bocker` will read the contents of this `ed_bocker` function,\nreplace every appearance of `ed_*` by `__ed_ship_method ed_*`.\nThat means, if you type `ed_apt_clean`, `Bocker` will invoke\n`__ed_ship_method ed_apt_clean` for you.\n\nBecause this is actually a replace-execute trick,\nit's your duty to make your definition of `ed_bocker` as simple\nas possible. Don't use complex stuff like expansion and (`WHO KNOWS`?)\nIf you have to do that, put your stuff under some functions,\nship them to the image with `ed_ship`, and that's just enough.\n\n## Dockerfile vs. Bockerfile\n\nFacts\n\n* `Dockerfile` statements are ordered. First declared first run.\n  In `Bockerfile`, most stuff in `PREAMBLE` are un-ordered;\n* `Dockerfile` supports array form of `ENV`, `EXPOSE`, `VOLUME`;\n  but `Bockerfile` doesn't. This way helps `Bockerfile` to glue\n  declarations from multiple library files into a single statement;\n* To group `RUN` commands in `Dockerfile`, you have to use `\u0026\u0026` and\n  remove `RUN` from the later statements. In `Bockerfile`, you simply\n  use `ed_group`. See [this example][Bockerfile.nginx];\n* To declare a `Bash` function and use them in every `RUN` statement,\n  you may put that definition in a file, use `COPY` to transfer the file\n  to the container and load it, e.g, `RUN source /mylib.sh; ...`;\n  You can love this way or not. In `Bockerfile`, you simply use `ed_ship`\n  for build-time methods, and `ed_ship --later` for run-time methods\n  with a minimum number of layers.\n\nHere is a table for quick reference.\n\nPurpose       | Dockerfile | Bockerfile (Preamble) | `ed_bocker`\n:--           | :--        | :--                   | :--\nBase image    | FROM       | ed_from               |\nBase script   |            | ed_reuse              |\nBase script   |            | ed_source, source     |\nMaintainer    | MAINTAINER | ed_maintainer         |\nVolume expose | VOLUME     | ed_volume             |\nPort expose   | EXPOSE     | ed_expose             |\nInit script   | ENTRYPOINT | ed_entrypoint         |\nInit command  | CMD        | ed_cmd                |\nInt command   | ONBUILD    | ed_onbuild            |\nVariable      | ENV        | ed_env [--later]      |\nBuild command | RUN        | `ed_bocker`           | `ed_foo`, ed_run\nBuild command | ADD        | ed_copy --add --later | ed_add\nBuild command | COPY       | ed_copy --later       | ed_copy\nBuild command | USER       | ed_user --later       | ed_user\nBuild command | WORKDIR    | TODO                  | ed_workdir\nDeclare method| N/A        | ed_ship [--later]     |\nGrouping      | \u0026\u0026         |                       | ed_group\nLabel         | LABEL      | ed_label              | echo \"LABEL foo=bar\"\nRaw statement |            |                       | echo \"# Something\"\n\n## `/bocker.sh` script\n\nThe result image has `/bocker.sh` script that contains (almost) all\nyour functions.\n\nWhen you use `ed_ship` or invoke some command inside your `ed_bocker`,\nyour function definitions are saved originally _(except the comments,\nof course)_ to the `/bocker.sh` script in the result image.\n\nThis script only contains functions, and if you provide any arguments\nto it, they are considered as command in the environment where your\nfunctions are defined. For example\n\n    # ed_ship --later my_method\n    /bocker.sh ed_my_method\n    # /bocker.sh find\n\nwill invoke `ed_my_method` (or `find` command) that you have shipped.\n\nBecause of this, you can simply define a `start-up` function, and\nuse `/bocker.sh` to call them. That exactly means, `bocker.sh` can\nbe used as your `ENTRYPOINT`.\n\n## Important notes\n\n* `ed_bocker` is executed locally at run time, on your local machine.\n  This is dangerous. Please don't add too much codes inside `ed_bocker`.\n  That function should only contain `ed_*` methods.\n* Any `RUN` generated by `Bocker` has option `-xeu` set by default;\n  That means any error will stop. If you want to have something else,\n  you can always do that in you `ed_*` definition.\n\n## History\n\nWhen the project is started, its name is `EDocker`, that's why you see\n`ed_` prefixes. `EDocker` isn't a good name, hence you see `Bocker` now.\n\n## License. Author\n\nThis work is released the terms of `MIT` license.\nThe author is Anh K. Huynh.\n\n[Bockerfile.nginx]: https://github.com/icy/docker/blob/master/bocker/Bockerfile.nginx\n","funding_links":[],"categories":["Container Operations","HarmonyOS","Dev Tools"],"sub_categories":["Container Composition","Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficy%2Fbocker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficy%2Fbocker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficy%2Fbocker/lists"}