Hot reload doesn't work inside Docker container
Link to the code that reproduces this issue
https://github.com/ArtoszBart/next-issue
To Reproduce
docker-compose up- make change in page.tsx
- save changes
Current vs. Expected behavior
Hot reload should reload the page to show changes, but changes is not visible in the browser
Provide environment information
Physical PC:
Operating System:
Platform: win32
Arch: x64
Version: Windows 10 Education
Available memory (MB): 16319
Available CPU cores: 16
Binaries:
Node: 20.18.0
npm: N/A
Yarn: N/A
pnpm: N/A
Relevant Packages:
next: 15.0.0 // Latest available version is detected (15.0.0).
eslint-config-next: 15.0.0
react: 19.0.0-rc-65a56d0e-20241020
react-dom: 19.0.0-rc-65a56d0e-20241020
typescript: 5.6.3
Next.js Config:
output: N/A
Container:
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP Fri Mar 29 23:14:13 UTC 2024
Available memory (MB): 7911
Available CPU cores: 16
Binaries:
Node: 20.18.0
npm: 10.8.2
Yarn: 1.22.22
pnpm: N/A
Relevant Packages:
next: 15.0.0 // Latest available version is detected (15.0.0).
eslint-config-next: 15.0.0
react: 19.0.0-rc-65a56d0e-20241020
react-dom: 19.0.0-rc-65a56d0e-20241020
typescript: 5.6.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Developer Experience
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
After saving changes in page.tsx on the PC, the .next/server/chunks/ssr on PC is updated same as page.tsx in container. However .next/server/chunks/ssr in container remains not updated.
Isn't this COPY . . only going to copy the source once, when you build up the container?
https://github.com/ArtoszBart/next-issue/blob/2e6ac6b3f252f172327d0ec22d205ad46ce1df63/Dockerfile.dev#L6
I'm pretty sure that if you want "outside" changes to be reflected inside the container in real time (without rebuilding), you need to mount the directory as a volume instead of just copying it.
Isn't this
COPY . .only going to copy the source once, when you start up the container? https://github.com/ArtoszBart/next-issue/blob/2e6ac6b3f252f172327d0ec22d205ad46ce1df63/Dockerfile.dev#L6I'm pretty sure that if you want "outside" changes to be reflected inside the container in real time (without restarting compose), you need to mount the directory as a volume instead of just copying.
Exactly. Volume mapping is in the docker-compose.yml file.
As I said earlier:
After saving changes in page.tsx on the PC, the .next/server/chunks/ssr on PC is updated same as page.tsx in container
Same problem here in nextjs 15 doesnt work wit turbopack in nextjs 14.2.5 its work
nvm after I mirrored this one it works somehow: volumes:
- ./:/app
- ./apps/web/node_modules:/app/apps/web/node_modules
- ./apps/web/.next:/app/apps/web/.next
Downgraded to [email protected]:
With:
volumes:
- ./:/app
After saving changes in page.tsx on the PC, the .next/server/app/page.js both on PC and container is updated same as page.tsx in container. However changes in app running inside container remains not updated in browser. After page reload i have:
Server Error
Error: Could not find the module "/app/node_modules/next/dist/client/components/app-router.js#" in the React Client Manifest. This is probably a bug in the React Server Components bundler.
The same error occurs with:
volumes:
- ./:/app
- ./node_modules:/app/node_modules
- ./.next:/app/.next
Having same issue with "next": "^15.0.0". Adding volume change is updated in docker but log never compile the new update.
Placing
const nextConfig: NextConfig = {
output: "standalone",
outputFileTracingRoot: path.join(__dirname, "../../"),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
webpackDevMiddleware: (config: any) => {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
};
return config;
},
};
Inside the next.config.ts worked for me. You will get warnings in the console when you start the container:
⚠ Invalid next.config.ts options detected:
frontend-1 | ⚠ Unrecognized key(s) in object: 'webpackDevMiddleware'
frontend-1 | ⚠ See more info here: https://nextjs.org/docs/messages/invalid-next-config
Keep in mind that you still need to add volumes in your docker-compose.yml file:
frontend:
build:
context: .
dockerfile: ./apps/frontend/Dockerfile
ports:
- "3000:3000"
volumes:
- ./apps/frontend:/app/apps/frontend
environment:
- NODE_ENV=development
depends_on:
- backend
It's still not working for me
It's still not working for me
This worked for me:
Edit the file "package.json" like so:
"scripts": { "dev": "WATCHPACK_POLLING=true next dev", ... }
This worked for me:
frontend\next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "standalone",
};
export default nextConfig;
docker-compose.dev.yaml
...
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
target: dev
container_name: frontend-dev
volumes:
- ./frontend:/app
- /app/node_modules
restart: unless-stopped
ports:
- "3000:3000"
env_file:
- .env
depends_on:
- backend
networks:
- devnet
command: npm run dev
...
frontend\package.json
"scripts": {
"dev": "WATCHPACK_POLLING=true next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"lucide-react": "^0.479.0",
"next": "^15.2.4",
"next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-hook-form": "^7.55.0",
},
finally got mine to work with docker-compose using the following snippet:
services:
client:
build:
context: .
image: ${DOCKER_USERNAME}/integrated-tracker
environment:
- WATCHPACK_POLLING=true
ports:
- "3000:${LOCAL_CLIENT_PORT}"
develop:
watch:
- action: sync
path: ./src
target: /app/src
ignore:
- node_modules
- action: rebuild
path: package.json
Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!
Another approach to accomplish this is by utilizing Docker compose watch feature. Here is example:
services:
web:
build:
dockerfile: dev.Dockerfile
develop:
watch:
- action: sync
path: .
target: /app
ignore:
- node_modules/
Adding this code to package.json on ui works for me too;
"scripts": { "dev": "WATCHPACK_POLLING=true next dev",
Here its working for webpack.
"scripts": { "dev": "WATCHPACK_POLLING=true next dev",
But not working for turbopack
"scripts": { "dev": "WATCHPACK_POLLING=true next dev --turbopack" ❌
I think that polling may not be using in turbopack, then it has to be any remedy to that.. Because of this hot reload is not working using turbo in nextjs.
I'm using Turbopack and having the exact same problem. Can't we fix this without having to use Webpack?