Update: I recently expanded upon this post in another story, where I altered the
Dockerfile
to use distroless: Fastify + Distroless Docker = 😍
Fastify is a popular, efficient and low overhead Node.js web framework for building scalable and fast HTTP servers. Docker is a powerful containerization tool that allows you to create and manage lightweight and portable containers that run your applications.
In this blog post, we will describe how to run a simple “hello world” HTTP server using the Fastify library inside a Docker container in Node.js.
Prerequisites
- Node.js and npm installed on your system.
- Docker installed on your system.
Create a new Node.js project
First, create a new directory for your project and initialise a new Node.js project using npm. Run the following commands in your terminal:
mkdir fastify-docker
cd fastify-docker
npm init -y
Install Fastify
Next, install Fastify and save it as a dependency in your project using npm. Run the following command in your terminal:
npm install fastify --save
Create the “hello world” server
Now, create a new file called index.js
in the root of your project directory. This file will contain the code for the "hello world" HTTP server.
const fastify = require('fastify')();
const { ADDRESS = 'localhost', PORT = '3000' } = process.env;
fastify.get('/', async (request, reply) => {
return { message: 'Hello world!' }
})
fastify.listen({ host: ADDRESS, port: parseInt(PORT, 10) }, (err, address) => {
if (err) {
console.error(err)
process.exit(1)
}
console.log(`Server listening at ${address}`)
})
By default, Fastify (and many other web servers) bind to the loopback IP address (127.0.0.1) when running on the host machine, which means that it can only receive connections from the same machine. However, when running inside a Docker container, the container’s loopback IP address is not accessible from the host machine or other machines on the network.
To allow incoming connections to reach Fastify inside the container, we need to bind to an IP address that is accessible from outside the container. Binding to 0.0.0.0 is a way to bind to all available network interfaces on the container, which means that Fastify will be able to receive connections from any IP address that can reach the container.
This code creates a new Fastify instance, defines a single GET
route for the root path, and starts the server listening on port 3000
. When a client makes a request to the root path, the server will respond with a JSON object containing the message "Hello world!".
Create a Dockerfile
Next, create a new file called Dockerfile
in the root of your project directory. This file will contain the instructions for building your Docker image.
FROM node:14
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
ENV ADDRESS=0.0.0.0 PORT=3000
CMD ["npm", "start"]
This Dockerfile
starts with the official Node.js 14 image, sets the working directory to /app
, copies the package.json
file to the working directory, installs the dependencies using npm, copies the rest of the files to the working directory, exposes port 3000, and sets the default command to run the npm start
script.
Build the Docker image
Now that you have created the Dockerfile
, you can use it to build a Docker image. Run the following command in your terminal:
docker build -t fastify-docker .
This command tells Docker to build an image using the instructions in the Dockerfile
and tag it with the name fastify-docker
.
Run the Docker container
Finally, you can run the Docker container using the image you just built. Run the following command in your terminal:
docker run -p 3000:3000 fastify-docker
This command tells Docker to run a container using the fastify-docker
image and map port 3000 inside the container to port 3000 on your local machine.
Test the server
You can now test your “hello world” server by opening a web browser and navigating to http://localhost:3000. You should see a JSON response containing the message “Hello world!”.
Congratulations! You have successfully built and run a Fastify HTTP server inside a Docker container in ❤️