├── README.md ├── commands.md ├── examples ├── first-docker-file │ ├── Dockerfile │ └── app.py ├── golang-multi-stage-docker-build │ ├── Dockerfile │ ├── README.md │ ├── calculator.go │ └── dockerfile-without-multistage │ │ ├── Dockerfile │ │ └── calculator.go └── python-web-app │ ├── Dockerfile │ ├── devops │ ├── db.sqlite3 │ ├── demo │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-310.pyc │ │ │ ├── urls.cpython-310.pyc │ │ │ └── views.cpython-310.pyc │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── templates │ │ │ └── demo_site.html │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── devops │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-310.pyc │ │ │ ├── settings.cpython-310.pyc │ │ │ ├── urls.cpython-310.pyc │ │ │ └── wsgi.cpython-310.pyc │ │ ├── asgi.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ └── manage.py │ └── requirements.txt ├── networking.md └── volumes.md /README.md: -------------------------------------------------------------------------------- 1 | # Repo to learn Docker with examples. Contributions are most welcome. 2 | 3 | ## If you found this repo useful, give it a STAR 🌠 4 | 5 | You can watch the video version of this repo on my youtube playlist. -> https://www.youtube.com/watch?v=7JZP345yVjw&list=PLdpzxOOAlwvLjb0vTD9BXLOwwLD_GWCmC 6 | 7 | 8 | ## What is a container ? 9 | 10 | A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. 11 | 12 | Ok, let me make it easy !!! 13 | 14 | A container is a bundle of Application, Application libraries required to run your application and the minimum system dependencies. 15 | 16 | ![Screenshot 2023-02-07 at 7 18 10 PM](https://user-images.githubusercontent.com/43399466/217262726-7cabcb5b-074d-45cc-950e-84f7119e7162.png) 17 | 18 | 19 | 20 | ## Containers vs Virtual Machine 21 | 22 | Containers and virtual machines are both technologies used to isolate applications and their dependencies, but they have some key differences: 23 | 24 | 1. Resource Utilization: Containers share the host operating system kernel, making them lighter and faster than VMs. VMs have a full-fledged OS and hypervisor, making them more resource-intensive. 25 | 26 | 2. Portability: Containers are designed to be portable and can run on any system with a compatible host operating system. VMs are less portable as they need a compatible hypervisor to run. 27 | 28 | 3. Security: VMs provide a higher level of security as each VM has its own operating system and can be isolated from the host and other VMs. Containers provide less isolation, as they share the host operating system. 29 | 30 | 4. Management: Managing containers is typically easier than managing VMs, as containers are designed to be lightweight and fast-moving. 31 | 32 | 33 | 34 | ## Why are containers light weight ? 35 | 36 | Containers are lightweight because they use a technology called containerization, which allows them to share the host operating system's kernel and libraries, while still providing isolation for the application and its dependencies. This results in a smaller footprint compared to traditional virtual machines, as the containers do not need to include a full operating system. Additionally, Docker containers are designed to be minimal, only including what is necessary for the application to run, further reducing their size. 37 | 38 | Let's try to understand this with an example: 39 | 40 | Below is the screenshot of official ubuntu base image which you can use for your container. It's just ~ 22 MB, isn't it very small ? on a contrary if you look at official ubuntu VM image it will be close to ~ 2.3 GB. So the container base image is almost 100 times less than VM image. 41 | 42 | ![Screenshot 2023-02-08 at 3 12 38 PM](https://user-images.githubusercontent.com/43399466/217493284-85411ae0-b283-4475-9729-6b082e35fc7d.png) 43 | 44 | 45 | To provide a better picture of files and folders that containers base images have and files and folders that containers use from host operating system (not 100 percent accurate -> varies from base image to base image). Refer below. 46 | 47 | 48 | 49 | ### Files and Folders in containers base images 50 | 51 | ``` 52 | /bin: contains binary executable files, such as the ls, cp, and ps commands. 53 | 54 | /sbin: contains system binary executable files, such as the init and shutdown commands. 55 | 56 | /etc: contains configuration files for various system services. 57 | 58 | /lib: contains library files that are used by the binary executables. 59 | 60 | /usr: contains user-related files and utilities, such as applications, libraries, and documentation. 61 | 62 | /var: contains variable data, such as log files, spool files, and temporary files. 63 | 64 | /root: is the home directory of the root user. 65 | ``` 66 | 67 | 68 | 69 | ### Files and Folders that containers use from host operating system 70 | 71 | ``` 72 | The host's file system: Docker containers can access the host file system using bind mounts, which allow the container to read and write files in the host file system. 73 | 74 | Networking stack: The host's networking stack is used to provide network connectivity to the container. Docker containers can be connected to the host's network directly or through a virtual network. 75 | 76 | System calls: The host's kernel handles system calls from the container, which is how the container accesses the host's resources, such as CPU, memory, and I/O. 77 | 78 | Namespaces: Docker containers use Linux namespaces to create isolated environments for the container's processes. Namespaces provide isolation for resources such as the file system, process ID, and network. 79 | 80 | Control groups (cgroups): Docker containers use cgroups to limit and control the amount of resources, such as CPU, memory, and I/O, that a container can access. 81 | 82 | ``` 83 | 84 | It's important to note that while a container uses resources from the host operating system, it is still isolated from the host and other containers, so changes to the container do not affect the host or other containers. 85 | 86 | **Note:** There are multiple ways to reduce your VM image size as well, but I am just talking about the default for easy comparision and understanding. 87 | 88 | so, in a nutshell, container base images are typically smaller compared to VM images because they are designed to be minimalist and only contain the necessary components for running a specific application or service. VMs, on the other hand, emulate an entire operating system, including all its libraries, utilities, and system files, resulting in a much larger size. 89 | 90 | I hope it is now very clear why containers are light weight in nature. 91 | 92 | 93 | 94 | ## Docker 95 | 96 | 97 | ### What is Docker ? 98 | 99 | Docker is a containerization platform that provides easy way to containerize your applications, which means, using Docker you can build container images, run the images to create containers and also push these containers to container regestries such as DockerHub, Quay.io and so on. 100 | 101 | In simple words, you can understand as `containerization is a concept or technology` and `Docker Implements Containerization`. 102 | 103 | 104 | ### Docker Architecture ? 105 | 106 | ![image](https://user-images.githubusercontent.com/43399466/217507877-212d3a60-143a-4a1d-ab79-4bb615cb4622.png) 107 | 108 | The above picture, clearly indicates that Docker Deamon is brain of Docker. If Docker Deamon is killed, stops working for some reasons, Docker is brain dead :p (sarcasm intended). 109 | 110 | ### Docker LifeCycle 111 | 112 | We can use the above Image as reference to understand the lifecycle of Docker. 113 | 114 | There are three important things, 115 | 116 | 1. docker build -> builds docker images from Dockerfile 117 | 2. docker run -> runs container from docker images 118 | 3. docker push -> push the container image to public/private regestries to share the docker images. 119 | 120 | ![Screenshot 2023-02-08 at 4 32 13 PM](https://user-images.githubusercontent.com/43399466/217511949-81f897b2-70ee-41d1-b229-38d0572c54c7.png) 121 | 122 | 123 | 124 | ### Understanding the terminology (Inspired from Docker Docs) 125 | 126 | 127 | #### Docker daemon 128 | 129 | The Docker daemon (dockerd) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes. A daemon can also communicate with other daemons to manage Docker services. 130 | 131 | 132 | #### Docker client 133 | 134 | The Docker client (docker) is the primary way that many Docker users interact with Docker. When you use commands such as docker run, the client sends these commands to dockerd, which carries them out. The docker command uses the Docker API. The Docker client can communicate with more than one daemon. 135 | 136 | 137 | #### Docker Desktop 138 | 139 | Docker Desktop is an easy-to-install application for your Mac, Windows or Linux environment that enables you to build and share containerized applications and microservices. Docker Desktop includes the Docker daemon (dockerd), the Docker client (docker), Docker Compose, Docker Content Trust, Kubernetes, and Credential Helper. For more information, see Docker Desktop. 140 | 141 | 142 | #### Docker registries 143 | 144 | A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. You can even run your own private registry. 145 | 146 | When you use the docker pull or docker run commands, the required images are pulled from your configured registry. When you use the docker push command, your image is pushed to your configured registry. 147 | Docker objects 148 | 149 | When you use Docker, you are creating and using images, containers, networks, volumes, plugins, and other objects. This section is a brief overview of some of those objects. 150 | 151 | 152 | #### Dockerfile 153 | 154 | Dockerfile is a file where you provide the steps to build your Docker Image. 155 | 156 | 157 | #### Images 158 | 159 | An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. For example, you may build an image which is based on the ubuntu image, but installs the Apache web server and your application, as well as the configuration details needed to make your application run. 160 | 161 | You might create your own images or you might only use those created by others and published in a registry. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it. Each instruction in a Dockerfile creates a layer in the image. When you change the Dockerfile and rebuild the image, only those layers which have changed are rebuilt. This is part of what makes images so lightweight, small, and fast, when compared to other virtualization technologies. 162 | 163 | 164 | 165 | ## INSTALL DOCKER 166 | 167 | A very detailed instructions to install Docker are provide in the below link 168 | 169 | https://docs.docker.com/get-docker/ 170 | 171 | For Demo, 172 | 173 | You can create an Ubuntu EC2 Instance on AWS and run the below commands to install docker. 174 | 175 | ``` 176 | sudo apt update 177 | sudo apt install docker.io -y 178 | ``` 179 | 180 | 181 | ### Start Docker and Grant Access 182 | 183 | A very common mistake that many beginners do is, After they install docker using the sudo access, they miss the step to Start the Docker daemon and grant acess to the user they want to use to interact with docker and run docker commands. 184 | 185 | Always ensure the docker daemon is up and running. 186 | 187 | A easy way to verify your Docker installation is by running the below command 188 | 189 | ``` 190 | docker run hello-world 191 | ``` 192 | 193 | If the output says: 194 | 195 | ``` 196 | docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied. 197 | See 'docker run --help'. 198 | ``` 199 | 200 | This can mean two things, 201 | 1. Docker deamon is not running. 202 | 2. Your user does not have access to run docker commands. 203 | 204 | 205 | ### Start Docker daemon 206 | 207 | You use the below command to verify if the docker daemon is actually started and Active 208 | 209 | ``` 210 | sudo systemctl status docker 211 | ``` 212 | 213 | If you notice that the docker daemon is not running, you can start the daemon using the below command 214 | 215 | ``` 216 | sudo systemctl start docker 217 | ``` 218 | 219 | 220 | ### Grant Access to your user to run docker commands 221 | 222 | To grant access to your user to run the docker command, you should add the user to the Docker Linux group. Docker group is create by default when docker is installed. 223 | 224 | ``` 225 | sudo usermod -aG docker ubuntu 226 | ``` 227 | 228 | In the above command `ubuntu` is the name of the user, you can change the username appropriately. 229 | 230 | **NOTE:** : You need to logout and login back for the changes to be reflected. 231 | 232 | 233 | ### Docker is Installed, up and running 🥳🥳 234 | 235 | Use the same command again, to verify that docker is up and running. 236 | 237 | ``` 238 | docker run hello-world 239 | ``` 240 | 241 | Output should look like: 242 | 243 | ``` 244 | .... 245 | .... 246 | Hello from Docker! 247 | This message shows that your installation appears to be working correctly. 248 | ... 249 | ... 250 | ``` 251 | 252 | 253 | ## Great Job, Now start with the examples folder to write your first Dockerfile and move to the next examples. Happy Learning :) 254 | 255 | ### Clone this repository and move to example folder 256 | 257 | ``` 258 | git clone https://github.com/iam-veeramalla/Docker-Zero-to-Hero 259 | cd examples 260 | ``` 261 | 262 | ### Login to Docker [Create an account with https://hub.docker.com/] 263 | 264 | ``` 265 | docker login 266 | ``` 267 | 268 | ``` 269 | Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. 270 | Username: abhishekf5 271 | Password: 272 | WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json. 273 | Configure a credential helper to remove this warning. See 274 | https://docs.docker.com/engine/reference/commandline/login/#credentials-store 275 | 276 | Login Succeeded 277 | ``` 278 | 279 | ### Build your first Docker Image 280 | 281 | You need to change the username accoringly in the below command 282 | 283 | ``` 284 | docker build -t abhishekf5/my-first-docker-image:latest . 285 | ``` 286 | 287 | Output of the above command 288 | 289 | ``` 290 | Sending build context to Docker daemon 992.8kB 291 | Step 1/6 : FROM ubuntu:latest 292 | latest: Pulling from library/ubuntu 293 | 677076032cca: Pull complete 294 | Digest: sha256:9a0bdde4188b896a372804be2384015e90e3f84906b750c1a53539b585fbbe7f 295 | Status: Downloaded newer image for ubuntu:latest 296 | ---> 58db3edaf2be 297 | Step 2/6 : WORKDIR /app 298 | ---> Running in 630f5e4db7d3 299 | Removing intermediate container 630f5e4db7d3 300 | ---> 6b1d9f654263 301 | Step 3/6 : COPY . /app 302 | ---> 984edffabc23 303 | Step 4/6 : RUN apt-get update && apt-get install -y python3 python3-pip 304 | ---> Running in a558acdc9b03 305 | Step 5/6 : ENV NAME World 306 | ---> Running in 733207001f2e 307 | Removing intermediate container 733207001f2e 308 | ---> 94128cf6be21 309 | Step 6/6 : CMD ["python3", "app.py"] 310 | ---> Running in 5d60ad3a59ff 311 | Removing intermediate container 5d60ad3a59ff 312 | ---> 960d37536dcd 313 | Successfully built 960d37536dcd 314 | Successfully tagged abhishekf5/my-first-docker-image:latest 315 | ``` 316 | 317 | ### Verify Docker Image is created 318 | 319 | ``` 320 | docker images 321 | ``` 322 | 323 | Output 324 | 325 | ``` 326 | REPOSITORY TAG IMAGE ID CREATED SIZE 327 | abhishekf5/my-first-docker-image latest 960d37536dcd 26 seconds ago 467MB 328 | ubuntu latest 58db3edaf2be 13 days ago 77.8MB 329 | hello-world latest feb5d9fea6a5 16 months ago 13.3kB 330 | ``` 331 | 332 | ### Run your First Docker Container 333 | 334 | ``` 335 | docker run -it abhishekf5/my-first-docker-image 336 | ``` 337 | 338 | Output 339 | 340 | ``` 341 | Hello World 342 | ``` 343 | 344 | ### Push the Image to DockerHub and share it with the world 345 | 346 | ``` 347 | docker push abhishekf5/my-first-docker-image 348 | ``` 349 | 350 | Output 351 | 352 | ``` 353 | Using default tag: latest 354 | The push refers to repository [docker.io/abhishekf5/my-first-docker-image] 355 | 896818320e80: Pushed 356 | b8088c305a52: Pushed 357 | 69dd4ccec1a0: Pushed 358 | c5ff2d88f679: Mounted from library/ubuntu 359 | latest: digest: sha256:6e49841ad9e720a7baedcd41f9b666fcd7b583151d0763fe78101bb8221b1d88 size: 1157 360 | ``` 361 | 362 | ### You must be feeling like a champ already 363 | -------------------------------------------------------------------------------- /commands.md: -------------------------------------------------------------------------------- 1 | # Docker Commands 2 | 3 | Some of the most commonly used docker commands are 4 | 5 | ### docker images 6 | 7 | Lists docker images on the host machine. 8 | 9 | ### docker build 10 | 11 | Builds image from Dockerfile. 12 | 13 | ### docker run 14 | 15 | Runs a Docker container. 16 | 17 | There are many arguments which you can pass to this command for example, 18 | 19 | `docker run -d` -> Run container in background and print container ID 20 | `docker run -p` -> Port mapping 21 | 22 | use `docker run --help` to look into more arguments. 23 | 24 | ### docker ps 25 | 26 | Lists running containers on the host machine. 27 | 28 | ### docker stop 29 | 30 | Stops running container. 31 | 32 | ### docker start 33 | 34 | Starts a stopped container. 35 | 36 | ### docker rm 37 | 38 | Removes a stopped container. 39 | 40 | ### docker rmi 41 | 42 | Removes an image from the host machine. 43 | 44 | ### docker pull 45 | 46 | Downloads an image from the configured registry. 47 | 48 | ### docker push 49 | 50 | Uploads an image to the configured registry. 51 | 52 | ### docker exec 53 | 54 | Run a command in a running container. 55 | 56 | ### docker network 57 | 58 | Manage Docker networks such as creating and removing networks, and connecting containers to networks. 59 | -------------------------------------------------------------------------------- /examples/first-docker-file/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | # Set the working directory in the image 4 | WORKDIR /app 5 | 6 | # Copy the files from the host file system to the image file system 7 | COPY . /app 8 | 9 | # Install the necessary packages 10 | RUN apt-get update && apt-get install -y python3 python3-pip 11 | 12 | # Set environment variables 13 | ENV NAME World 14 | 15 | # Run a command to start the application 16 | CMD ["python3", "app.py"] 17 | -------------------------------------------------------------------------------- /examples/first-docker-file/app.py: -------------------------------------------------------------------------------- 1 | print("Hello World") 2 | -------------------------------------------------------------------------------- /examples/golang-multi-stage-docker-build/Dockerfile: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # BASE IMAGE 3 | ########################################### 4 | 5 | FROM ubuntu AS build 6 | 7 | RUN apt-get update && apt-get install -y golang-go 8 | 9 | ENV GO111MODULE=off 10 | 11 | COPY . . 12 | 13 | RUN CGO_ENABLED=0 go build -o /app . 14 | 15 | ############################################ 16 | # HERE STARTS THE MAGIC OF MULTI STAGE BUILD 17 | ############################################ 18 | 19 | FROM scratch 20 | 21 | # Copy the compiled binary from the build stage 22 | COPY --from=build /app /app 23 | 24 | # Set the entrypoint for the container to run the binary 25 | ENTRYPOINT ["/app"] 26 | 27 | -------------------------------------------------------------------------------- /examples/golang-multi-stage-docker-build/README.md: -------------------------------------------------------------------------------- 1 | # Multi Stage Docker Build 2 | 3 | The main purpose of choosing a golang based applciation to demostrate this example is golang is a statically-typed programming language that does not require a runtime in the traditional sense. Unlike dynamically-typed languages like Python, Ruby, and JavaScript, which rely on a runtime environment to execute their code, Go compiles directly to machine code, which can then be executed directly by the operating system. 4 | 5 | So the real advantage of multi stage docker build and distro less images can be understand with a drastic decrease in the Image size. 6 | -------------------------------------------------------------------------------- /examples/golang-multi-stage-docker-build/calculator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | fmt.Println("Hi Abhishek.Veeramalla, I am a calculator app ....") 13 | 14 | for { 15 | // Read input from the user 16 | reader := bufio.NewReader(os.Stdin) 17 | fmt.Print("Enter any calculation (Example: 1 + 2 (or) 2 * 5 -> Please maintain spaces as shown in example): ") 18 | text, _ := reader.ReadString('\n') 19 | 20 | // Trim the newline character from the input 21 | text = strings.TrimSpace(text) 22 | 23 | // Check if the user entered "exit" to quit the program 24 | if text == "exit" { 25 | break 26 | } 27 | 28 | // Split the input into two parts: the left operand and the right operand 29 | parts := strings.Split(text, " ") 30 | if len(parts) != 3 { 31 | fmt.Println("Invalid input. Try again.") 32 | continue 33 | } 34 | 35 | // Convert the operands to integers 36 | left, err := strconv.Atoi(parts[0]) 37 | if err != nil { 38 | fmt.Println("Invalid input. Try again.") 39 | continue 40 | } 41 | right, err := strconv.Atoi(parts[2]) 42 | if err != nil { 43 | fmt.Println("Invalid input. Try again.") 44 | continue 45 | } 46 | 47 | // Perform the calculation based on the operator 48 | var result int 49 | switch parts[1] { 50 | case "+": 51 | result = left + right 52 | case "-": 53 | result = left - right 54 | case "*": 55 | result = left * right 56 | case "/": 57 | result = left / right 58 | default: 59 | fmt.Println("Invalid operator. Try again.") 60 | continue 61 | } 62 | 63 | // Print the result 64 | fmt.Printf("Result: %d\n", result) 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /examples/golang-multi-stage-docker-build/dockerfile-without-multistage/Dockerfile: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # BASE IMAGE 3 | ########################################### 4 | 5 | FROM ubuntu AS build 6 | 7 | RUN apt-get update && apt-get install -y golang-go 8 | 9 | ENV GO111MODULE=off 10 | 11 | COPY . . 12 | 13 | RUN CGO_ENABLED=0 go build -o /app . 14 | 15 | ENTRYPOINT ["/app"] 16 | 17 | -------------------------------------------------------------------------------- /examples/golang-multi-stage-docker-build/dockerfile-without-multistage/calculator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | fmt.Println("Hi Abhishek.Veeramalla, I am a calculator app ....") 13 | 14 | for { 15 | // Read input from the user 16 | reader := bufio.NewReader(os.Stdin) 17 | fmt.Print("Enter any calculation (Example: 1 + 2 (or) 2 * 5 -> Please maintain spaces as shown in example): ") 18 | text, _ := reader.ReadString('\n') 19 | 20 | // Trim the newline character from the input 21 | text = strings.TrimSpace(text) 22 | 23 | // Check if the user entered "exit" to quit the program 24 | if text == "exit" { 25 | break 26 | } 27 | 28 | // Split the input into two parts: the left operand and the right operand 29 | parts := strings.Split(text, " ") 30 | if len(parts) != 3 { 31 | fmt.Println("Invalid input. Try again.") 32 | continue 33 | } 34 | 35 | // Convert the operands to integers 36 | left, err := strconv.Atoi(parts[0]) 37 | if err != nil { 38 | fmt.Println("Invalid input. Try again.") 39 | continue 40 | } 41 | right, err := strconv.Atoi(parts[2]) 42 | if err != nil { 43 | fmt.Println("Invalid input. Try again.") 44 | continue 45 | } 46 | 47 | // Perform the calculation based on the operator 48 | var result int 49 | switch parts[1] { 50 | case "+": 51 | result = left + right 52 | case "-": 53 | result = left - right 54 | case "*": 55 | result = left * right 56 | case "/": 57 | result = left / right 58 | default: 59 | fmt.Println("Invalid operator. Try again.") 60 | continue 61 | } 62 | 63 | // Print the result 64 | fmt.Printf("Result: %d\n", result) 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /examples/python-web-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | 3 | WORKDIR /app 4 | 5 | COPY requirements.txt /app/ 6 | COPY devops /app/ 7 | 8 | RUN apt-get update && apt-get install -y python3 python3-pip python3-venv 9 | 10 | SHELL ["/bin/bash", "-c"] 11 | 12 | RUN python3 -m venv venv1 && \ 13 | source venv1/bin/activate && \ 14 | pip install --no-cache-dir -r requirements.txt 15 | 16 | EXPOSE 8000 17 | 18 | CMD source venv1/bin/activate && python3 manage.py runserver 0.0.0.0:8000 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/db.sqlite3 -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/demo/__init__.py -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/demo/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/__pycache__/urls.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/demo/__pycache__/urls.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/__pycache__/views.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/demo/__pycache__/views.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class DemoConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'demo' 7 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/demo/migrations/__init__.py -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/templates/demo_site.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CSS Template 5 | 6 | 7 | 71 | 72 | 73 | 74 | 75 |
76 |

