Docker
https://www.youtube.com/watch?v=fqMOX6JJhGo
Containers
Are running instances of images that are isolated and have own environments and sets of processes
a container only lives as long as the process inside it runs
Images
An image is a package, template, plan.
Used to create one or more containers.
Commands
Containers
docker run
docker run nginx
start a container
/docker run attached/detatched/
docker run kodekloud/simple-webapp
running this command means its in attached mode meaning you are attached to the console or stout of console container
ctrl+c exits back to prompt
to run in detatched mode:
docker run -d kodekloud/simple-webapp
runs in the background go back to. your prompt imediatley
docker ps
to view container
docker attach container-id or container-name
to attach to container later
/tags/
docker run redis:4.0
You can target different versions of containers reds:4.0
4.0 is called a tag.
if no tag enteres latest
is assumed.
dockerhub lists all supported tags
/interactive mode and terminal/
by default docker containers dont listen to standard input - it attaches to console but doesnt wait for input it runs in non interactive mode.
docker run -i kodekloud/simple-prompt-docker
runs interactive mode
docker run -it kodekloud/simple-prompt-docker
attached to terminal and interactive mode
/port mapping/
how does a user access an application? what IP do I use to access from webbrowser?
- use docker container IP - only accessible on docker host
- use docker host IP -
docker run -p 80:5000 kodekloud/simple-webapp
- lets you run multiple instances
docker run -p hostport:containerport kodekloud/simple-webapp
$ docker run kodekloud/webapp
* Running on http://0.0.0.0:5000
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2a32e68ecac1 nginx:alpine "/docker-entrypoint.…" 8 minutes ago Up 7 minutes 0.0.0.0:3456->3456/tcp, 0.0.0.0:38080->80/tcp angry_hoover
Ports on the right(after ->) are exposed on the container
ports on left are exposed on the host
Run an instance of kodekloud/simple-webapp
with a tag blue
and map port 8080 on the container to 38282 on the host.
docker run -p 38282:8080 kodekloud/simple-webapp:blue
/volume mapping and persisting data/
docker run -v /opt/datadir:/var/lib/mysql mysql
keep data outside docker
Bind mounts have been around since the early days of Docker. Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the /host machine/ is mounted into a container. The file or directory is referenced by its full or relative path on the host machine. By contrast, when you use a volume, a new directory is created within Docker’s storage directory on the host machine, and Docker manages that directory’s contents.
/environment variables/
docker run -e APP_COLOR=blue simple-webapp-color
docker inspect container-name
under config - you find environment vans
Run a container named blue-app
using image kodekloud/simple-webapp
and set the environment variable APP_COLOR
to blue
. Make the application available on port 38282
on the host. The application listens on port 8080
.
docker run --name blue-app -p 38282:8080 -e APP_COLOR=blue kodekloud/simple-webapp
Deploy a mysql
database using the mysql
image and name it mysql-db
.
Set the database password to use db_pass123
. Lookup the mysql image on Docker Hub and identify the correct environment variable to use for setting the root password.
docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=db_pass123 mysql
docker inspect
docker inspect container-id or container-name
docker logs
- `
docker logs container-id or container-name
docker ps
docker ps
list all running containers and basic infodocker ps -a
list all running containers and non running containers
docker stop
docker stop container-id or container-name
stop container
docker rm
docker rm container-id or container-name
completely remove a container to save space
docker exec
docker exec container-name cat /etc/hosts
See contents of file in containerdocker exec -it <mycontainer> bash
docker attach
docker attach container-id or container-name
attach to container later
Images
docker images
docker images
list of available images and sizes
docker rmi
docker rmi nginx
remove image completely
docker pull
docker pull nginx
pull the image store it and not run it
docker history
docker history apricot13/simple-webapp
Show the history of an image
docker build
docker build .
- if a step fails it starts from failed section
creating own images
Manual app setup:
- install os (ubuntu)
- update with apt get
- install dependencies using apt
- install python dependencies with pip
- copy source code to /opt folder
- run server using flask command
Create Dockerfile
text file written in instruction and arguments format
every dockerfile is based off another image (either of an os or another image)
(in this instance source code is in folder were running from)
FROM Ubuntu
RUN apt-get update
RUN apt-get install python
RUN pip install flask
RUN pip install flask-mysql
COPY . /opt/source-code
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
docker build Dockerfile -t apricot13/my-custom-app
create local image
docker push apricot13/my-custom-app
push to dockerhub
Build a docker image using the Dockerfile and name it webapp-color
. No tag to be specified.
docker build Dockerfile -t webapp-color
docker build . -t webapp-color
Run an instance of the image webapp-color
and publish port 8080
on the container to 8282
on the host.
docker run -p 8282:8080 webapp-color
What is the base Operating System used by the python:3.6
image?
Run docker run python:3.6 cat /etc/*release*
command
Docker cmd's arguments and entrypoints
containers only live as long as the process inside them is running
who defines whcih process is run in each container? - dockerfile CMD command
bash is the defailt command for an os image - by default no terminal attached on run - terminal not found so container exists.
how to override default command? append command
docker run ubuntu sleep 5
want image to always run sleep when it starts? create own image and specify new command
FROM Ubuntu
CMD sleep 4 or CMD ["command", "param1"] CMD ["sleep", "5"]
when you specifify in json format must be command then parameter
how to change the sleep value?
FROM Ubuntu
ENTRYPOINT ["sleep"]
docker run ubuntu-sleeper 10
ENTRYPOINT replaces CMD parameter is appended to ENTRYPOINT value if you dont enter 10 youre just running 'sleep command'to create a default value:
FROM Ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
command at startup
sleep 5
docker run ubuntu-sleeper 10
command at start-upsleep 10
You can override entry points with
docker run --entrypoint sleep2.0 ubuntu-sleeper 10
runssleep2.0 10
on startup
Run an instance of the ubuntu image to run the sleep 1000 command at startup
Run it in detached mode.
docker run -d ubuntu sleep 1000
Docker networking
docker network
docker network ls
docker network inspect bridge
docker creates 3 networks when you install it
- bridge - default network a container gets attached too
- to access from outside map the ports (
-p hostport:containerport
)
- to access from outside map the ports (
- none
docker run Ubuntu --network=none
- not attached to any network - no access to external network or other containers
- Host
docker run Ubuntu --network=host
- web container uses the hosts network 0 no port mapping - cant run multiple web containers
to associate with any other host you use the --network
parameter
- all containers can resolve each others ips using the name of the container
- mysql.connect(container-name)
127.0.0.11
dns server always runs at
- docker uses network namespaces - create separate namespace for each container
Run a container named alpine-2
using the alpine
image and attach it to the none
network.
docker run --name alpine-2 alpine --network=none
Create a new network named wp-mysql-network
using the bridge
driver. Allocate subnet 182.18.0.1/24
. Configure Gateway 182.18.0.1
docker network create --driver bridge --subnet 182.18.0.1/24 --gateway 182.18.0.1 wp-mysql-network
Deploy a mysql
database using the mysql:5.6
image and name it mysql-db
. Attach it to the newly created network wp-mysql-network
Set the database password to use db_pass123
. The environment variable to set is MYSQL_ROOT_PASSWORD
docker run -d --name mysql-db -e MYSQL_ROOT_PASSWORD=db_pass123 --network wp-mysql-network mysql:5.6
Deploy a web application named webapp
, using image kodekloud/simple-webapp-mysql
. Expose port to 38080 on the host. The application takes an environment variable DB_Host
that has the hostname of the mysql database. Make sure to attach it to the newly created network wp-mysql-network
docker run --network=wp-mysql-network -e DB_Host=mysql-db -e DB_Password=db_pass123 -p 38080:8080 --name webapp --link mysql-db:mysql-db -d kodekloud/simple-webapp-mysql
data
/var/lib/docker
aufs
containers
image
volumes
- copy on write mechanism - to edit file in the read only layer when you write to the file a copy is taken and brought into the readwrtie container layer so the files in the image layer is not modified
- when we delete container changes get deleted
- how to Persist data persistent volume
docker volume create data_volume
var/lib/docker
volumes
data_volume
docker run -v data_volume:/var/lib/mysql mysql
(docker will automatically create a volume if not created previously) (volume mounting)
docker run -v /data/mysql:/var/lib/mysql mysql
if data already exists on the host (bind mounting) mound directory from any location on docker host-v
old style--mount
preferreddocker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql
- image-2020062542953243
docker uses storage drivers: AUFS, ZFS BTRFS Device mapper overlay overlay2 - docker chooses best automatically
Run a mysql
container named mysql-db
using the mysql
image. Set database password to db_pass123
Note: Remember to run it in the detached mode.
docker run -e MYSQL_ROOT_PASSWORD=db_pass123 --name mysql-db -d mysql
docker exec mysql-db mysql -pdb_pass123 -e 'use foo; select * from myTable'
Run a mysql container again, but this time map a volume to the container so that the data stored by the container is stored at /opt/data
on the host.
Use the same name : mysql-db
and same password: db_pass123
as before. Mysql stores data at /var/lib/mysql
inside the container.
docker run -e MYSQL_ROOT_PASSWORD=db_pass123 --name mysql-db --mount type=volume,source=/opt/data/,target=/var/lib/mysql -d mysql
or docker run -v /opt/data:/var/lib/mysql -d --name mysql-db -e MYSQL_ROOT_PASSWORD=db_pass123 mysql
docker compose
docker-compose up
- only applicable on single docker host
Single docker engine - voting application
docker run method
docker run -d --name=redis redis
docker run -d --name=db postgres:9.4
docker run -d --name=vote -p 5000:80 voting-app
docker run -d --name=result -p 5001:80
docker run -d --name=worker worker
- problem: creates the containers but doesn't link them together
--link nameofcontainer:nameofhostapplookingfor
creates entry into voting app container hosts file- --link deprecated docker swarm improves this.
docker run -d --name=redis redis
docker run -d --name=db postgres:9.4 --link db:db
docker run -d --name=vote -p 5000:80 --link redis:redis voting-app
docker run -d --name=result -p 5001:80
docker run -d --name=worker --link db:db --link redis:redis worker
def get_redis():
if not hasattr(g, 'redis'):
g.redis = Redis(host="redis", db=0, socket_timeout=5)
return g.redis
docker-compose method
- NB
db:db
===db
redis:
image: redis
db:
image: postgres:9.4
vote:
image: voting-app
ports:
- 5000:80
links:
- redis
result:
image: result-app
ports:
- 5001:80
links:
- db
worker:
image: worker
links:
- redis
- db
docker-compose up
vote:
build: ./vote
ports:
- 5000:80
links:
- redis
./vote
points to a GitHub repo containing a dockerfile
versioning dockercompose files
version 1 stuck on 1 bridged network
for v2 and up specify the version in top of file
version: 2
automatically create new bridged network and attaches them all - so v2 you dont need to use links
specify startup order depends_on:
version: 3
support for docker swarm
networks in docker compose
two networks - frontend and backend
version: 2
services:
redis:
image: redis
networks:
- back-end
db:
image: postgres:9.4
networks:
- back-end
vote:
image: voting-app
ports:
- 5000:80
links:
- redis
networks:
- front-end
- back-end
result:
image: result-app
ports:
- 5001:80
links:
- db
networks:
- front-end
- back-end
worker:
image: worker
links:
- redis
- db
networks:
- back-end
networks:
front-end:
back-end:
First create a postgress database container called db
, image postgres
, environmental variable POSTGRES_PASSWORD=mysecretpassword
if you are unsure, check the hints section for the exact commands.
docker run -d -e POSTGRES_PASSWORD=mysecretpassword --name db postgres
Next let's create a simple wordpress container called wordpress
, image: wordpress
, link it to the container db
and expose it on host port 8085
if you are unsure, check the hints section for the exact commands.
docker run -d --name wordpress -p 8085:80 --link db:db wordpress
version: 2
services:
db:
image: postgres
environment:
- POSTGRES_PASSWORD=mysecretpassword
wordpress:
image: wordpress
links:
- db
ports:
- 8085:80
Docker registry
docker images are storred in the docker registry
docker login private-registry.io
docker run private-registry.io/apps/internal-app
run your own version of docker hub locally
docker run -d -p 5000:5000 --name registry registry:2
docker image tag my-image localhost:5000/my-image
register local image
docker push localhost:5000/my-image
pushed to local registery
docker pull localhost:5000/my-image
docker pull 192.168.56.100:5000/my-image
docker engine
Good docker links:
https://medium.com/better-programming/customize-your-mysql-database-in-docker-723ffd59d8fb
https://stackoverflow.com/questions/27409761/docker-multiple-dockerfiles-in-project
Created on: 11th October, 2022
Last updated: 12th October, 2022
Tagged With: