Docker is a software platform that allows you to build, test, and deploy applications quickly. Docker packages software into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and runtime. Using Docker, you can quickly deploy and scale applications into any environment and know your code will run.
Docker provides us with containers. And containerization consists of an entire runtime environment, an application, all its dependencies, libraries, binaries and configuration files needed to run it, bundled into one package. Each application runs separately from the other. Docker solves the dependency problem by keeping the dependency contained inside the containers. It unites developers against dependency of their project. Docker-based applications can be seamlessly moved from local development machines to production deployments.
Docker works by providing a standard way to run your code. Docker is an operating system for containers. Similar to how a virtual machine virtualize (removes the need to directly manage) server hardware, containers virtualize the operating system of a server. Docker is installed on each server and provides simple commands you can use to build, start, or stop containers.
$ docker
$ docker version
$ docker info
π‘ NOTE: Docker is based on
Go
language.
$ docker run -it redis
$ docker run -d redis
π‘ NOTE: WHAT
run
DID?
- Looked for image called redis in image cache
- If not found in cache, it looks to the default image repo on Docker hub
- Pulled it down (latest version), stored in the image cache
- Started it in a new container
docker run
=docker create
+docker start
π‘ NOTE: Analogy to understand image and container: Consider image like blueprint and container like an actual house, we can't build the house without blueprint thus need to download image. Container is like running instance of image which got created in the system.
$ docker ps
$ docker ps -a
π‘ NOTE: If we are not giving any specific name to our container, it randomly generate one, with first segment adjective and second segment famous hacker/scientist name.
$ docker stop <CONTAINER_ID>
$ docker stop $(docker ps -aq)
docker kill <CONTAINER_ID>
$ docker rm <CONTAINER_ID>
$ docker rm -f <CONTAINER_ID>
$ docker rm <CONTAINER_ID_1> <CONTAINER_ID_2> <CONTAINER_ID_3>
$ docker rm $(docker ps -aq)
$ docker container logs <CONTAINER_NAME>
$ docker top <CONTAINER_NAME>
π‘ NOTE: ABOUT CONTAINERS - Docker containers are often compared to virtual machines but they are actually just processes running on your host
OS
. In Windows/Mac, Docker runs in a mini-VM so to see the processes you'll need to connect directly to that. On Linux however you can run "ps aux" and see the processes directly.
$ docker container inspect <CONTAINER_NAME>
$ docker container inspect --format '{{ .NetworkSettings.IPAddress }}' <CONTAINER_NAME>
$ docker container stats <CONTAINER_NAME>
$ docker image ls
$ docker pull <IMAGE_NAME>
π‘ NOTE: Even after removing container, image still exists. IMAGE needs to removed separately.
$ docker image rm <IMAGE_NAME>
$ docker rmi $(docker images -a -q)
π‘ NOTE: About IMAGE
- Images are app binaries and dependencies with meta data about the image data and how to run the image
- Images are no a complete OS. No kernel, kernel modules (drivers)
- Host provides the kernel, big difference between VM
# -p 80:80 is optional as it runs on 80 by default
# -d :- To run container in background
$ docker container run -d -p 80:80 --name nginx nginx
# Official name of apache is httpd on docker hub, so we are giving custom name
$ docker container run -d -p 8080:80 --name apacheCustomName httpd
$ docker container run -d -p 27017:27017 --name mongo mongo
# running some command line environment variable which mysql support
$ docker container run -d -p 3306:3306 --name mysql --env MYSQL_ROOT_PASSWORD=123456 mysql
# - i = interactive Keep STDIN open if not attached
# - t = tty - Open prompt
$ docker container run -it --name <CONTAINER_NAME> nginx bash
π‘ NOTE: To access running container - Consider running redis in container and then play with it.
$ docker run redis
-> Now, redis is running inside a docker container. Now if we try to runredis-cli
it will throw error stating redis server not running. Reason? Redis is running inside a container & it will be accessible only inside that. To go inside container and then run command we have to do following:docker exec -it <CONTAINER_ID> <COMMAND>
Dockerfile -> Docker Client -> Docker Server -> Usable Image!
Dockerfile contains configuration to define how our container should behave.
- FROM - The os used. Common is alpine, debian, ubuntu
- ENV - Environment variables
- RUN - Run commands/shell scripts, etc
- EXPOSE - Ports to expose
- CMD - Final command run when you launch a new container from image
- WORKDIR - Sets working directory (also could use 'RUN cd /some/path')
- COPY # Copies files from host to container
Q: Create a node server and dockerize it?
// index.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('How are you doing');
});
app.listen(8080, () => {
console.log('Listening on port 8080');
});
// package.json
{
"dependencies": {
"express": "*"
},
"scripts": {
"start": "node index.js"
}
}
// Dockerfile
# Specify a base image
FROM node:alpine
# create usr/app and make use of this directory now onward
WORKDIR /usr/app
# Install some dependencies
COPY ./package.json ./
RUN npm install
COPY ./ ./
# Default command
CMD ["npm", "start"]
Now, Build your docker image:
docker build -t alok722/simpleserver
Now, we need to run our image along with port mapping so that server port would be accessible outside container.
docker run -p 8080:8080 <IMAGE_ID>
π‘ NOTE: Keep things that change the most toward the bottom of the Dockerfile so that mostly cached would be utilized
$ docker tag simpleserver:latest alok722/simpleserver:latest
$ docker push alok722/simpleserver
- Configure relationships between containers
- Save our docker container run settings in easy to read file
- 2 Parts: YAML File (docker.compose.yml) + CLI tool (docker-compose)
- containers
- networks
- volumes
version: '2'
# same as
# docker run -p 80:4000 -v $(pwd):/site bretfisher/jekyll-serve
services:
jekyll:
image: bretfisher/jekyll-serve
volumes:
- .:/site
ports:
- '80:4000'
docker-compose up
docker-compose up -d
docker-compose down
To Be Continued...