![](/style/images/good.png)
![](/style/images/bad.png)
Build and Run a Node.js application in Docker
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 theDockerfile
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!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK