Create a Swift Docker image to build a static website using Publish
The typical workflow of working on a static website with Publish is, usually,
publish runlocally to get a localhost web server;
- work on the content, theme, or building process on (possibly) Xcode;
- compile the latest changes;
- see the changes on the localhost;
- go live with the changes.
When you are ready to go live with your website, you are faced with a choice: building your website locally to upload the output on a hosted space, or having some continuous deployment tool take care of the building process and upload.
Locally building and uploading
When you run
publish run, an
Output directory is created, with the compiled version of your website. You can manually upload the content of this directory to where your website is hosted.
Publish facilitates the deployment process by including a
publish deploy command can be run on your machine and everything should work fine, because you already have all the dependencies and external tools that you need to compile the website during development.
How to avoid building locally
If, instead, you run
publish deploy from your continuous deployment tool, you will need to use an environment that includes all your needed dependencies and external tools.
The best way to ensure that the machine used to build your website has all the needed tools is by using a Docker container.
A Docker container is a lightweight, versioned, piece of software that is independent from the environment that runs it. This independence is exactly what we are looking for.
We want a container that is able to compile Swift packages, plus the external tools that we need for our specific website.
Once we define such a container, we can use continuous deployment tools to load the container and compile/deploy our website from it. It does not matter when we compile, or where we compile it, the output code for our website will be the sameas long as we use the same container.
A Docker container is defined by a Docker image. You can have multiple containers running at the same time, defined by the same Docker image.
A Docker image is built from a versioned file called Dockerfile.
In our case, the image needs to include a version of Swift and all the external tools we need for compiling the website. We define tools and versions in the Dockerfile.
A very basic Dockerfile that we can use is
which says: use the base Docker image, maintained by the Swift team, that has Swift version 5.2.4, and do not add anything to it.
Such Dockerfile is not very interesting, it does not add anything to that base image, thus we could use that image directly.
But if we need some external tool like LibSass to compile
sass code into
css with the SassPublishPlugin, or if we modify images in building time with ImageMagick using MagickPublishPlugin, we need to add the tools in the Docker image.
A much more interesting Dockerfile would be
FROM swift:5.2.4 # Needed libraries and programs RUN apt-get update && apt-get install -y \ libsass-dev \ imagemagick \ && rm -rf /var/lib/apt/lists/* \
where, when compiling the Docker image, we install
Every container launched from this image will include Swift, LibSass, and ImageMagick, so it will be ready to compile our website.
Using the container
The Docker image defined by the Dockerfile above can be used in continuous deployment tools like GitHub Actions, or GitLab CI/CD.
For instance it can be used as starting image in this article about using GitLab CI/CD to publish Swift static websites.
You can build the image every time you need it, that is, every time you push new changes to your remote repository, or, you can use the image I already uploaded to Docker Hub so you do not need to maintain the Dockerfile.
If you need a special Docker file, you can even start from my image and add more external tools. Then you can publish your own version on Docker Hub, a big repository of images that everybody can easily use:
FROM ishouldgotosleep/swift-publish:5.2.4 # Needed libraries and programs RUN apt-get update && apt-get install -y \ # Your tools and libraries here && rm -rf /var/lib/apt/lists/* \
Leave a comment