Swift@IBM Logo

We are excited to announce that in addition to the Docker image for Swift development that we released over a year ago, ibmcom/swift-ubuntu, we have recently made available an additional Docker image for Swift enthusiasts, ibmcom/swift-ubuntu-runtime. This new image is much smaller in size than the ibmcom/swift-ubuntu image and is tailored for provisioning your Swift applications to cloud environments, such as IBM Cloud. By not including in the ibmcom/swift-ubuntu-runtime image any of the build tools (e.g. SwiftPM, clang, etc.) that are required for compiling, linking and testing your Swift applications, we were able to create an image with a size of roughly 300 MB. The ibmcom/swift-ubuntu-runtime image contains only those shared objects (.so files) from the Swift binaries that are required for executing your Swift applications. Therefore, this Docker image is not suited for application development, testing, or debugging but exclusively for running Swift applications.

We can take the ibmcom/swift-ubuntu-runtime image for a test drive by extending it, adding the code for the Kitura-Starter application (an IBM Cloud starter application for the Kitura web framework and HTTP server), and running this sample application in a Docker container. Let’s start by cloning the Kitura-Starter application:

$ git clone https://github.com/IBM-Bluemix/Kitura-Starter
Cloning into 'Kitura-Starter'...
remote: Counting objects: 639, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 639 (delta 4), reused 0 (delta 0), pack-reused 622
Receiving objects: 100% (639/639), 116.52 KiB | 0 bytes/s, done.
Resolving deltas: 100% (340/340), done.

After cloning Kitura-Starter, let’s create a backup of the Dockerfile found in your local repository of the Kitura-Starter sample application (i.e. rename it to Dockerfile.original):

$ mv Dockerfile Dockerfile.original
$ ls -la
total 128
drwxr-xr-x  17 olivieri  staff    578 Feb 13 13:20 .
drwxr-xr-x  16 olivieri  staff    544 Feb 13 13:17 ..
-rw-r--r--   1 olivieri  staff    189 Feb 13 13:17 .cfignore
drwxr-xr-x  13 olivieri  staff    442 Feb 13 13:17 .git
-rw-r--r--   1 olivieri  staff    139 Feb 13 13:17 .gitignore
-rw-r--r--   1 olivieri  staff      0 Feb 13 13:17 .gitmodules
-rw-r--r--   1 olivieri  staff      6 Feb 13 13:17 .swift-version
-rw-r--r--   1 olivieri  staff   1561 Feb 13 13:17 .travis.yml
-rw-r--r--   1 olivieri  staff   1287 Feb 13 13:17 Dockerfile.original
-rw-r--r--   1 olivieri  staff  11324 Feb 13 13:17 LICENSE
-rw-r--r--   1 olivieri  staff   1200 Feb 13 13:17 Package.swift
-rw-r--r--   1 olivieri  staff  18179 Feb 13 13:17 README.md
drwxr-xr-x   3 olivieri  staff    102 Feb 13 13:17 Sources
drwxr-xr-x   3 olivieri  staff    102 Feb 13 13:17 ci
-rw-r--r--   1 olivieri  staff    217 Feb 13 13:17 docker-compose.yml
-rw-r--r--   1 olivieri  staff    163 Feb 13 13:17 manifest.yml
drwxr-xr-x   6 olivieri  staff    204 Feb 13 13:17 public

Let’s now compile the Kitura-Starter application. However, executing swift build directly on your macOS won’t be quite useful. Instead, we need to compile the application on a system that runs Ubuntu 14.04. If you are wondering how you can do this, that’s what our development image for Swift (ibmcom/swift-ubuntu) is for! Make sure you have the latest version of this image on your local system:

$ docker pull ibmcom/swift-ubuntu:latest
latest: Pulling from ibmcom/swift-ubuntu
c60055a51d74: Already exists 
755da0cdb7d2: Already exists 
969d017f67e6: Already exists 
37c9a9113595: Already exists 
a3d9f8479786: Already exists 
33d721a2c9ee: Pull complete 
218060c9f1e9: Pull complete 
7baf37364ea1: Pull complete 
174817f7b6e2: Pull complete 
89c45f744f23: Pull complete 
Digest: sha256:b4c38381c7be4a6d80092ed099b4d9419e65a865225c6fe994fd7d80ca1dea32
Status: Downloaded newer image for ibmcom/swift-ubuntu:latest

With the latest version of the ibmcom/swift-ubuntu image available on your local development system, you can create a new Docker container, mount the folder that contains the Kitura-Starter repository, and compile the sample application in release mode (i.e. swift build --configuration release) instead of debug mode:

$ docker run -i -t -v /Users/olivieri/git/Kitura-Starter/:/Kitura-Starter ibmcom/swift-ubuntu:latest
root@c528db75744e:~# cd Kitura-Starter/
root@c528db75744e:~/Kitura-Starter# swift package clean
root@c528db75744e:~/Kitura-Starter# swift build --configuration release
Compile CHTTPParser utils.c
Compile CHTTPParser http_parser.c
Compile Swift Module 'Signals' (1 sources)
Compile Swift Module 'Socket' (3 sources)
Compile Swift Module 'LoggerAPI' (1 sources)
Compile Swift Module 'KituraTemplateEngine' (1 sources)
Compile Swift Module 'KituraContracts' (2 sources)
Compile Swift Module 'HeliumLogger' (2 sources)
Compile Swift Module 'Health' (3 sources)
Compile Swift Module 'Configuration' (6 sources)
Compile Swift Module 'SSLService' (1 sources)
Compile Swift Module 'CloudFoundryEnv' (6 sources)
Compile Swift Module 'CloudFoundryDeploymentTracker' (1 sources)
Compile Swift Module 'CloudEnvironment' (16 sources)
Compile Swift Module 'KituraNet' (36 sources)
Compile Swift Module 'Kitura' (45 sources)
Compile Swift Module 'Controller' (1 sources)
Compile Swift Module 'Kitura_Starter' (1 sources)
Linking ./.build/x86_64-unknown-linux/release/Kitura-Starter
root@c528db75744e:~/Kitura-Starter# 

