Essay - Published: 2022.11.16 | docker | node | sveltekit |
DISCLOSURE: If you buy through affiliate links, I may earn a small commission. (disclosures)
SvelteKit is my favorite frontend framework. I containerize most of my projects for ease of development and the ability to run anywhere.
In this post we'll walk through how to build and serve SvelteKit with Node in a Docker container.
In order to follow along with this tutorial, we're going to assume you already have a few things installed / available to you:
A typical Dockerfile to build and serve SvelteKit on Node looks like this:
Dockerfile
FROM node:lts-slim as build
WORKDIR /app
COPY package*.json ./
RUN rm -rf node_modules
RUN rm -rf build
COPY . .
RUN npm install
RUN npm run build
FROM node:lts-slim as run
WORKDIR /app
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/build ./build
RUN npm install --production
EXPOSE 8080
ENTRYPOINT [ "npm", "run", "start" ]
The package.json commands look like this:
package.json
"scripts": {
"build": "vite build",
"start": "export PORT=8080 && node ./build",
},
This Dockerfile is split into two sections:
viteNote: This is the same Dockerfile / package.json I use to build and serve all my SvelteKit sites (including this one). You can get your hands on a full-stack, fully-Dockerized SvelteKit project with CloudSeed.
I think the Dockerfile itself is pretty straightforward but there are likely a lot of open questions about why some decisions were made. As such I'm going to use the rest of this post to cover some common questions I've received / I researched during my build.
We can save a decent chunk of storage by going multistage. This is because most SvelteKit sites will have some dependencies that are needed for dev / building the site but not actually for running it. By going multistage we omit those dependencies in the final image.
Anecdata:
slim image size (125mb -> 105mb (20mb, 16%))node:slim vs alpine / regular?slim and alpine provide much smaller image sizes than regular (~75% smaller). In most cases, there's no reason to have a full on OS running your image (this is what regular provides) so in most cases you should go with a slim or alpine.
When choosing between slim and alpine it becomes a harder tradeoff. slim is typically a bit heavier than alpine (~20%) but it uses more common libraries which leaves less performance pitfalls. Whether or not the extra image savings is worth the potential performance pitfalls will depend on your workflow but I tend to go with slim to maximize savings and minimize risk.
alpine performance pitfalls references:
Anecdata:
regular: 409 mbslim: 105 mbalpine: 92 mblts vs latest?This is a harder one. lts (long-term support) is pretty behind in Node versions when compared to latest (currently at lts = 16 vs latest = 19). This likely means that latest is going to have much faster, more updated software.
That said, I typically think building on lts versions of software is better for your projects as it provides a much more stable base with more community support and less breaking changes.
If you do not specifically need some feature from a later release, I'd recommend sticking with lts. It will get these features eventually and when it does they will be well tested.
node vs vite preview?So most SvelteKit example projects will ship with a serve script utilizing vite preview. That said vite preview is specifically not meant for serving production traffic. From the official documentation:
It is important to note that vite preview is intended for previewing the build locally and not meant as a production server.
To be fair - this is fine in most cases. There are plenty of examples of frameworks not meant for production being used in production for years at high scale companies with little fanfare.
But if we're trying to do it "right" then we'll follow best practices and just serve with node.
Anecdotally I haven't really seen much of a difference in my sites' performance but I also don't serve much traffic so ymmv.
The best way to support my work is to like / comment / share for the algorithm and subscribe for future updates.