I am trying to create a Docker image for a little API I built with Fastify and Node. I came up with the following Dockerfile:
FROM node:current-alpine3.19
WORKDIR /usr/src/app
RUN chown -R node:node /usr/src/app
COPY src/package.json ./
COPY src/package-lock.json ./
RUN npm install
USER node
COPY --chown=node:node ./src .
CMD [ "npm", "start" ]
The build worked and I started the container with "docker run -p 3000:3000 [my-project]".
The file structure seems to be correct and I get the expected response when trying "wget 127.0.0.1:3000" inside the container.
But I can't open the page from my PC with localhost:3000 or 127.0.0.1:3000. Firefox: "The connection to the server was reset while the page was loading." Curl: "curl: (56) Recv failure: Connection reset by peer"
Fastify runs under port 3000, port 3000 is also used in the "docker run" command and I open the page with port 3000.
What am I doing wrong?
You need to accept connections from 0.0.0.0 because 127.0.0.1 references the container and not the host.
So, for example, supposing that your project looks like this (very simplified!):
├── Dockerfile
└── src
├── index.js
├── package.json
└── package-lock.json
then your index.js
might be:
const fastify = require('fastify')({
logger: true
});
fastify.get('/', async (request, reply) => {
return { hello: 'world' }
});
const start = async () => {
try {
await fastify.listen({ port: 3000, host: '0.0.0.0' });
console.log(`Server is running at ${fastify.server.address().port}`);
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
}
start();
The important bit is specifying host: '0.0.0.0'
to fastify.listen()
. You also need to share this port with the host when you do docker run
by giving -p 3000:3000
.