Openshift’s S2i (Source-2-image) is a pretty cool replacement to buildpacks using Dockerfiles and Openshift
The goal is to be able to create a container image that contains the necessary application dependencies just by uploading the application code without having to write Dockerfiles.
Creating S2i builder images
S2i builder images are the base images that your deploying application will be injected its code/binary into to create a new deployment image.
An easy way to think about S2i builder images is that it is analogous to Buildpacks in which they set the environment for applications.
S2i builder images have the following directory structure:
/ /s2i/ /s2i/assemble /s2i/usage /s2i/run Dockerfile
Key details to note is that when you create a new build that uses an s2i builder image as its base layer, your source code will be injected into
/tmp/src of the builder image. You will need to keep this in mind when you write your
S2i Builder Image Default Files
This is a bash script that contains instructions that will be run right after your deploying app source code is injected into
/tmp/src of the S2i builder image.
#!/bin/sh set -ex echo "---> Preparing source..." mkdir -p /tmp/myapp cp -Rf /tmp/src/src/. /tmp/myapp
This script is run when the builder image is run w/o any additional commands. Its sole responsibility is to print out the usage of the builder image in text form.
This script is run during runtime when the derived application image runs. Should contain the actual running of a long-lived process.
#!/bin/sh set -e echo "Running myapp..." cat /tmp/myapp/* echo Sleeping... while true; do sleep 1; echo -n .;done
S2i Builder Image Dockerfile
A typical Dockerfile should contain at minimum the following steps:
# This image creates a very simple s2i builder image # We are basing our builder image on openshift base-centos7 image FROM openshift/base-centos7 # Set labels used in OpenShift to describe the builder images LABEL io.k8s.description="simple s2i builder example" \ io.k8s.display-name="simple s2i builder example" \ io.openshift.s2i.scripts-url="image:///usr/libexec/s2i" \ io.openshift.tags="builder" # Copy the example S2I scripts to the expected location COPY ./s2i/ /usr/libexec/s2i # Set the default user for the image USER 1001 # Set the default CMD to print the usage of the image, if somebody does docker run CMD /usr/libexec/s2i/usage
io.openshift.s2iannotations can provide you with more configurable settings to help you with your s2i image creation. For example, you can use
io.openshift.s2i.destination="/path/where/appcode/is/injected". If not your application code will be injected into
/tmp/srcof the base image.
To quickly generate the necessary files to get your S2i builder image started (including the above directory structure), you can actually cheap by using the
s2i cli. You can grab it at http://github.com/openshift/source-to-image
$ s2i create <image name> <relative path to name of directory to use to contain the files>
Deploying your Builder Image onto Openshift
oc new-build --name <name of builder image> --binary=true # Create the build configuration (using Docker build strategy) oc start-build <name of builder image> --from-dir=. # Start the build, using the current directory oc logs bc/<name of builder image> -f # Check the build output for errors
When this is complete, this creates an image called
<name of builder image> into Openshift which you can then use as the source base image.
Deploying your App onto Openshift
Now that you have your app, all you really need is to send an instruction to have your app baked into your builder image and return an output image which youc an then use to deploy.
In the directory of your app source code, create a new
build configuration. Like the steps above,
oc new build creates a build instruction to tell what is the expected output image.
$ oc new-build --binary=true -i <name of builder image> --name <name of output image/appname>
binary=true just instructs Openshift to expect the incoming files to be from a tarball/raw files
At this stage, you should have a working build configuration. Now let’s start to build an output image. The following command will push all the files in the current directory up start a build.
# make sure you're in your app source code directory $ oc start-build <name of output image/appname> --from-dir=. $ oc logs bc/<name of output image> -f
After this is completed, just do an
oc new-app <name of output image/appname> and your app is deployed!
Bonus: If you want your application to overwrite any of the
assemble/run/usagescripts in your builder image, you can add them in
application root. The S2i process will find these file and inject them into the builder image during build time.