Dockerize a Svelte App with routing
Learn how to make routing work in a dockerized Svelte App with an NGINX.
Recently I have started to play around with Svelte as a frontend technology and I have to say I really like it and for me personally it is better than React and Angular.
To deploy my demo app I have decided to containerize it with Docker, even though Docker is not free anymore for companies bigger than 10 people. No problem for me right now, but I am still not happy about this decision by Docker (I understand it from a business perspective though) and there are multiple alternatives that can be tried like Buildah.
To building a containerized application for Docker I have used the following guide, which works like a charm: https://sveltesociety.dev/recipes/publishing-and-deploying/dockerize-a-svelte-app
Routing on NGINX for Svelte apps
One thing I have realized though, if you are using routing in your Svelte app (e.g. with svelte-routing) then this is not working because for Svelte you need to have all requests coming to your index.html in order to get the routing done.
For an NGINX this can be achieved by adding try_files to your config file:
try_files $uri $uri/ /index.html;
NGINX config for Svelte routing
So all you need to do is to create a default.conf with this configuration and update it during the docker build phase. I have create a folder called nginx with the following default.conf:
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Dockerfile to make the Svelte routing work on NGINX
The updated dockerfile looks like this:
FROM node:14 AS build
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . ./
RUN npm run build
FROM nginx:1.23-alpine
COPY --from=build /app/public /usr/share/nginx/html
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
That's it, now you can run the docker build command, and the routing is working:
docker build . -t my-image-name