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: 8 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 (8 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.sh
sh 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-compose
sudo 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 app
cd 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)