This is a simple OWIN web application that uses FROM scratch
in its Dockerfile
. The application packaging is an example of The Build Container pattern where container's build procedure is represented as a Two-Phase process:
- Prepare binary components from which application consists of (
Dockerfile.build
) - Build the runtime image by using previous step output (
Dockerfile
)
Run build-image.sh
and you'll see the described procees in a console.
alpine-mono-sdk
is a base image that produces application binaries. They are packed in a single file artifacts/runtime.tar
which represents the root filesystem in a runtime image.
This image in turn based on Alpine Linux one and have all needed dependencies to compile .NET application including Mono.
Mono is compiled from sources against musl
libc library. It also includes mkbundle
patch.
build.sh
's role is to restore dependencies and run FAKE script. Unfortunately, FAKE can not instantiate F# interpreter host, so temporary workaround for now just to feed fsi.exe
directly with build.fsx
. F# interpreter comes from FSharp.Compiler.Tools
package (I was unable to build F# from sources on Alpine image; perhaps 80K musl
's stack size is a showstopper).
MakeAppBundle
creates a single executable file which is under certain circumstances is the only file needed to run the application.
I intentionally introduced Mono.Posix
dependency to show how to deal with native dependencies.
It is possible to statically link
glibc
andlibgcc
— runtime dependencies — with bundle by playing withmkbundle
andgcc
command line arguments. It is important to note, that linking should be made with-Wl,-Bdynamic
anyway to allow CLR load assemblies even from bundle itself).
PackRuntime
archives application bundle with native Linux dependencies. As you can see, it includes Mono runtime deps, as well as Mono.Posix
specific (libMonoPosixHelper.so
and libz
). machine.config
could be included in bundle itself but to manage, for instance, machineKey
it is better to leave it outside of executable.
Under the hooks
directory you could find scripts that help to leverage Two-Phase build within Docker infrastructure.