https://github.com/mugilan-codes/node-devops-docker-demo
https://github.com/mugilan-codes/node-devops-docker-demo
devops docker docker-compose dockerfile droplet expressjs mongodb mongoose nginx redis
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/mugilan-codes/node-devops-docker-demo
- Owner: Mugilan-Codes
- Created: 2021-05-24T07:53:37.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2021-06-14T05:54:00.000Z (over 4 years ago)
- Last Synced: 2025-06-05T12:08:26.163Z (4 months ago)
- Topics: devops, docker, docker-compose, dockerfile, droplet, expressjs, mongodb, mongoose, nginx, redis
- Language: JavaScript
- Homepage:
- Size: 228 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# node-devops-docker-demo
## Practicing Node Devops with Docker
[Devops with Docker and Node.js Youtube Playlist](https://www.youtube.com/playlist?list=PL8VzFQ8k4U1JEu7BLraz8MdKJILJir7oY)
### Resource
- [Nginx and Let’s Encrypt with Docker in Less Than 5 Minutes](https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71)
- [Setup Nginx and Let’s Encrypt with Docker](https://www.thirdrocktechkno.com/blog/setup-nginx-and-lets-encrypt-with-docker/)
- [Docker compose of nginx, express, letsencrypt SSL get 502 Bad gateway](https://stackoverflow.com/questions/57743088/docker-compose-of-nginx-express-letsencrypt-ssl-get-502-bad-gateway)### Commands
- Build App Image
```sh
docker build -t node-devops-docker-demo-image .
```- Run a Container (port fowarding, bind mount(read-only), and anonymous volume)
```sh
docker run -v $(pwd):/app:ro -v /app/node_modules -p 3000:4000 --env-file ./.env -d --name node-devops-docker-demo node-devops-docker-demo-image
```- Access FileSystem
```sh
docker exec -it node-devops-docker-demo bash
```- Exit FileSystem
```sh
exit
```- Forcefully Remove a container with volume
```sh
docker rm node-devops-docker-demo -fv
```- Using Docker Compose
- Build App
```sh
docker-compose up -d
```
- use this if there is a change in image (Dockerfile)```sh
docker-compose up -d --build
```- Delete App
```sh
docker-compose down -v
```- Development docker-compose command
- up
```sh
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d# force re-build image for changes
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build# re-build image without downing the container and re creating anonymous volumes
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build -V# scale the number of instances
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --scale node-app=2
```- down
```sh
docker-compose -f docker-compose.yml -f docker-compose.dev.yml down -v# don't remove volumes
docker-compose -f docker-compose.yml -f docker-compose.dev.yml down
```- Production docker-compose command
- up
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d# force re-build image for changes
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
```- down
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml down -v# don't remove volumes
docker-compose -f docker-compose.yml -f docker-compose.prod.yml down
```- Open MongoDB directly
```sh
docker exec -it node-devops-docker-demo_mongodb_1 mongo -u "mugil" -p "mypassword"
```**note**: Don't pass in `-v` flag to remove the volumes when using databases as it would ultimately remove all volumes, Instead start up the containers and run `docker volume prune` to remove unused volumes.
- Get network details of container
```sh
docker inspect
```**note**: you can directly use the service name from docker-compose instead of using the ipAddress(works only for the services created/declared in docker-compose).
- Open Redis CLI
```sh
docker exec -it node-devops-docker-demo_redis_1 redis-cli
```- View Session Keys
```sh
KEYS *
```- Get Session Details
```sh
GET
```### Steps to Production
- Create Ubuntu Server on Cloud Platforms like **Digital Ocean** (I am using this one), AWS, etc..
- Create a Droplet
- Copy the IP Address of the Droplet provided
- Open a terminal in your computer and SSH into the droplet```sh
ssh root@
```- Type in `yes` to conntinue connecting
- Type in your root password that you used while creating the droplet
- Install docker engine in the droplet```sh
curl -fsSL https://get.docker.com -o get-docker.shsh get-docker.sh
```- Install docker-compose by following instructions in the official documentation for linux
```sh
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose
```- Set Environment Variables
```sh
export =
```- Show all Env variables
```sh
printenv
```- Instead of individually adding env variables, setup .env file and add the .env variables into it
```sh
vi .env
```- Open `.profile` and add this at the bottom
```sh
vi .profile
``````vim
set -o allexport; source /root/.env; set +o allexport
```- Create a directory and move into it
```sh
mkdir appcd app
```- Clone the Git repo in this folder and pull whenever there is a change
```sh
git clone .
```**Note**: This works with public repo. If you want to work with private repos, check [Deploy Keys](https://docs.github.com/en/developers/overview/managing-deploy-keys) section or [How to clone your private repository from GitHub to server, Droplet, VDS, etc?](https://dev.to/koddr/quick-how-to-clone-your-private-repository-from-github-to-server-droplet-vds-etc-39jm)
- Run the production docker-compose command
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d# do this to see any changes made
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build# rebuild only necessary service to avoid checking other containers unneccessarily
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build node-app# when you don't want to check for dependencies
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build --no-deps node-app# force rebuild containers even when there is no change
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --force-recreate node-app# force rebuild containers even when there is no change without dependecies
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --force-recreate --no-deps node-app
```- Make requests to `http:///` routes
- Push Images to docker to avoid building images on production server. Create a repo in `dockerhub`
- Tag the local image with the name of that of the remote image
```sh
docker tag
```- Push the tagged image to dockerhub
```sh
docker push
```- Build the image on local machine
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml build# build only the services that is required (custom image)
docker-compose -f docker-compose.yml -f docker-compose.prod.yml build node-app
```- Push the custom build image to dockerhub
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml push# push only the services that we want
docker-compose -f docker-compose.yml -f docker-compose.prod.yml push node-app
```- Pull the latest images in the production server
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull# only specific image
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull node-app
```- Update the changes in producton server
```sh
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d# specific rebuild
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --no-deps node-app
```- Use watchtower to automatically look for changes in the remote custom build image (specify the images that needs to be watched at the end)
```sh
docker run -d --name watchtower -e WATCHTOWER_TRACE=true -e WATCHTOWER_DEBUG=true -e WATCHTOWER_POLL_INTERVAL=50 -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower app_node-app_1
```**NOTE**: No need to pull and update changes in production server if watchtower is used
- Activate docker swarm for orchestration. Get IP of the droplet by `ip add` command
```sh
docker swarm init --advertise-addr
```- Add more manager nodes, run this command and follow the instructions
```sh
docker swarm join-token manager
```- Add worker node to swarm
```sh
docker swarm join --token :
```- Deploy
```sh
docker stack deploy -c docker-compose.yml -c docker-compose.prod.yml myapp
```- check how many nodes are running
```sh
docker node ls
```- check how many stacks are there
```sh
docker stack ls
```- list the services in the stack
```sh
docker stack services myapp
```- list all the services across all stacks
```sh
docker service ls
```- list the tasks in the stack
```sh
docker stack ps myapp
```#### TODO
- [X] Add SSL Certificate (https)
- [X] Add Domain Name
- [ ] Modify ./init-letsencrypt.sh to use docker swarm and production docker compose
- [ ] Run the modified ./init-letsencrypt.sh on the server for first time to generate fake certificates
- [ ] Everything must be automated
#### Docker Images
- [node](https://hub.docker.com/_/node)
- [mongo](https://hub.docker.com/_/mongo)
- [redis](https://hub.docker.com/_/redis)
- [nginx](https://hub.docker.com/_/nginx)#### DOCS
- [Express behind proxies](https://expressjs.com/en/guide/behind-proxies.html)
- [Docker Script for Ubuntu](https://get.docker.com/)
- [Install Docker Compose](https://docs.docker.com/compose/install/)
- [Watchtower](https://containrrr.dev/watchtower/)
- [Docker Compose Deploy Reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#deploy)