Docker Overview
Use containers to Build, Share and Run your applications !!!
Docker is an open platform for developing, shipping, and running applications.
Docker enables you to separate your applications from your infrastructure
so you can deliver software quickly.
Docker provides the ability to package and run an application
in a loosely isolated environment called a container.
The isolation and security allow you to run many containers simultaneously on a given host.
Containers are lightweight and contain everything needed to run the application,
so you do not need to rely on what is currently installed on the host.
You can easily share containers while you work, and be sure that
everyone you share with gets the same container that works in the same way
Docker Arichtecture
- Docker Documentation
- Docker best practices
- Docker releases notes
-
Docker BuildKit
-
Play with Docker Classroom
- Get/Install Docker
And run your first container like:docker run hello-world
Basic commands
Commands ...
docker --help # to list all available options
docker pull ${image} # to get image from default docker registry: docker pull nginx
# Build a image
docker build -t ${image}:${tag} ./ # if Dockerfile is in the current folder
docker build -t ${image}:${tag} -f /path/to/Dockerfile # to specify path or custom file name
## --build-arg bvar_name=value to argument value if you use ARG in your Dockerfile
docker history ${image} # to see image build history
docker run --name myconten -i -t myimage /bin/bash
docker exec -it ${container_name_or_id} bash #or bash or sh according to case# to enter inside container
docker stop {container_name_or_id} # to stop
docker start {container_name_or_id}
docker ps # to see the running containers
docker ps -a # to see all including stopped/crashed containers
docker ps -f "status=exited" # to see only stopped containers
is_runned=$(docker ps -q -f "name=${cont_name}")
docker stop $(docker ps -a -q) # stop all container
docker stop $(docker ps -a -q) # remove all container
docker rmi $(docker images -q) #remove all images.
# Log in a registry
docker login -u ${registry}
# commit container changes into new image
# useful when you manually change/add something
#inside container and you want to save/keep it for next time
docker commit - a="auteur" -m="message" {container_name_or_id} ${new_image}
# copy file between server and container
docker cp myfile {container_name_or_id}:/dst/myfile #from server to container
docker cp {container_name_or_id}:/dst/myfile //myfile
docker export containerID > filename.tar # Export a container’s filesystem as a tar archive
docker save imageID > filename.tar # Save one or more images to a tar archive
# or like
docker save -o filename.tarr imageID
docker load < filename.tar # Load an image from a tar archive or STDIN
docker load --input filename.tar
docker inspect ${container_name_or_id} # to see container conf details
docker inspect --format='{{json .State.Health}}' ${container_name_or_id}
# docker import: Import the contents from a tarball to create a filesystem image
docker import filename.tar
cat filename.tar| docker import - ${new name}
## You can also clone an exisitng server filesystem to use it to create image
## Example below
Archive existing server filesystem and import it as Docker image
Archiche server FS and create Docker image
## You must exclude some system folder like: sys, proc, dev/pts, mnt
## Then you can exclude another folders if you want
cd /mnt
tar -cvpf fullbackup.tar --directory=/ --exclude=proc --exclude=sys --exclude=dev/pts --exclude=tmp --exclude=backups \
--exclude=mnt --exclude=home/osadmin --exclude=lost+found --exclude=images --exclude=media --exclude=users --exclude=opt \
--exclude=var/log --exclude=var/lib/docker --exclude=var/log/docker --exclude=usr/tmp --exclude=usr/lib/vmware-tools \
--exclude=usr/lib/firmware --exclude=usr/share/doc .
# Import archive as Docker image
cat fullbackup.tar | docker import - myserverclone:1.0.0
Docker Group for Non-root users
Create a docker group to enable non-root users to run docker commands without using sudo
Create docker group and add a user
# Create the docker group if it doesn't exist
sudo groupadd docker
# Add a $USER to the group
sudo usermod -aG docker $USER
# Log in to the docker group
newgrp docker
# Test with a non-root user
docker info
Ubuntu - DEBIAN_FRONTEND
ENV DEBIAN_FRONTEND noninteractive
When you use debian or ubuntu as base in Dockerfile you should add this
to avoid interactive rquest otherwise the image build will fail
Docker insecure registry
If you want to use your own docker registry you should add it in daemon.json`` as insecure registry.
Modify or create /etc/docker/daemon.json
and add
{
"insecure-registries" : ["myregistrydomain.com:5000"]
}
Change data-root - /var/lib/docker
Sometimes you want to change /var/lib/docker
folder to another folder
Create folder and stop Docker
mkdir –p /path/newfolder
chmod 701 /path/to/newfolder
service docker stop
# if you already have docker data: images/containers and you want to keep
## you can copy /var/li/docker content in the new one like
sudo rsync -aP /var/lib/docker/ /path/newfolder
Then modify or create /etc/docker/daemon.json
to add key data-root
(graph
if you use an old version) to specify your new folder
Update daemon.json
vim /etc/docker/daemon.json # Create if does not exist yet and add this:
{
"storage-driver": "overlay2" ## an already existing key in my case
,"data-root": "/path/newfolder" ##added to change /var/docker/
}
# Start a Docker service
service docker start
# you can now delete /var/lib/docker
Use Docker behind Proxy
When your server need proxy to access to external, docker pull
will not work.
But you can use proxy settings to achieve that:
https://docs.docker.com/config/daemon/systemd/#httphttps-proxy
Setup HTTP Proxy
sudo mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF
Environment="HTTP_PROXY=http://proxy.example.com:80"
Environment="HTTPS_PROXY=https://proxy.example.com:443"
Environment="NO_PROXY=localhost,127.0.0.1,xxx"
EOF
Socks5 Proxy
# Sometimes you need a socks proxy instead of hhtp/https one
## Linux
Environment="ALL_PROXY=socks5://127.0.0.1:8899/"
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker # to verify configuration
## Open sock tunnel proxy based on port 8899
sshpass -p password ssh -D 8899 -f -C -q -N user@ip
Socks5 Proxy
## Windows
[Environment]::SetEnvironmentVariable("ALL_PROXY", "socks5://127.0.0.1:666/", [EnvironmentVariableTarget]::Machine)
[Environment]::SetEnvironmentVariable("NO_PROXY", "localhost,127.0.0.1", [EnvironmentVariableTarget]::Machine)
Restart-Service docker
Update a logical volume used by docker [RedHat]
This assumes you are using devicemapper driver
which uses a logical volume
Already experimented with this case with Red Hat servers where the /var/lib/docker
was mounted on a dedicated logical volume(LV).
More about devicemapper driver in production here
Use case example
Chosen VG: infravg car plus d'espace
Pre-Setup
systemctl stop docker
rm -rf /var/lib/docker # if you don't want to keep existing things
# or mv /var/lib/docker /var/lib/docker.old # to keep it
/etc/docker/daemon.json
Directly with `/etc/docker/daemon.json`
# ${DEVICE} is a PV (hysical volume) to use to create a Docker LV
vim /etc/docker/daemon.json
# and
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.directlvm_device=${DEVICE}",
"dm.thinp_percent=95",
"dm.thinp_metapercent=1",
"dm.thinp_autoextend_threshold=80",
"dm.thinp_autoextend_percent=20",
"dm.directlvm_device_force=false"
]
}
service docker start
/etc/sysconfig
According to your system settings
(Applied on Red Hat server some years ago)
cd /etc/sysconfig
vim docker-storage-setup ## add The VG you wan to use (infravg)
vim docker-storage # leave OPTIONS as blank
docker-storage-setup # will create a Docker LV for you
#lvdisplay
service docker start
lv commands
if you want to create docker LV by yourself
lvdisplay # to have details about existing logical volume
pvdisplay # to have details about pv
## here i use a VG called: infravg
lvcreate --wipesignatures y -n thinpool infravg -l 45%VG #22,5 GB
## lvremove /dev/mapper/infravg-thinpool # to delete a lv if needed
lvcreate --wipesignatures y -n thinpoolmeta infravg -l 5%VG #2,5 GB
lvconvert -y --zero n -c 512K --thinpool infravg/thinpool --poolmetadata infravg/thinpoolmeta
cd /etc/lvm/profile
vim infravg--docker-pool-extend.profile
### and then specify thin_pool_autoextend_threshold and thin_pool_autoextend_percent values
lvchange --metadataprofile infravg--docker-pool-extend infravg/thinpool
## Udpdate docker storage confile with the new LV path
sudo lvs -o+seg_monitor ## Assure lv monitoring is enabled
sudo lvchange --monitor y docker/thinpool
## Accrding to your case you should update the LV path
vim /etc/sysconfig/docker-storage
## add /dev/mapper/infravg-thinpool
service docker start
Basic Exercices
Basic Apache Website
create index.php
## create index.php
cat > index.php << EOF
<!DOCTYPE html>
<html>
<head>
<title> Check system </title>
</head>
<body>
<p> Welcome: I am a PHP-APACHE Container! </p>
<?php
echo "<h5> System Info </h5>";
echo " ";
$unam = shell_exec('uname -a');
echo "<pre>$unam</pre>";
$lscpu = shell_exec('lscpu | head -23');
echo "<pre>$lscpu</pre>";
?>
<?php
echo "<h5> Load average </h5>";
echo " ";
$uptim = shell_exec('uptime');
echo "<pre>$uptim</pre>";
echo " "
?>
<?php
echo "<h5> CPU and MEM </h5>";
echo " ";
$cpumem = shell_exec('top -b -n1 | head -3');
echo "<pre>$cpumem</pre>";
echo " "
?>
<?php
echo "<h5> top </h5>";
echo " ";
$top = shell_exec('top -b -n1');
echo "<pre>$top</pre>";
echo " "
?>
<?php
echo "<h5> Stockage </h5>";
echo " ";
$free = shell_exec('free');
echo "<pre>$free</pre>";
$dfh = shell_exec('df -h');
echo "<pre>$dfh</pre>";
echo " "
?>
<?php
echo "<h5> Users list </h5>";
echo " ";
$userlist = shell_exec('cut -d: -f1 /etc/passwd');
echo "<pre>$userlist</pre>";
echo " "
?>
</body>
</html>
EOF
docker run -d -p 80:80 --name my-app -v "$PWD":/var/www/html php:7.0-apache
# visit http://localhost or http://${server_ip}
```
imple Docker training exercices
exo-00: docker cli
tests somme commands:
docker, info docker images, docker ps; docker ps -a, docker inspect,
docker run, docker logs, docker stop docker rm, docker volume ls
[Discover CLI command](https://docs.docker.com/engine/reference/commandline/docker/){:target="_blank"}
pratical test: https://katacoda.com/alvagante/scenarios/3
exo-01: Run Docker containers
More about [docker run command](https://docs.docker.com/engine/reference/run/#general-form){:target="_blank"}
Pratical test [HERE](https://katacoda.com/allamand/courses/docker-course/docker-basics){:target="_blank"},
do **only** from step **1** to step **3** (1, 2 and 3)
exo-02: Dockerfile, build image and run container
learn dockerfile: https://docs.docker.com/engine/reference/builder/#usage
Only Step4: katacoda: https://katacoda.com/allamand/courses/docker-course/docker-basics
Build image in our server(not in katacoda) with Dockerfile
1. write a simple html file
2- write a Dockerfile
*** use httpd base image to deploy a basic web site:
static base image: amp-prod-repo-artifacts.equant.com:5005/orange/httpd-mime:1.0
** add or copy your source file in your image:
3 build your image
4 run your container
**change your web site port 8081
create a docker volume "myvolume" see docker volume..
using it by mounting the /var/www/html/
exo-03: Write complex Dockerfile
## run ubuntu container
image: docker.io/ubuntu:latest
## To run
docker run --name ubuntu -d docker.io/ubuntu:latest tail -f /dev/null
# to enter inside
docker exec -it ubuntu bash
#the container ubuntu: is equivalent(like) of your machine/vm/server with OS ubuntu
## first step:
a- enter inside:
install apache, deploy a simple html page(index.html)
then: install PHP and try to deploy now a dynamique page(index.php)
{ you can do this directly by skipping html step if you want}
b: you have finished to deploy all web services in your server ubuntu
## second step:
Now write a Dockerfile to do all manual actions you do above inside container
to allow another one to have an ready image with theses services
## deploy your website with docker run to test it
Exo-04: Deploy with docker-compose.yml
!!! Read only page content, DON'T FOLLOW its sub links
about docker-compose: https://docs.docker.com/compose/overview/
command docker-compose: https://docs.docker.com/compose/reference/overview/
docker-compose file
version2: https://docs.docker.com/compose/compose-file/compose-file-v2/
version3: https://docs.docker.com/compose/compose-file/
Only step5 katacoda: https://katacoda.com/allamand/courses/docker-course/docker-basics
Write on our server, write docker-compose.yml to deploy you exercice2 website
dockerfile ubuntu
FROM docker.io/ubuntu:latest
LABEL MAINTAINER="xxx" \
Version="xxx" \
Name="xxx" \
Vendor="xxx"
## pour le dpkg
ENV DEBIAN_FRONTEND noninteractive
USER root
RUN apt-get update && \
apt-get install apache2 apache2-doc apache2-utils -y && \
apt-get install php -y && \
apt-get install apt-utils -y &&\
apt-get install vim -y && \
apt-get install curl -y
#ajout de conf pour example.conf
ADD example.com.conf /etc/apache2/sites-available
RUN echo "Europe/Paris" > /etc/timezone && \
dpkg-reconfigure -f noninteractive tzdata && \
a2dissite 000-default.conf && \
mkdir -p /var/www/example.com/public_html && \
mkdir /var/www/example.com/logs
COPY index.php /var/www/example.com/public_html/
ADD start.sh /tmp/
RUN a2ensite example.com.conf && \
chmod 777 /tmp/start.sh
CMD /tmp/start.sh
## start.sh
#!/bin/bash
service apache2 start &
while true
do
echo "coucou, je suis toto"
sleep 1
done