3

Build and Run a Node.js application in Docker

 2 years ago
source link: https://blog.bitsrc.io/build-and-run-a-nodejs-application-in-docker-8f728df84d2a
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

A small Node.js API

For this tutorial, we are not going to spend much time working on our API as our goal is to deploy it.

In a new folder, run npm init -y and install Express with npm install -S express

Create an index.js file and paste the following content into it:

const express = require('express');

const app = express();

app.get('/ping', (req, res) => {
res.send('pong');
});

app.listen(3000, () => {
console.log('listening on port 3000');
});

Run your app with node index.js and go onto http://localhost:3000/ping you should be able to see pong.

That’s all for our app! Let’s create our Dockerfile now.

Build with a Dockerfile

Create a new file called Dockerfile.

Note: The case/name is very important as it’s how Docker detects the file to build it

Pick our base image

Now, the first step when building with Docker is choosing the base image that Docker will use. Images are usually based on operating systems (alpine, debian, ubuntu) or on runtimes (NodeJS, Java, …)

Note: It is also possible to pick the operating system to use with the runtime. Like nodejs-alpine, for example.

For this tutorial, we are going to use a NodeJS (LTS 16.x) image based on alpine, You can easily find it on the Docker HUB website.

As a first-line in your Dockerfile, add the following content:

FROM node:16-alpine

This will fetch an alpine image with NodeJS 16.x pre-installed.

Using an image based on a runtime allows us a minimum of setup as it’s already done for us. You may want later to have more control on your container but for the current goal, it’s more than enough for us

Copy our local environment into our Docker image

Next, we’d like to copy from our local environment to our Docker image our project files. To do so, we are going to use the ADD command:

ADD . ./

This is going to copy all your content at the root level of your docker image.

The only issue we’re having with this is that our node_modules are going to be included as well and we don’t want that. A simple solution would be to add only specific files or folders. It’d work for our project as it’s small, but when it’ll grow, it’ll quickly become a nightmare.

We are then going to create a .dockerignore file. This file works the same way than .gitignore.

In your .dockerignore add the following content:

node_modules

Now, ADD will ignore the node_modules !

Adding the node modules in the image from the local is not recommended. Some packages are OS specific (node-sass for example) and as a docker image can be another operating system, your app is unlikely to run in there

Install our dependencies in the images

Because we are building the image without the node_modules, we now have to install them. We are going to use npm install -ci for that with the command RUN:

RUN npm install -ci

We could use npm install but it may pick up newer version of the libraries depending if you are using the symbols ^ and ~ in your package.json and we want our app to match exactly with our package-lock.json

Run the app

The final step is running the app. We’d have to add a final line in our Dockerfile which tells Docker what command to execute when we are deploying the image in a container.

At the end of the Dockerfile, add the following line:

CMD ["node", "index.js"]

As our original command is node index.js we have to specify as parameters each “word” separately

Now, our app is ready to run, build it first with the command

docker build -t express-app .

-t is to assign a tag to our image. It allow us to run it more easily

And run it with the command

docker run -p 3000:3000 express-app

-p is to publish ports on the host. Otherwise, we wouldn’t be able to access our express server within our docker container. The left side of the colon is on the host side and the right side is the port used by express.

Et voila! If you now go again on localhost:3000/ping you should see a pong

Bonus: Using docker-compose

I’m a big fan of docker-compose. It makes our life so much easier.

We are first going to create our docker-compose.yml file and then past this content:

services:
express-app:
build: .
ports:
- 3000:3000

Since some versions ago, the version at the top of this file is not required anymore.

Make sure that this docker-compose.yml is at the same level than the Dockerfile

As you can see, we are describing one service called express-app building our local Dockerfile and exposing the port 3000 .

Simply run docker-compose up to build and run your container!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK