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 ofxyzfrom docker repo.- also
xyz:12.2.3is an option, to use specific version of that image.
- also
-
RUN: is to execute commands during building the image. you can use multipleRUNinDockerfile- 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
.dockerignorefile; it works exactly as.gitignorefile.
Now let's build an image:
- go to same directory as
Dockerfileand 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 imagesnow 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-namethis 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-namethis command will create a docker container named todo and run it.
-
-p 80:3000: exposing container's port3000to local machine on port80 -
-d: dispatch means run in background.
Start same container next time,
docker start container-nameStop a container
docker stop container-nameList of all running containers
docker psList of all containers
docker ps -aLogs of continer
docker logs container-nameContinous logs of container
docker logs container-name -fRemove a container
docker rm container-nameremove an image
docker rmi image-namechange tag of image
docker tag image-name docker-id/image-namethis will create an image alias to image
image-name.
push an image to dockerhub repository
docker push docker-id/image-namepull any public image
docker pull docker-id/image-nameA 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