Free DevOps Course By Abhishek

77 |
78 | 79 |
80 | 87 | 88 |
89 |

Agenda

90 |

Learn DevOps with strong foundational knowledge and practical understanding

91 |

Please Share the Channel with your friends and colleagues

92 |
93 |
94 | 95 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | path('', views.index, name='index'), 7 | ] 8 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/demo/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | from django.shortcuts import render 3 | 4 | 5 | def index(request): 6 | return render(request, 'demo_site.html') 7 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/devops/__init__.py -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/devops/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/__pycache__/settings.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/devops/__pycache__/settings.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/__pycache__/urls.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/devops/__pycache__/urls.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/__pycache__/wsgi.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iam-veeramalla/Docker-Zero-to-Hero/f324152c83ec2ce7c0313e3dc170754e1dc75a0d/examples/python-web-app/devops/devops/__pycache__/wsgi.cpython-310.pyc -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for devops project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'devops.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for devops project. 3 | 4 | Generated by 'django-admin startproject' using Django 4.1.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/4.1/ref/settings/ 11 | """ 12 | 13 | import os 14 | from pathlib import Path 15 | 16 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 17 | BASE_DIR = Path(__file__).resolve().parent.parent 18 | 19 | 20 | # Quick-start development settings - unsuitable for production 21 | # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ 22 | 23 | # SECURITY WARNING: keep the secret key used in production secret! 24 | SECRET_KEY = 'django-insecure-js0^(n81j2j1@&5fn!a_jh92*_05id$3tegf@g8frdo!q$fdm*' 25 | 26 | # SECURITY WARNING: don't run with debug turned on in production! 27 | DEBUG = True 28 | 29 | ALLOWED_HOSTS = ['*'] 30 | 31 | 32 | # Application definition 33 | 34 | INSTALLED_APPS = [ 35 | 'django.contrib.admin', 36 | 'django.contrib.auth', 37 | 'django.contrib.contenttypes', 38 | 'django.contrib.sessions', 39 | 'django.contrib.messages', 40 | 'django.contrib.staticfiles', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'devops.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [os.path.join(BASE_DIR, 'demo/templates')], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'devops.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/4.1/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': BASE_DIR / 'db.sqlite3', 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/4.1/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_TZ = True 114 | 115 | 116 | # Static files (CSS, JavaScript, Images) 117 | # https://docs.djangoproject.com/en/4.1/howto/static-files/ 118 | 119 | STATIC_URL = 'static/' 120 | 121 | # Default primary key field type 122 | # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field 123 | 124 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 125 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/urls.py: -------------------------------------------------------------------------------- 1 | """devops URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/4.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | 19 | urlpatterns = [ 20 | path('demo/', include('demo.urls')), 21 | path('admin/', admin.site.urls), 22 | ] 23 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/devops/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for devops project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'devops.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /examples/python-web-app/devops/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'devops.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /examples/python-web-app/requirements.txt: -------------------------------------------------------------------------------- 1 | Django 2 | tzdata 3 | -------------------------------------------------------------------------------- /networking.md: -------------------------------------------------------------------------------- 1 | # Docker Networking 2 | 3 | Networking allows containers to communicate with each other and with the host system. Containers run isolated from the host system 4 | and need a way to communicate with each other and with the host system. 5 | 6 | By default, Docker provides two network drivers for you, the bridge and the overlay drivers. 7 | 8 | ``` 9 | docker network ls 10 | ``` 11 | 12 | ``` 13 | NETWORK ID NAME DRIVER 14 | xxxxxxxxxxxx none null 15 | xxxxxxxxxxxx host host 16 | xxxxxxxxxxxx bridge bridge 17 | ``` 18 | 19 | 20 | ### Bridge Networking 21 | 22 | The default network mode in Docker. It creates a private network between the host and containers, allowing 23 | containers to communicate with each other and with the host system. 24 | 25 | ![image](https://user-images.githubusercontent.com/43399466/217745543-f40e5614-ac34-4b78-85a9-91b24512388d.png) 26 | 27 | If you want to secure your containers and isolate them from the default bridge network you can also create your own bridge network. 28 | 29 | ``` 30 | docker network create -d bridge my_bridge 31 | ``` 32 | 33 | Now, if you list the docker networks, you will see a new network. 34 | 35 | ``` 36 | docker network ls 37 | 38 | NETWORK ID NAME DRIVER 39 | xxxxxxxxxxxx bridge bridge 40 | xxxxxxxxxxxx my_bridge bridge 41 | xxxxxxxxxxxx none null 42 | xxxxxxxxxxxx host host 43 | ``` 44 | 45 | This new network can be attached to the containers, when you run these containers. 46 | 47 | ``` 48 | docker run -d --net=my_bridge --name db training/postgres 49 | ``` 50 | 51 | This way, you can run multiple containers on a single host platform where one container is attached to the default network and 52 | the other is attached to the my_bridge network. 53 | 54 | These containers are completely isolated with their private networks and cannot talk to each other. 55 | 56 | ![image](https://user-images.githubusercontent.com/43399466/217748680-8beefd0a-8181-4752-a098-a905ebed5d2a.png) 57 | 58 | 59 | However, you can at any point of time, attach the first container to my_bridge network and enable communication 60 | 61 | ``` 62 | docker network connect my_bridge web 63 | ``` 64 | 65 | ![image](https://user-images.githubusercontent.com/43399466/217748726-7bb347d0-3736-4f89-bdff-31d240b15150.png) 66 | 67 | 68 | ### Host Networking 69 | 70 | This mode allows containers to share the host system's network stack, providing direct access to the host system's network. 71 | 72 | To attach a host network to a Docker container, you can use the --network="host" option when running a docker run command. When you use this option, the container has access to the host's network stack, and shares the host's network namespace. This means that the container will use the same IP address and network configuration as the host. 73 | 74 | Here's an example of how to run a Docker container with the host network: 75 | 76 | ``` 77 | docker run --network="host" 78 | ``` 79 | 80 | Keep in mind that when you use the host network, the container is less isolated from the host system, and has access to all of the host's network resources. This can be a security risk, so use the host network with caution. 81 | 82 | Additionally, not all Docker image and command combinations are compatible with the host network, so it's important to check the image documentation or run the image with the --network="bridge" option (the default network mode) first to see if there are any compatibility issues. 83 | 84 | ### Overlay Networking 85 | 86 | This mode enables communication between containers across multiple Docker host machines, allowing containers to be connected to a single network even when they are running on different hosts. 87 | 88 | ### Macvlan Networking 89 | 90 | This mode allows a container to appear on the network as a physical host rather than as a container. 91 | 92 | -------------------------------------------------------------------------------- /volumes.md: -------------------------------------------------------------------------------- 1 | # Docker Volumes 2 | 3 | ## Problem Statement 4 | 5 | It is a very common requirement to persist the data in a Docker container beyond the lifetime of the container. However, the file system 6 | of a Docker container is deleted/removed when the container dies. 7 | 8 | ## Solution 9 | 10 | There are 2 different ways how docker solves this problem. 11 | 12 | 1. Volumes 13 | 2. Bind Directory on a host as a Mount 14 | 15 | ### Volumes 16 | 17 | Volumes aims to solve the same problem by providing a way to store data on the host file system, separate from the container's file system, 18 | so that the data can persist even if the container is deleted and recreated. 19 | 20 | ![image](https://user-images.githubusercontent.com/43399466/218018334-286d8949-d155-4d55-80bc-24827b02f9b1.png) 21 | 22 | 23 | Volumes can be created and managed using the docker volume command. You can create a new volume using the following command: 24 | 25 | ``` 26 | docker volume create 27 | ``` 28 | 29 | Once a volume is created, you can mount it to a container using the -v or --mount option when running a docker run command. 30 | 31 | For example: 32 | 33 | ``` 34 | docker run -it -v :/data /bin/bash 35 | ``` 36 | 37 | This command will mount the volume to the /data directory in the container. Any data written to the /data directory 38 | inside the container will be persisted in the volume on the host file system. 39 | 40 | ### Bind Directory on a host as a Mount 41 | 42 | Bind mounts also aims to solve the same problem but in a complete different way. 43 | 44 | Using this way, user can mount a directory from the host file system into a container. Bind mounts have the same behavior as volumes, but 45 | are specified using a host path instead of a volume name. 46 | 47 | For example, 48 | 49 | ``` 50 | docker run -it -v : /bin/bash 51 | ``` 52 | 53 | ## Key Differences between Volumes and Bind Directory on a host as a Mount 54 | 55 | Volumes are managed, created, mounted and deleted using the Docker API. However, Volumes are more flexible than bind mounts, as 56 | they can be managed and backed up separately from the host file system, and can be moved between containers and hosts. 57 | 58 | In a nutshell, Bind Directory on a host as a Mount are appropriate for simple use cases where you need to mount a directory from the host file system into 59 | a container, while volumes are better suited for more complex use cases where you need more control over the data being persisted 60 | in the container. 61 | --------------------------------------------------------------------------------