“Slim” Docker images for Swift
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 buildFROM 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!