daniebker

Running a SvelteKit app in Docker

· [Daniel Baker]

Getting SvelteKit to work in a docker environment is pretty straight forward, you just need to change a configuration option first to build the application for your environment.

This example assumes you already have a working SvelteKit app. The steps in this article work on an application created using the Getting Started guide in the svelte kit docs. Following the same steps should work for this article.

Once you have a SvelteKit app running locally we’re ready to start preparing the docker image. In this guide I’m going to be using node as the environment.

Setting up Svelte for Node

The first thing we need to do is install the node adapter and update the svelte config to use that adapter instead.

npm i -D @sveltejs/adapter-node

Then update the svelte.config.js file to remove the following:

import adapter from "@sveltejs/adapter-auto"

and replace it with:

import adapter from '@sveltejs/adapter-node';

This instructs SvelteKit to use the node adapter when building. Run a build to check everything worked.

npm run build

You should now have a build/ folder at the root of the SvelteKit app with the following files.

client     env.js     handler.js index.js   server     shims.js

Running node index.js in this folder should launch a server where you can navigate to your app.

Building the SvelteKit Dockerfile

The next step is to create a Dockerfile to copy over the app, install dependencies, and build the production code. At the root of the app directory create a new file Dockerfile

The Dockerfile has been split into multiple parts so that dependencies are only redownloaded when they change. This should speed up the image build since the code is changing more often than dependencies.

FROM node:18-alpine AS base

FROM base AS installer
RUN apk add --no-cache libc6-compat curl
RUN apk update

# Set working directory
WORKDIR /app
COPY . .

# First install the dependencies (as they change less often)
RUN npm ci

# Copy over deps and then build sveltekit
FROM base as builder
WORKDIR /app
COPY --from=installer /app .
RUN npm run build

FROM base AS runner
WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 sveltejs
USER sveltejs

COPY --from=builder /app/package.json .
COPY --from=builder --chown=sveltejs:nodejs /app/build ./
COPY --from=builder /app/node_modules ./node_modules

CMD node index.js

Next create a docker compose file that uses the docker image to easily start the application.

version: '3.7'
services:
  web:
    container_name: sveltekit
    environment:
      - ORIGIN=http://localhost:3000
    build:
      context: .
      dockerfile: ./Dockerfile
    restart: unless-stopped
    ports:
      - 3000:3000
    networks:
      - app_network

networks:
  app_network:

Running docker compose up -d will build the Dockerfile and start the container. You should now be able to access your application running in the docker container at http://localhost:3000

If you make changes to the app and you want to force a rebuild run docker compose up -d --build

Wrapping up

And that’s it! You should now have a docker image built and a docker compose file capable of running your application.

For a complete example check out the repository over on GitHub. Comments, suggestions, and pull requests welcome!