With the help from SO community I was finally able to dockerize my Sveltekit app and access it from the browser (this was an issue initially). So far so good, but now every time I perform a code change I need to re-build and redeploy my container which obviously is not acceptable. Hot reload is not working, I’ve been trying multiple things I’ve found online but none of them have worked so far.
Here’s my Dockerfile
:
FROM node:19-alpine
# Set the Node environment to development to ensure all packages are installed
ENV NODE_ENV development
# Change our current working directory
WORKDIR /app
# Copy over `package.json` and lock files to optimize the build process
COPY package.json package-lock.json ./
# Install Node modules
RUN npm install
# Copy over rest of the project files
COPY . .
# Perhaps we need to build it for production, but apparently is not needed to run dev script.
# RUN npm run build
# Expose port 3000 for the SvelteKit app and 24678 for Vite's HMR
EXPOSE 3333
EXPOSE 8080
EXPOSE 24678
CMD ["npm", "run", "dev"]
My docker-compose
:
version: "3.9"
services:
dmc-web:
build:
context: .
dockerfile: Dockerfile
container_name: dmc-web
restart: always
ports:
- "3000:3000"
- "3010:3010"
- "8080:8080"
- "5050:5050"
- "24678:24678"
volumes:
- ./:/var/www/html
the scripts from my package.json
:
"scripts": {
"dev": "vite dev --host 0.0.0.0",
"build": "vite build",
"preview": "vite preview",
"test": "playwright test",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
},
and my vite.config.js
:
import { sveltekit } from '@sveltejs/kit/vite';
import {defineConfig} from "vite";
export default defineConfig({
plugins: [sveltekit()],
server: {
watch: {
usePolling: true,
},
host: true, // needed for the DC port mapping to work
strictPort: true,
port: 8080,
}
});
any idea what am I missing? I can reach my app at http://localhost:8080
but cannot get to reload the app when a code change happens.
Thanks.
2
Answers
Why are you using docker for local development? Check this https://stackoverflow.com/a/70159286/3957754
Nodejs works very well even on windows, so my advice is to develop directly in the host with a simple nodejs installation. Your hot reload should work.
Docker is for your test, staging or production servers in which you don’t want a hot-reload because reals users are using your web. Hot reload is only for local development.
container process
When the docker starts, is linked to a live and foreground process. If this process ends or is restarted, the entire container will crash. Check this https://stackoverflow.com/a/68593731/3957754
That’s why docker goal is not related to hot-reload at source code level
anyway
Anyway, if you have a machine in which to have the workspace (nodejs, git, etc) is so complex, you could use docker with nodejs hot reload following these steps:
Solution
The workspace in question does not work simply because it does not bind-mount the source directory. Other than that, it has no problem whatsoever.
Here’s working code at my github:
https://github.com/rabelais88/stackoverflow-answers/tree/main/74680419-svelte-docker-HMR
1. Proper bind mount in docker-compose
The
docker-compose.yaml
from the question only mounts the result of previous build, not the current source files.2. dockerfile should not include file copy and command
dockerfile
does not always have to include command. it is necessary when 1)the result has to be preserved 2)the process lifecycle is critical to image. In this case 1)the result is not quite certain because the source may not be complete at the moment of booting, 2) the process lifecycle is not really important because the user may manually execute or close the container. The local development environment for VSCode + Docker, a.k.a VSCode devcontainer, also usessleep infinity
command for this reason.As mentioned above, the code cannot be copied to docker space because it would conflict with bind-mounted files. To avoid both files collide, just remove
COPY
andCMD
command from dockerfile and add more commands atdocker-compose.yaml
and add command to docker-compose
and rest of configs in the question are not necessary. you can check this out from my working demo at Github
Edit
the answer uses arbitrary settings. the volumes and
CMD
may has to be changed accordingly.i.e.)
I’ve used
/home/node/app
as WORKDIR because/home/node
is used as main WORKDIR for official node docker image. However, it is not necessary to use the same folder. If you’re going to use/home/node/app
, make sure create the folder before use.