integrate with other tech like mongoose, Datastax and firebase and learning something cool.
Now that i've learned about nodeJs and various stuff within it.
I'm now focusing on best way to deploy nodeJs web application.
Heroku is still one of the best options, But i want something more flexible and controllable. that's where Docker
comes in.
So let's learn docker.
There are two different things in the beginning:
- image
- container
suppose i've created a simple node app. Now it's time to run, test and deploy it. First thing i'll do is to create a Dockerfile
.
it is set of commands that docker will execute in order to create docker image.
simple file can be:
FROM node # docker will use latest node image to provide runtime env for app
ENV node_env production # setting environment variable
WORKDIR app/ # create and enter folder `app` in container
COPY [ "package.json", "package-lock.json*", "./" ] # copy package.json and package-lock.json file from current dir to folder named `/app` in continer
RUN npm install # install all dependencies for node app by reading that package.json
COPY . . # copy everything from local active dir to containers' active directory
CMD ["node", "app.js"] # command that container executes everytime built image runs
-
FROM xyz
: use latest image ofxyz
from docker repo.- also
xyz:12.2.3
is an option, to use specific version of that image.
- also
-
RUN
: is to execute commands during building the image. you can use multipleRUN
inDockerfile
- example:
RUN npm install
- example:
-
CMD
: is command that execute in the container everytime you run a built image.- example:
CMD ["node", "app.js"]
- example:
this file will give docker the instruction to a build an image.
if there's some files on your local dir that you dont want to be on your container, then use
.dockerignore
file; it works exactly as.gitignore
file.
Now let's build an image:
- go to same directory as
Dockerfile
and execute following
docker build --tag image-name .
this command will create a docker image of name image-name
- you can list all docker images on your local machine using this command:
docker images
now that you've build your first image, you can find that image named image-name in this list.
It's time to create a container by running that image.
docker run image-name
this command will run your image and will create a container with random name and latest tag.
Another thing to notice here is, containers are isolated from your local machine; means you can't access ports of container without exposing it to communicate with outside world.
docker run -p 80:3000 --name something -d image-name
this command will create a docker container named todo
and run it.
-
-p 80:3000
: exposing container's port3000
to local machine on port80
-
-d
: dispatch means run in background.
Start same container next time,
docker start container-name
Stop a container
docker stop container-name
List of all running containers
docker ps
List of all containers
docker ps -a
Logs of continer
docker logs container-name
Continous logs of container
docker logs container-name -f
Remove a container
docker rm container-name
remove an image
docker rmi image-name
change tag of image
docker tag image-name docker-id/image-name
this will create an image alias to image
image-name
.
push an image to dockerhub repository
docker push docker-id/image-name
pull any public image
docker pull docker-id/image-name
A container can be used as database like mySQL or mongodb;
But the problem is, once you stop the container; all it's runtime data gets erased. To overcome this problem, docker introduced the concept of volumes.
volume
: It's a persistent memory shared b/w containers and is located on your machine, managed by docker.
network
: It's user defined bridge newtwork that our application and database will use to talk to each other.
Let's setup mongodb database in a container with appropriate volumes to persist it's data over multiple runs;
- create volumes
- we'll create 2 volumes, one for data and other for configuration of MongoDB.
$ docker volume create mongodb
$ docker volume create mongodb_config
- create network, It'll let our app and mongodb container talk to each other.
$ docker newtwork create mongodb
- run MongoDB in a container and attach to volumes and network that we've created above.
- docker will pull the image from hub and run it locally.
$ docker run -it --rm -d -v mongodb:/data/db \
-v mongodb_config:/data/configdb \
-p 26016:26016 \
--network mongodb \
--name mongodb \
mongo