“Slim” Docker images for Swift

Ian Partridge
3 min readJul 20, 2019

--

Swift has had official Docker images for a number of years, aiming to provide a useful development environment for Swift programs, based on Ubuntu. You can docker run -it swift:latest and drop into a Bash shell with the Swift compiler all set up and waiting for you.

Now with the release of the Swift 5.0.2 Docker images, there are new “slim” images as well. What are they, and why might you want to use them?

Build+Run

The main Swift Docker images are designed for building Swift programs. As well as the Swift compiler they include the Swift Package Manager, libdispatch, Foundation, and all the system level requirements like git and pkg-config. While you can use these images to run your Swift program as well, the resulting images are very large because they contain everything the build process needs.

REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
swift latest 25813e4da77c 22 hours ago 1.35GB

The new slim images only contain what’s required to run an already compiled program. That means the number of pre-installed system packages is much smaller, and the image only contains the Swift runtime, not the Swift compiler.

As a consequence, the slim image is much smaller:

REPOSITORY    TAG     IMAGE ID        CREATED         SIZE
swift slim 318115d81cb7 22 hours ago 196MB

The best way to use the slim image is via a multi-stage Dockerfile. Multi-stage builds were introduced in Docker 17.05 and allow a single Dockerfile to chain together build stages from multiple base images.

Example

Here’s the simplest Dockerfile example of using this with the Swift images:

FROM swift:5.0 as builder
WORKDIR /hello-world
RUN swift package init --type executable && swift build
FROM swift:5.0-slim
WORKDIR /hello-world
COPY --from=builder /hello-world .
CMD [".build/x86_64-unknown-linux/debug/hello-world"]

The first half of this Dockerfile uses the full Swift image to initialize a new executable Swift package and build it.

Then, the second half uses the slim image. It copies the compiled Swift package from the full container to the slim container, then specifies what command should be used to run it. Here’s the output of building that Dockerfile.

$ docker build -f Dockerfile
Sending build context to Docker daemon 2.048kB
Step 1/7 : FROM swift:latest as builder
---> 25813e4da77c
Step 2/7 : WORKDIR /hello-world
---> Using cache
---> 17969563548e
Step 3/7 : RUN swift package init --type executable && swift build
---> Running in 388e97129a29
Creating executable package: hello-world
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/hello-world/main.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/hello-worldTests/
Creating Tests/hello-worldTests/hello_worldTests.swift
Creating Tests/hello-worldTests/XCTestManifests.swift
[1/2] Compiling Swift Module 'hello_world' (1 sources)
[2/2] Linking ./.build/x86_64-unknown-linux/debug/hello-world
Removing intermediate container 388e97129a29
---> 34cf5946e5f3
Step 4/7 : FROM swift:slim
---> 318115d81cb7
Step 5/7 : WORKDIR /hello-world
---> Using cache
---> fb08a684b846
Step 6/7 : COPY --from=builder /hello-world .
---> c4c096bc4cac
Step 7/7 : CMD [".build/x86_64-unknown-linux/debug/hello-world"]
---> Running in 7a486ccbb80d
Removing intermediate container 7a486ccbb80d
---> bb483c859efc
Successfully built bb483c859efc

Now that the image has been built, we can run it:

$ docker run bb483c859efc
Hello, world!

Available images

We’ve released slim images for both Ubuntu 18.04 and Ubuntu 16.04. The tags are as follows:

Ubuntu 18:04: 5.0.2-slim, 5.0-slim, 5.0.2-bionic-slim, 5.0-bionic-slim, bionic-slim, slim.

Ubuntu 16.04: 5.0.2-xenial-slim, 5.0-xenial-slim, xenial-slim.

Choose the tag that works for you. If you are deploying to production you probably want to pin your Docker image to a precise version of Swift so you aren’t inadvertently upgraded on a docker pull.

What’s next

Work is already underway on defining the Swift 5.1 Docker images. Work in the Swift open source project means that Swift’s system package requirements are slightly smaller, so the images should be even smaller!

--

--