As developers, we're always looking for ways to streamline our workflow and boost productivity. One of the most powerful tools in our arsenal is hot reloading - the ability to see our changes reflected in real-time without manually restarting our application. But what happens when we throw Docker into the mix? In this post, we'll walk through the process of enabling hot reloading for a Next.js application running inside a Docker container.
Why Docker?
Docker has become an essential tool in modern web development. It allows us to create consistent development environments, simplify deployment processes, and ensure that our application runs the same way across different machines. However, running a Next.js application in Docker can sometimes feel like we're sacrificing the rapid feedback loop we're used to in local development.
The Challenge
By default, when you run a Next.js application in a Docker container, changes to your local files aren't automatically reflected in the running application. This is because the container is isolated from your local file system. To bridge this gap and enable hot reloading, we need to make some specific configurations.
The Solution
To enable hot reloading for Next.js in Docker, we need to make changes to three key files: the Dockerfile, the Docker Compose file, and the Next.js configuration file. Let's break down each of these changes.
1. Updating the Dockerfile
First, we need to modify our Dockerfile to run Next.js in development mode:
FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
COPY next.config.mjs ./next.config.mjs
EXPOSE 3000
CMD ["npm", "run", "dev"]
The key changes here are:
- We're not running
npm run build
anymore. - We've changed the CMD to
npm run dev
to start Next.js in development mode.
2. Modifying the Docker Compose File
Next, we need to update our Docker Compose file to enable volume mounting:
version: '3'
services:
# ... other services ...
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- BACKEND_URL=http://backend:8000
volumes:
- ./frontend:/app
- /app/node_modules
depends_on:
- backend
The crucial additions here are:
- We've added
volumes
to mount the localfrontend
directory to/app
in the container. - We've included a volume for
node_modules
to prevent it from being overwritten by the local mount.
3. Adjusting the Next.js Configuration
Finally, we need to modify our Next.js configuration to enable file watching in Docker:
/** @type {import('next').NextConfig} */
const nextConfig = {
// ... other configurations ...
webpackDevMiddleware: config => {
config.watchOptions = {
poll: 1000,
aggregateTimeout: 300,
}
return config
},
}
export default nextConfig;
The added webpackDevMiddleware
configuration enables polling for file changes, which is necessary for hot reloading to work in Docker.
Putting It All Together
With these changes in place, you can now run your Docker setup with hot reloading enabled. Use the following command to start your containers:
docker-compose up --build
Now, when you make changes to your Next.js application code, you should see those changes reflected almost immediately in your browser, just as if you were running Next.js directly on your host machine.
Conclusion
Enabling hot reloading for Next.js in Docker might seem like a small change, but it can significantly improve your development experience. It combines the consistency and isolation of Docker with the rapid feedback loop we've come to expect in modern web development.
Remember, the first time you run this setup, it might take a while to install all the dependencies. Subsequent runs should be much faster.
By following this guide, you've supercharged your Next.js development environment in Docker. Happy coding!
Top comments (1)
I am getting:
The fix is not to use the webpackDevMiddleware config option. I also found it weird that my next.js config should influence anything related to Docker...
Instead, you should set the environment variable
WATCHPACK_POLLING=true
in your compose.