@@@@@@@@@@@@@@@@@@@@@@@@@@@ Date: 11-Nov-2024 Topic : Docker Introduction @@@@@@@@@@@@@@@@@@@@@@@@@@@ ========================== Application Architecture ========================== => Application will be developed with 3 layers 1) Frontend (User interface) 2) Backend (business logic) 3) Database (storage) ======================= Application Tech Stack ======================= Project-1 : Angular + Java + Oracle DB Project-2 : React JS + Java + MySQL DB Project-3 : React JS + Node JS + Mongo DB Project-4 : Angular + .Net + SQL Server Project-4 : React JS + Python + MySQL DB If we want to run application in any machine then we have to install all the required softwares with proper version compatability. Ex: Angular 17v, Java 11v, Tomcat 9.0v, MySQL 8.5v Note: If we do any mistake in s/w installations then application can't execute. => If we want to test our application in multiple machines then installing all the required softwares in all those machines is time taking process and risky process. => To simplify application execution process in any machine we will use Docker. =============== What is Docker =============== => It is free and open source s/w. => Docker is used for containerization. Note: Containerization is the process of packaging "application code + application dependencies as single unit for execution". => Using docker, we can run our application in machine without bothering about softwares installation. Note : Docker will take care of s/w installation required to run our application. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Date: 12-Nov-2024 Topic : Docker Architecture + Docker Commands @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ==================== Docker Architecture ==================== 1) Dockerfile 2) Docker Image 3) Docker Container 4) Docker Hub => Dockerfile contains set of instructions to build docker image. => Docker Image is a package which contains "code + dependencies" for execution. Note: When we run Docker Image then Docker container will be created. => Docker Container is a virtual machine, in that our app will execute. => Docker Hub is a registry which is used to store our docker images. ============== Docker Setup ============== https://github.com/ashokitschool/DevOps-Documents/blob/main/02-Docker-Setup.md ================= Docker Commands ================= docker images : Display list of images available in our machine docker ps : Display Running containers docker ps -a : Display stopped containers docker rmi : Remove image from machine docker rm : Remove stopped container docker pull : Download docker image docker run : To create docker container docker stop : Stop the running container docker start : Start the container which got stopped docker system prune -a : Remove stopped containers + un-used images @@@@@@@@@@@@@@@@@@@@@@@@@@@ Date: 13-Nov-2024 Topic : Docker Containers @@@@@@@@@@@@@@@@@@@@@@@@@@@ ############ 1) What is detached mode ? ########### => It is used to created in background. It will allow us to run commands in terminal. Ex : docker run -d ashokit/spring-boot-rest-api ############ 2) What is port mapping ? ############### => It is used to map container port number to host machine port number => Once we perform port mapping then we can access our application which is running inside the container by using host machine public address. Syntax : docker run -d -p Ex : docker run -d -p 9090:9090 ashokit/spring-boot-rest-api Note: To access our application we need to enable HOST PoRT in security group inbound rules. App URL : http://public-ip:host-port/welcome/raja Note: If we are using docker in windows machine instead of public we can use localhost in the url. ============ Dockerfile ============ => Dockerfile contains set of instructions to create docker image. => In Dockerfile we will add below details a) Application Dependencies b) Application Execution Process => To write Dockerfile we will use below keywords 1) FROM 2) MAINTAINER 3) RUN 4) CMD 5) COPY 6) ADD 7) WORKDIR 8) EXPOSE 9) ENTRYPOINT 10) USER Note: Dockerfile will be saved with a name "Dockerfile" (no extension). @@@@@@@@@@@@@@@@@@@@@@@@@@@ Date: 14-Nov-2024 Topic : Docker File @@@@@@@@@@@@@@@@@@@@@@@@@@@ ## FROM : It is used to specify base image to create our image. Ex: FROM openjdk:17 FROM python:3.9 FROM tomcat:9.0 FROM node:latest Note: Base images we can find in docker hub. ## MAINTAINER : It is used to specify author of dockerfile (optional) Ex: MAINTAINER Ashok(13247979) ## RUN : It is used to specify instructions which will execute when docker image is getting created. Ex: RUN git clone RUN mvn clean package Note: We can write multiple RUN instructions in dockerfile, they will execute in sequential order. ## CMD : It is used to specify instructions which will execute when docker container is getting created. Note: CMD is used to run our application inside container. Note: We can write multiple CMD instructions in dockerfile, but docker will execute only last CMD instruction. ## ENTRYPOINT : It is used to execute instructions while container getting created. Ex: ENTRYPOINT [java -jar app.jar] Note: CMD instructions we can override while running docker image where as ENTRYPOINT instructions we can't override. ## COPY : It is used to copy the files from HOST machine to container machine. Ex: COPY target/app.war /usr/local/tomcat/webapps/app.war ## ADD : It is used to copy the files from HOST machine to container machine. Ex: ADD ## WORKDIR : It is used to set working directory while executing dockerfile. Ex: WORKDIR /usr/app/ ## EXPOSE : It is used to specify container running on which port number. It is only used for readability and it is optional to mention in dockerfile. EX: EXPOSE 9090 ## USER : It is used to specify with which user account we want to use to execute dockerfile instructions. Ex: USER devopsuser =================== FROM ubuntu MAINTAINER Ashok RUN echo 'hi - run-1' RUN echo 'hello - run-2' CMD echo 'Hi - cmd1' CMD echo 'hello - cmd2' ======================== $ docker images $ docker system prune -a $ docker build -t . Ex : docker build -t . $ docker images $ docker run $ docker login Note: Need to enter docker hub account credentials. $ docker push @@@@@@@@@@@@@@@@@@@@@@@@@@@ Date: 15-Nov-2024 Topic : Writing Dockerfile @@@@@@@@@@@@@@@@@@@@@@@@@@@ ========================================================== Dockerizing Java web application (without springboot) =========================================================== => Java web applications (without springboot) will be packaged as war file. => To run war file we need a webserver like apache Tomcat. => Inside tomcat server "webapps" folder will be available to deploy war files. Note: We need to copy project war file to tomcat server webapps folder for execution. ------------------------------------------------------------------------ FROM tomcat:latest EXPOSE 8080 COPY target/maven-web-app.war /usr/local/tomcat/webapps/ ------------------------------------------------------------------------- @@ Maven Web App Git Repo : https://github.com/ashokitschool/maven-web-app.git Note: If you are using docker in linux vm then install git and maven softwares $ sudo yum install git -y $ sudo yum install maven -y # clone git repo git clone https://github.com/ashokitschool/maven-web-app.git # Perform maven build cd maven-web-app mvn clean package Note: After maven package it will generate war file inside target directory. # check targer directory content ls -l target # create docker image docker build -t app1 . # Check docker images docker images # Run container docker run -d -p 8080:8080 app1 Note: Enable 8080 port number in security group inbound rules. # Access application in browser URL : http://public-ip:8080/maven-web-app/ ========================================= Dockerizing Java Spring Boot Application ========================================= => Every SpringBoot application will be packaged as jar file only => To run spring boot application we need to execute jar file. Syntax : java -jar Note: When we run springboot application jar file then springboot will start tomcat server with 8080 port number (embedded tomcat server). =============== Dockerfile for Spring Boot Application ============= FROM openjdk:17 MAINTAINER Ashok COPY target/app.jar /usr/app/ WORKDIR /usr/app/ EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"] ==================================================================== ## Java Spring Boot App Git Repo : https://github.com/ashokitschool/spring-boot-docker-app.git $ git clone https://github.com/ashokitschool/spring-boot-docker-app.git $ cd spring-boot-docker-app $ mvn clean package $ ls -l target $ docker build -t sb-app . $ docker run -d -p 8080:8080 sb-app Note: Once container created check logs of container $ docker logs Note: Access our application using host-vm public and host port URL : http://localhost:host-port/ ===================================== Dockerize Python Flask Application ===================================== => Python is a scripting language => We don't need any build tool for python app => Directley we can run python programs Ex : python app.py => Flask is a python library which is to develop rest apis in python. => To download flask library we will use 'python pip software' Note: We will configure dependencies in "requirements.txt" =============== Dockerfile for Python Flask App ================= FROM python:3.6 MAINTAINER Ashok COPY . /usr/app/ WORKDIR /usr/app/ RUN pip install -r requirements.txt EXPOSE 5000 ENTRYPOINT ["python", "app.py"] =================================================================== Python App Git Repo : https://github.com/ashokitschool/python-flask-docker-app.git $ git clone https://github.com/ashokitschool/python-flask-docker-app.git $ cd python-flask-docker-app $ docker build -t . $ docker run -d -p 5000:5000 $ docker ps Note: Enable 5000 port in security group inbound rules. => Access application with URL URL : http://public-ip:host-port/ @@@@@@@@@@@@@@@@@@@@@@@@@@@ Date: 19-Nov-2024 Topic : Docker Projects @@@@@@@@@@@@@@@@@@@@@@@@@@@ ================================= Dockerizing Angular application ================================= => Angular is a frontend framework => Angular is used to develop frontend of the applications Note: Angular developed by google company. => We will use Node Package Manager( NPM ) to build angular applications Note: When we build angular app it will generate "dist" folder for deployment => To run angular app we can copy "dist" folder data to "Nginx" server. -------------- FROM node:18 AS build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build --prod FROM nginx:alpine COPY --from=build /app/dist/angular_docker_app /usr/share/nginx/html EXPOSE 80 -------------------- git clone https://github.com/ashokitschool/angular_docker_app.git cd angular_docker_app docker build -t ngapp . docker images docker run -d -p 80:80 ngapp Note: Enable 80 port number in security group inbound rules. => Access application in browser using docker-server public ip address URL : http://13.200.252.152/ ================================= Dockerizing React JS application ================================= => React JS is a Java Script library it is used to develop frontend of the applications. Note: React JS developed by facebook. => We will use Node Package Manager( NPM ) to build react applications Note: When we build react app it will generate "build" folder for deployment. => To run angular app we can copy "build" folder data to "Nginx" server. -------------- FROM node:18 AS build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build --prod FROM nginx:alpine COPY --from=build app/build /usr/share/nginx/html EXPOSE 80 -------------------- git clone https://github.com/ashokitschool/ReactJS_Docker_App.git cd ReactJS_Docker_App docker build -t reactapp . docker images docker run -d -p 80:80 reactapp Note: Enable 80 port number in security group inbound rules. => Access application in browser using docker-server public ip address URL : http://13.200.252.152/ ================ Docker Network ================ => Network is all about communication => Docker network is used to provide isolated network for containers. => If we want to access one docker container from another docker container then those 2 containers should run on the same network. => By default we have 3 networks in the docker 1) bridge 2) host 3) none => Bridge network is used to run standalone containers. It will assign one IP address for the container. It is the default network used by docker container. => Host network is used to run standalone containers. This will not assign any ip address for the container. => None means no network will be provided. # display docker networks docker network ls # create docker network docker network create ashokit-nw # inspect docker network docker network inspect ashokit-nw # run docker container with custom network docker run -d -p 8080:8080 --network ashokit-nw ashokit/java-web-app # delete network docker network rm ashokit-nw ================= Docker Compose ================= => Earlier companies used to develop applications using Monolithic architecture (everything in single application). => Now a days companies are using Microservices architecture to develop the applications. => Microservices means we will have multiple backend apis and every backend api is a seperate project. a) hotels-api b) flights-api c) trains-api d) cabs-api => For every backend api seperate dockerfile will be available and we need to create seperate docker image for every api. => In order to deploy our application we need to manage multiple containers. => When we have multiple containers then managing them will be difficult (create/start/stop/re-start). => To overcome these management problems we will use Docker Compose. => Docker Compose is used to manage multi-container based applications. => using docker-compose with single command we can "create/stop/start/delete" multiple containers. => which containers should be managed by docker-compose we will configure that information in docker-compose.yml file. ============================= What is docker-compose.yml ? ============================= => It is used to specify containers information. => The default file name is "docker-compose.yml" => docker-compose yml contains 4 sections version : Represents compose yml version services : Represents containers information(image, port no) networks : Represents docker network to run containers volumes : Represents storage for containers ===================== Docker Compose Setup ===================== https://github.com/ashokitschool/DevOps-Documents/blob/main/03-Docker-Compose-Setup.md =============================================== Spring Boot with MySQL DB using Docker-Compose =============================================== version: "3" services: application: image: spring-boot-mysql-app ports: - "8080:8080" networks: - springboot-db-net depends_on: - mysqldb volumes: - /data/springboot-app mysqldb: image: mysql:5.7 networks: - springboot-db-net environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=sbms volumes: - /data/mysql networks: springboot-db-net: =============================== Application Execution Process =============================== # clone git repo git clone https://github.com/ashokitschool/spring-boot-mysql-docker-compose.git #go inside project directory cd spring-boot-mysql-docker-compose # build project mvn clean package # create docker image docker build -t spring-boot-mysql-app . # check docker images docker images # create containers using docker-compose docker-compose up -d # stop containers using docker-compose docker-compose stop # start containers using docker-compose docker-compose start # delete containers using docker-compose docker-compose down ============================================= Stateless Containers vs Statefull Containers ============================================= Stateless Container : Data will be deleted after container deletion Statefull Container : Data will be available permanentley. Note: Docker containers are by default stateless. Note: In above example when we delete and re-create containers we lost data that we inserted in application. This is not accepted in the real-time. => In order to maintain containers data we will use Docker Volumes concept. => Using Docker Volumes concept, we can make docker container as statefull container. ===================================== Making docker container as stateful ===================================== => Map ".app" directory to database container as a bind mount volume. version: "3" services: application: image: spring-boot-mysql-app ports: - "8080:8080" networks: - springboot-db-net depends_on: - mysqldb volumes: - /data/springboot-app mysqldb: image: mysql:5.7 networks: - springboot-db-net environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=sbms volumes: - .app:/var/lib/mysql networks: springboot-db-net: ========== Summary ========== 1) What are the challenges in app deployment process 2) Containerization 3) Docker Introduction 4) Docker Architecture 5) Docker Setup in windows & linux 6) Docker Registry (docker hub) 7) Docker Images 8) Docker Containers 9) Dockerfile 10) Dockerize java web app with tomcat 11) Dockerize java springboot app 12) Dockerize python flask app 13) Dockerize angular app 14) Dockerize react app 15) Docker Network 16) Docker Compose 17) Docker Volumes 18) Docker Swarm