EPICS Base Image
EPICS is the Experimental Physics and Industrial Control System.
This image contains source and build of "EPICS base" version R18.104.22.168, the core EPICS software.
The purpose of this image is to provide a bare-bones, minimalistic EPICS base for other images to build upon.
This image itself is based on Alpine, to minimize image size and overhead.
||EPICS base source and build|
||Sets up environment variables for serving EPICS CA (link)|
||Minimalistic init system, which is described in a section below.|
This image is intended to be used as a base image. To to extend it, create a new Dockerfile and reference it using the
To make use of the provided init system, you should keep the provided
ENTRYPOINT or ensure you use
/init.sh as the first field when defining your own
We recommend setting up any required environment variables by providing an
/etc/profile.d/*.sh script and following the
XY-some-name.sh naming convention, where
XY is a two-digit number. Since the scripts are sourced in alphabetical order, that number can be used to control execution order.
FROM dmscid/epics-base:latest RUN apk --no-cache add python COPY 10-setup-environment.sh /etc/profile.d/10-setup-environment.sh ENTRYPOINT ["/init.sh", "python"]
This will create an image that drops straight into a python shell, with the environment already set up by sourcing
/etc/profile.d/10-setup-environment.sh in that order.
For a real-world example, see dmscid/epics-gateway.
Docker containers lack an init or supervisor system by default. This leads to issues with rampant root zombie processes and signals sent to the container not being passed through as expected.
ENVdirective in Dockerfiles does not currently support variable values
~/.profilewill not be sourced unless you explictly start a login shell
~/.bashrcwill not be sourced unless you run
bashin interactive but not login mode
... it can be tricky to reliably ensure environment variables are correctly set up with values that must be determined at runtime (such as a variable IP or hostname).
To resolve these issues, this image provides a combination of tini and an
/init.sh script. Tini is a tiny init system that solves the zombie and signal issues. The
init.sh script sources
/etc/profile and ensures tini is launched correctly. This script is used as the
ENTRYPOINT of this image, and derived images are encouraged to follow suit.
The script has the following usage:
. /init.sh [command [arguments]]
This will do the following:
sourced to set up the environment (which in turn
[command]is run with
[arguments], via tini (
/sbin/tini -s -g)
- If no command was provided,
/bin/shis used as a default
- Assuming the script is run as the
CMD, or by a shell that is PID 1, tini will have PID 1 so that it will receive any signals the container receives from the host
- tini will reap child processes so they don't turn into zombies and forward any signals it receives to all child processes
The init script (or any
ENTRYPOINT) may be circumvented using the
--entrypoint argument of
docker run. When running a container like that, you can switch to "init mode" by sourcing
$ docker run -it --entrypoint sh dmscid/epics-base / # ps aux PID USER TIME COMMAND 1 root 0:00 sh 7 root 0:00 ps aux / # . /init.sh ac28333e09e1:/# ps aux PID USER TIME COMMAND 1 root 0:00 /sbin/tini -s -g -- /bin/sh 11 root 0:00 /bin/sh 12 root 0:00 ps aux ac28333e09e1:/# exit $
/sbin/tini has replaced
sh as the PID 1 process, and you are now in a new shell (which defaulted to
/bin/sh because no parameters were passed to
/init.sh). Nevertheless, a single
exit shuts down the container since the old shell is gone and tini shuts down when its child process does.