When you compile a Swift application in release mode, the binary generated is optimized for a production deployment and debugging information is not included in the binaries. For further details on how to use the ibmcom/swift-ubuntu for developing server side Swift projects, we invite you to checkout the README file of our GitHub repository for our Docker images.

Once the Kitura-Starter code is compiled, let’s create a new Dockerfile with the contents shown below:

# Builds a Docker image for running the Kitura-Starter sample application.

FROM ibmcom/swift-ubuntu-runtime:latest
MAINTAINER IBM Swift Engineering at IBM Cloud
LABEL Description="Docker image for running the Kitura-Starter sample application."

USER root

# Expose default port for Kitura
EXPOSE 8080

# Binaries should have been compiled against the correct platform (i.e. Ubuntu 14.04).
COPY .build/x86_64-unknown-linux/release/Kitura-Starter /Kitura-Starter/.build/release/Kitura-Starter
COPY public /Kitura-Starter/public
CMD [ "sh", "-c", "cd /Kitura-Starter && .build/release/Kitura-Starter" ]

The above Dockerfile extends the new ibmcom/swift-ubuntu-runtime image, exposes port 8080, and adds the necessary project files (i.e. public folder) and generated binaries for the Kitura-Starter application. You should know that the public folder contains static HTML content that is served by the sample server. Therefore, we include this folder along with the generated binaries in the new Docker image. We can now create a runtime image (kitura-starter-runner) using the new Dockerfile by executing the following command in the root folder of the Kitura-Starter repo:

$ docker build -t kitura-starter-runner:latest .
Sending build context to Docker daemon  116.1MB
Step 1/8 : FROM ibmcom/swift-ubuntu-runtime:latest
 ---> 706735b21a94
Step 2/8 : MAINTAINER IBM Swift Engineering at IBM Cloud
 ---> Using cache
 ---> 543338eaf02c
Step 3/8 : LABEL Description "Docker image for running the Kitura-Starter sample application."
 ---> Using cache
 ---> f377b5d47b88
Step 4/8 : USER root
 ---> Using cache
 ---> 8fbaa6d8d162
Step 5/8 : EXPOSE 8080
 ---> Using cache
 ---> fb80aec334bd
Step 6/8 : COPY .build/x86_64-unknown-linux/release/Kitura-Starter /Kitura-Starter/.build/release/Kitura-Starter
 ---> Using cache
 ---> 22e13b53f474
Step 7/8 : COPY public /Kitura-Starter/public
 ---> 5491f2c2b5c4
Step 8/8 : CMD sh -c cd /Kitura-Starter && .build/release/Kitura-Starter
 ---> Running in 37fab4832a33
 ---> 6a673c599f19
Removing intermediate container 37fab4832a33
Successfully built 6a673c599f19
Successfully tagged kitura-starter-runner:latest

Now that we have a new image, kitura-starter-runner, that extends the ibmcom/swift-ubuntu-runtime image and contains the binaries for the Kitura-Starter application, let’s create a new container to execute the sample application.

$ docker run -p 8080:8080 -i -t kitura-starter-runner:latest
...
[2017-11-06T17:09:37.039Z] [INFO] [main.swift:28 Kitura_Starter] Server will be started on 'http://localhost:8080'.
[2017-11-06T17:09:37.040Z] [INFO] [HTTPServer.swift:124 listen(on:)] Listening on port 8080

Once the application is running in the Docker container, you can access it by pointing your browser to http://localost:8080:

Kitura-Starter welcome page

You have now successfully used the new runtime image for Swift, ibmcom/swift-ubuntu-runtime, to execute a Swift application inside a Docker container! You can use this new runtime image for running and making your applications available to your customers on the IBM Cloud. For details on how to publish your Swift applications using containers, feel free to check out 10 Steps To Running a Swift App in an IBM Container.

For more information on server-side Swift, visit the Swift@IBM Developer Center.

Ricardo Olivieri, Senior Software Engineer, IBM Swift Engineering at IBM Cloud

4 comments on"New Runtime Docker Image for Swift Applications"

  1. When I run:

    docker run -i -t -v /Users/olivieri/git/Kitura-Starter/:/root/Kitura-Starter ibmcom/swift-ubuntu:latest

    modified for my situation:

    docker run -i -t -v /Users/chris/Desktop/Kitura-Starter/:/root/Kitura-Starter ibmcom/swift-ubuntu:latest

    there is no directory Kitura-Starter. i.e., after running the above docker run command, and doing an ls, I have:

    bin dev home lib64 mnt proc run srv tmp var
    boot etc lib media opt root sbin sys usr

  2. I think I see the problem now. I had to do cd root/Kitura-Starter/ :).

  3. Thanks for this. I’ve got it working now. Two more thoughts:

    1) When I run it swift build --clean gives an error.
    error: unknown option –clean; use –help to list available options
    Was –clean removed as an option?

    2) In the Dockerfile, I had to comment out:
    COPY .build/release/*.so /root/Kitura-Starter/.build/release/
    there are no .so’s. I assume that in some cases the swift build will generate these, but just doesn’t in this case.

    • Ricardo Olivieri November 06, 2017

      Thanks Christopher for your comments/questions above. This blog post was originally published many months ago and a few things got outdated and, hence, the issues you ran into. I just went ahead and updated the contents of the blog so they are compatible now with the latest docker images and Swift 4. If you run into any other issues, please let us know.

Leave a Reply