Saving Express Apps with Docker
Learn how to use Docker to save Express apps from crashing indefinitely. We will go over Docker restart policies and how Express handles asynchronous errors.
Table of Contents 📖
Express Crashing
Express apps will crash if an error is not caught in an asynchronous function. In the code below, sending a GET request to /crash will cause the app to crash.
import express from 'express';
const HOST = process.env.HOST;
const PORT = process.env.PORT;
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/crash', async (req, res) => {
throw new Error('Crash!');
});
app.listen(PORT, HOST, () => {
console.log(`Running on http://${HOST}:${PORT}`);
});
curl localhost:3000
Hello World!
curl localhost:3000/crash
curl: (52) Empty reply from server
curl localhost:3000
curl: (52) Empty reply from server
Dockerizing Express
Docker can act as a backup if Express apps crash due to its restart policies. In other words, when the app crashes, Docker can restart it. The following Dockerfile and command Dockerizes the above Express app.
FROM node:22-alpine
ENV PORT=3000
ENV HOST=0.0.0.0
WORKDIR /server
COPY package*.json ./
RUN npm i
COPY . .
CMD ["npm", "start"]
docker build -t node-i .
Now we can spin up a Docker container from this image with the restart policy set to always. This makes it so the container always restarts if it stops.
docker run --name node-c -p 3000:3000 --restart=always node-i
curl localhost:3000
Hello World!
curl localhost:3000/crash
curl: (52) Empty reply from server
curl localhost:3000
Hello World!
When our app crashes, Docker restarts it, allowing us to proceed as normal. Of course, we should set up a detection system for these errors and ensure they don't happen again, but this acts as a nice safety net.