Vapor 4 deployment on small docker image like for instance 12.1-alpine

Hi there,

is it possible to have a smaller Run image for Vapor 4 apps than vapor/ubuntu:18.04?

From looking at the Dockerfile included in a Vapor 4 project I conclude that all the heavy stuff needed for building the Vapor 4 app is included in the Build image which is vapor/swift:5.2. So what is really needed to run the Vapor 4 app, I hope something smaller than a full fledged Ubuntu 18.04 is sufficient. I ideally had it running on a image as minimal as an 12.1-alpine, but would that be possible?

Motivation:

The department I work in is currently investigating whether Vapor 4 can be used as a system for our backends. Up until now we're mostly using Node.js for that purpose and to some extend Golang. Since it is our main task to develop mobile apps, most of our developers are profound in Swift and/or Kotlin. Not so much in JavaScript for Node or Golang. Because of this the backends are mostly done by one person who knows all this, but this person turns out to be more and more a bottleneck.
All our backends are running in Docker containers. To keep the footprint small, we usually prefer some sort of alpine images which contain only the absolutely necessary stuff inside. The person responsible for our hosting said, that deploying fully fledged Ubuntu images on our servers would be an absolute no go because of their sheer size alone.
So whether we can use Vapor for backend development depends on the crucial question: is it possible to deploy Vapor 4 apps in docker images smaller than Ubuntu?

Thanks in advance,

Lars

The smallest officially supported Swift images you will find are the slim images. They are still based on Ubuntu but quite a bit smaller footprint. You will need to cross reference the Dockerfile there with the one vapor suggests to see what libraries vapor adds that are not strictly speaking necessary to just run Swift.

@mattpolzin is that the final word on that topic? I asked our person who is responsible for the hosting and he answered: "still not small enough". Is there a way to use something smaller or isn't that possible at all?

Thanks in advance,

Lars

How small do they want it and what size are you seeing your deployment images coming out as?

Alpine isn't possible because of Swifts reliance on specific versions of glibc IIRC

Yeah, some in the community have worked on non-Ubuntu Swift releases, but Alpine seems like a stretch because of the non-standard Linux libraries it ships with.

@IOOI Not sure what you mean by final word; I am just stating the fact that official support stops at Ubuntu and Ubuntu-slim docker images (as of now, subject to change in the future). Beyond that, the community has had some success with other distributions but not Alpine per se to my knowledge.

It seems rather absurd 40MB can make a difference (Alpine base is 2.5MB, Xenial slim is 42.5MB). Future Ubuntus will be better (about 28MB) but hitting an Alpine size will never be possible, even on Alpine itself, due to the additional dependencies that would be required. Swift itself is about 50MB.

Hi @all,

I tried to reach the responsible person, but here it's already after 20:00h, so he will have already finished work (we are all in the home office because of Corona, so I don't know exactly). So his answer probably won't come until tomorrow.

In the meantime, I have goggled and got wind of a mysterious 29MB minimal Ubuntu Image, which is supposed to be here: Ubuntu Minimal Cloud Images (RELEASED) but as far as I had a look the images in question there are way larger.

So anyone knows where to find this mysterious 29MB minimal Ubuntu Docker image and whether it would be sufficient to run Vapor 4 apps?

Yes, sorry, looks like the base Bionic image is already down to the 28MB I mentioned. That makes the slim Swift image ~78MB. You can find all of the Ubuntu images here.

Using Vapor you’ll tack on a bit more size to the smallest possible image than the aforementioned ~78MB, and then there’s the likely modest size of your executable as well. This may make it not the absolute lightest weight microservice Docker image, but in this day and age I can’t imagine the hard drive space you are dealing with is so limited that this will make or break things for you.

@Jon_Shier @mattpolzin , got an late night answer from our Docker and Deployments guy. He wrote (translated using https://www.deepl.com/ ):

When you build productive containers, you take Scratch or Alpine as a basis, that is the state of the art. If it doesn't work on that, it's just not mature.

Since he has the final word is this regard our department currently is out of using Vapor for now. Like I said, it wasn't my decision. I regret it very much, maybe I'll see you again sometime later.

Kind regards,

Lars

To each their own, I suppose, but I would definitely disagree with his assessment. I’d call swift “younger” for sure than other options but using availability of Apline docker images as a gauge for “maturity” is a bit odd. The useful definition for “maturity” would be something that actually indicates stability of a platform and the ecosystem of libraries and tools available for it. These are areas in which Swift certainly shows its youth, but if there’s enough out there to write your server app then Swift is “mature” enough for the given application.

Anyway, I know you’re not personally in need of convincing so I’m just talking out loud.

Cheers.

1 Like

So Java's not mature? Sounds like a made up rule, since not all software is compatible with Alpine's changes. Even Java offers it only as an option, not the default, because of possible incompatibilities.

1 Like

You can absolutely do distro-less Swift containers built from a SCRATCH base and make really small deployment containers. The trick is that the Swift runtime itself needs to be in a separate container that is only deployed once. I do precisely this in: GitHub - CSCIX65G/SwiftCrossCompilers: SPM toolchain to cross compile Raspberry Pi (arm64) and Amd64 Swift binaries on macOS , the Swift NIO echo server I create in the subdir there came in at <4MB when stripped the last time I looked. I expect a Vaporized version of something similar would only add 1MB or so. Probably even less if you moved Vapor and its dependencies into their own separate container as well.

I'd imagine that your dev-ops guy's objection is not nearly as much to size as it is to the use of any distro which would allow you to get to a shell prompt in his production environment. I mean if you are deploying to a lot of machines the difference between 5MB and 100MB is pretty important for deploy times alone, but the real benefit to distro-less containers is in minimizing the security cross-section, IMO.

2 Likes