Table of contents
- Getting started
- Install and Usage
- Syntax of Bockerfile
- Dockerfile vs. Bockerfile
- Bocker.sh script
- Important notes
- License. Author
Bocker makes your
The name is combined from
Dockerfile is a mix of shell commands, run-time settings and stuff.
It looks simple at first, but in a long run, you'll have some problems:
- Have to
pastecommon codes between
- No way to do some basic checks. For example, the
COPY /foo /barwill raise an error if
/foodoesn't exist; if that's the case, you have no way to tell
- It's hard to define and call a
RUNis one-line statement. Yes, you can try to do that with a mess of unreadable and un-maintainable codes;
- No way to include some useful parts from other
- No way to create the full
Dockerfileof an image and its ancestors.
This project is to solve these problems. It will read some
source files, and write new
STDOUT. The output
is cacheable, and can be executed by
docker build command.
A minimal example
Take a look at a quite minimal example in
To use this file, type the following commands
$ cd examples/ $ ../bocker.sh Bockerfile.alpine > Dockerfile.alpine
New contents are exactly a
Dockerfile for your build.
Overloading? Improve caching with
ship instead of
ADD / COPY commands?
See more from
or a collection of
Install and Usage
Bocker requires the popular tools:
- On local machine where you run
- On base image:
base64 is a basic tool from
There is only one
bocker.sh. Put this script in
one of your binary directories, and start it with
$ bocker.sh MyBockerfile >/dev/null # to see if there is any error $ bocker.sh MyBockerfile # to see Dockerfile output
The output is written to
STDOUT. You should check if there is anything
Bocker is unable to check if your source
file has problem.
Command line options
--version): Print the script version;
--test): Check if there is any problem with input.
Bash source files. That means you can write
your source in some small files, and include them in other files.
The first rule is that every method is started with
There are some basic methods to define your meta information. For your overview, let's see:
ed_from YOUR_BASE_IMAGE ed_maintainer "YOUR INFORMATION" ed_env FOO /bar/ ed_expose 80 ed_volume /example.net/ ed_cmd '["/supervisor.sh", "foo", "bar"]' ed_ship foobar ....
EXPOSE. They are:
ed_from: Define your
ed_maintainer: Define your
ed_env: Define new
--lateroption if your environment is only needed at the run-time;
ed_expose: Specify a list of exposed ports;
ed_volume: Specify a list of volumes;
ed_onbuild: Specify trigger on the descendant image build;
ed_cmd: Define your
ed_user: Define your
USERstatement; Must use with
ed_copy: Define your
COPYstatement; If you want to have
--addoption. Must use with the option
ed_entrypoint: Define your
ed_ship: Define a list of methods to be shipped to the image; That means, you can define a function
ed_foobar, and call
ed_ship ed_foobarto make this function available to
Dockerat build time and run time. Actually, functions' definitions are written to the file
/bocker.shin the result image, and that will be included at every
ed_ship --later: Like
ed_ship, but the contents are shipped at the very end of
Dockerfile. This is very useful when the functions are only needed at the run-time, because that really speeds up your build process. See example in
ed_reuse: Load the
Bockerfile(s) specified in argument, and re-use
ed_dockerfrom that source if any. All
ed_dockerdefinitions are additive in order provided.
All these commands can be used multiple times, and/or be put in
your base libraries. (See
The last statement of
will win; other functions have additive effect.
You can define your set of methods as
Bash functions, each of them
has a name started by
ed_. For example, in
you will see
ed_apt_clean that removes unused
apt-get variable data
to minimize the size of your result image.
This is a must-have function.
Bocker will raise error if you
don't define it.
This function should not contain any function from
It can have some special functions
ed_copy: Define your
ed_add: Define your
ed_user: Define your
ed_workdir: Define your
ed_run: Define your
ed_group: Group multiple methods into a single
Bocker will read the contents of this
replace every appearance of
That means, if you type
Bocker will invoke
__ed_ship_method ed_apt_clean for you.
Because this is actually a replace-execute trick,
it's your duty to make your definition of
ed_bocker as simple
as possible. Don't use complex stuff like expansion and (
If you have to do that, put your stuff under some functions,
ship them to the image with
ed_ship, and that's just enough.
Dockerfile vs. Bockerfile
Dockerfilestatements are ordered. First declared first run. In
Bockerfile, most stuff in
Dockerfilesupports array form of
Bockerfiledoesn't. This way helps
Bockerfileto glue declarations from multiple library files into a single statement;
- To group
Dockerfile, you have to use
RUNfrom the later statements. In
Bockerfile, you simply use
ed_group. See this example;
- To declare a
Bashfunction and use them in every
RUNstatement, you may put that definition in a file, use
COPYto transfer the file to the container and load it, e.g,
RUN source /mylib.sh; ...; You can love this way or not. In
Bockerfile, you simply use
ed_shipfor build-time methods, and
ed_ship --laterfor run-time methods with a minimum number of layers.
Here is a table for quick reference.
|Base script||ed_source, sourc|
|Build command||ADD||ed_copy --add --later||ed_add|
|Build command||COPY||ed_copy --later||ed_copy|
|Build command||USER||ed_user --later||ed_user|
|Declare method||N/A||ed_ship [--later]|
|Label||LABEL||TODO||echo "LABEL foo=bar"|
|Raw statement||secho "# Something"|
The result image has
/bocker.sh script that contains (almost) all
When you use
ed_ship or invoke some command inside your
your function definitions are saved originally (except the comments,
of course) to the
/bocker.sh script in the result image.
This script only contains functions, and if you provide any arguments to it, they are considered as command in the environment where your functions are defined. For example
# ed_ship --later my_method /bocker.sh ed_my_method # /bocker.sh find
find command) that you have shipped.
Because of this, you can simply define a
start-up function, and
/bocker.sh to call them. That exactly means,
be used as your
ed_bockeris executed locally at run time, on your local machine. This is dangerous. Please don't add too much codes inside
ed_bocker. That function should only contain
-xeuset by default; That means any error will stop. If you want to have something else, you can always do that in you
When the project is started, its name is
EDocker, that's why you see
EDocker isn't a good name, hence you see
This work is released the terms of
The author is Anh K. Huynh.