Hello there, This post is a continuation of my docker article. To check click the links.
Docker in and out
Dockerize NodeJs app
To follow along, you must have docker and node installed.
Today, we will learn how we can deploy two services NodeJs app with MongoDb
.
Find the source code here
Agenda
π― Node Project Setup
π― Docker setup
π― Folder structure
π― Code breakdown
Initiate the project
npm init -y
Install the dependencies
npm i express dotenv mongoose
package.json
Docker Setup
To pull node and mongo image, go to docker hub and get the official images. click
Make sure your docker deamon is on. Click on the docker desktop to activate the deamon.
To check if your docker is installed on your machine, run docker --version
in your terminal
Pull node image
Pull the mongo image
Check the docker images
docker image ls
Folder structure
Here's our folder structure in its most basic architecture.
Code breakdown
π Database setup
In this config folder, we imported the mongoose module, connected to our database and exported the configuration.
β οΈ Note:
- The
docker-node-mongo
can be named anything - Notice the
mongo
:27017/docker-node-mongo, this replaces thelocalhost
we use in our development mode.
π Model and Schema
Here we import the mongoose library and create a new schema for the user.
π Routes
We write the business logic and export the express router and thereafter mount it in the main entry file app.js
π .env
π app.js
const express = require('express');
const dotenv = require('dotenv');
dotenv.config();
const connectDb = require('./config/db');
const app = express();
connectDb();
const port = process.env.NODE_LOCAL_PORT || 3020;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.get('/', (req, res) => {
res.send('Hello World');
});
app.use('/', require('./routes/user'));
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Now, let's test our app locally by running the following command:
npm start
Next, let's stop the server by running Ctrl + C
.
Docker file
The first line is the base image that we want to use.
The WORKDIR command is used to set the working directory for the container.
We copy the package.json file to the current directory.
We install our dependencies.The COPY command copies the contents of the current directory to the Dockerfile's context.
The EXPOSE command is used to expose ports to the outside world.
The CMD directive is used to specify the command that will be run when the image is run.
β οΈ We could actually go ahead to build this image using this Dockerfile by running the build command like
docker build -t [name of container]
and then run usingdocker run -p 8082:8082 [image name] ...
but it will not connect to the mongodb service. In other to be able to run the two services we need adocker-compose.yml
file
Docker compose file
Lastly, we setup our docker-compose.yml for the app and mongo service. This file helps us to build and link our NodeJs app to the mongo image.
Testing
To test we run this command:
docker-compose up -d
The -d
flag means we are running the container in a detached mode.
To check running containers
We see the two containers up and running.
Testing the POST route.
Lets check our created user using the docker exec
command.
Check the running container
Enter into the mongo container
Conclusion
I hope this post was helpful. Check the above link for the source code if you get stuck while following along.
Top comments (20)
Thank you very much! for creating this
It's very helpful to me while doing a course on Coursera. You have created such an easy way to perform the steps.
is your code run ?
yes
How kindly explain so that I can sort out, it is not running when I run command 'npm start'
send your discord user name, I will connect with you and explain or if you can explain your problem here in detail
your github repo has nothing to solve
I couldn't done this. is the documentation correct or something missing or not guided according to the beginner level ?
Everything is correct; just follow the steps. Did you install Node and Docker?
yes, but when I run localhost to check docker container it is not respond and when I run command 'npm start' the other port for node is running.
Yes, actually, there is a problem with the Mongoose file db.js
`const mongoose = require('mongoose');
const mongoURI = "mongodb://localhost:27017"
const connectDb = async () => {
try {
mongoose.set('strictQuery', false)
mongoose.connect(mongoURI)
console.log('Mongo connected')
}
catch(error) {
console.log(error)
process.exit()
}
}
module.exports = connectDb;
`
try this code instead.
hope this will help to resolve.
C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\router\index.js:469
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a Object
at Function.use (C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\router\index.js:469:13)
at Function. (C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\application.js:227:21)
at Array.forEach ()
at Function.use (C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\application.js:224:7)
at Object. (C:\Users\zahak\OneDrive\Desktop\webApp\app.js:18:5)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Function.executeUserEntryPoint as runMain
Now this error I'm facing
send your app.js and user.js file to me, there's probably problem with your routes
how ? where ?
can you push it on your github ?
doing
pushed Code, have you seen yet ?
Sorry, bro, I was busy for a few days. couldn't see it; I even didn't get this notification. Will see and let you know asap.
C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\router\index.js:469
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a Object
at Function.use (C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\router\index.js:469:13)
at Function. (C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\application.js:227:21)
at Array.forEach ()
at Function.use (C:\Users\zahak\OneDrive\Desktop\webApp\node_modules\express\lib\application.js:224:7)
at Object. (C:\Users\zahak\OneDrive\Desktop\webApp\app.js:18:5)
at Module._compile (node:internal/modules/cjs/loader:1256:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
at Module.load (node:internal/modules/cjs/loader:1119:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Function.executeUserEntryPoint as runMain
I got this error
added two files to your repository.