Docker by doing 2 - docker advanced
Syslog (container logging)
- Find
rsyslog.conf
1
nano /etc/rsyslog.conf
- Edit the file uncomment the two lines under “Provides UDP syslog reception” by removing ‘#’
1
2$ModLoad imudp
$UDPServerRun 514 - Start the syslog service and configure docker to use it via
daemon.json
1
2
3systemctl start rsyslog
sudo mkdir /etc/docker
nano /etc/docker/daemon.json - Edit
daemon.json
1
2
3
4
5
6{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://<PRIVATE_IP>:514"
}
} - Start the Docker service
1
2
3systemctl start docker
# are there docker logs?
tail /var/log/messages - Create two new containers using the httpd image
- Syslog on log driver
1
2
3
4
5
6
7docker container run -d --name syslog-logging httpd
docker logs syslog-logging
# Error response from daemon: configured logging does not support reading
# check the content of '/var/log/messages':
# verify that the syslog-logging container is sending its logs to syslog
tail /var/log/messages
# the output shows us the logs that are being input to syslog - JSON file as log driver
1
2
3docker container run -d --name json-logging --log-driver json-file httpd
docker logs json-logging
# the logs do not appear in /var/log/messages
- Syslog on log driver
Watchtower (updating containers)
- Watchtower: monitoring containers with other container and update them when the image is updated
- Watchtower needs images pushed to a repository (see DockerHub)
- Create a dockerfile for a nodejs ‘express’ app
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# set base image
FROM node
# create the directory where the app will be copied to
RUN mkdir -p /var/node
# add our express content to that directory
ADD content-express-demo-app /var/node/
# set the working directory
WORKDIR var/node/
# scripts to build the app
RUN npm install
# execute
CMD ./bin/www - Log into DockerHub, build and push the image
1
2
3
4
5docker login
# -f = determine the dockerfile
# . = the dockerfile in this directory
docker build -t myDockerHubUser/express -f .
docker push myDockerHubUser/express - Execute dockerized app and watchtower
1
2
3
4
5
6
7
8
9## express app
# -d = run in the background
# -p = port, 80 on local, 3000 on container
docker run -d --name demo -p 80:3000 --restart always myDockerHubUser/express
docker ps
## watchtower
# last paramerter is refresh period (30 seconds)
docker run -d --name watchtower -p 80:3000 --restart always -v /var/run/docker.sock:/var/run/docker.sock v2tec/watchtower -i 30 - Make a small change on the ‘express’ app dockerimage, and push it to teh repository. Watchtower should autoupdate it
- Create a dockerfile for a nodejs ‘express’ app
Metadata and labels
- Use 2 different consoles to avoid issues (we will name them ‘docker workstation’ and ‘docker server’)
- Create a Dockerfile (on the docker workstation)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17FROM node
LABEL maintainer=user@mail.com
ARG BUILD_VERSION
ARG BUILD_DATE
ARG APPLICATION_NAME
LABEL org.label-schema.build-date=$BUILD_DATE
LABEL org.label-schema.applicaiton=$APPLICATION_NAME
LABEL org.label-schema.version=$BUILD_VERSION
RUN mkdir -p /var/node
ADD weather-app/ /var/node/
WORKDIR /var/node
RUN npm install
EXPOSE 3000
CMD ./bin/www - Build the Docker image (on the docker workstation)
1
2
3
4
5
6
7
8
9
10# log in to DockerHub
docker login
# build the image with parameters
docker build -t myDockerHubUser/weather-app --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg APPLICATION_NAME=weather-app --build-arg BUILD_VERSION=v1.0 -f Dockerfile .
# show image id (IMAGE_ID), and use it to inspect it
docker images
docker inspect IMAGE_ID
# push the image to DockerHub
docker push myDockerHubUser/weather-app - Create the weather-app container (on the docker server)
1
2docker run -d --name demo-app -p 80:3000 --restart always myDockerHubUser/weather-app
docker ps - Check out version v1.1 of the weather app (on the docker workstation)
1
2
3cd weather-app
git checkout v1.1
cd ../ - Rebuild the weather-app image (on the docker server)
1
2
3
4
5
6docker build -t mydockerHubUser/weather-app --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') /
--build-arg APPLICATION_NAME=weather-app --build-arg BUILD_VERSION=v1.1 -f Dockerfile .
docker push USERNAME/weather-app
# show image id (IMAGE_ID), and use it to inspect it
docker ps
docker inspect IMAGE_ID
Load balancing containers
- 2 servers: swarm manager and swarm worker (always on swarm manager unless you are told so)
- Create a Docker Compose file on Swarm Server 1 (on lb-challenge directory)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29# Change to the lb-challenge directory
version: '3.2'
services:
weather-app1:
build: ./weather-app
tty: true
networks:
- frontend
weather-app2:
build: ./weather-app
tty: true
networks:
- frontend
weather-app3:
build: ./weather-app
tty: true
networks:
- frontend
loadbalancer:
build: ./load-balancer
image: nginx
tty: true
ports:
- '80:80'
networks:
- frontend
networks:
frontend: - Update
nginx.conf
(on load-balancer directory)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17events { worker_connections 1024; }
http {
upstream localhost {
server weather-app1:3000;
server weather-app2:3000;
server weather-app3:3000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost;
proxy_set_header Host $host;
}
}
} - Execute docker-compose up
1
2
3cd ../
docker-compose up --build -d
docker ps - Create a Docker service using Docker Swarm
1
2
3
4cd ~/
# review the token
cat swarm-token.txt
# Copy the 'docker swarm join' command from the previous step - On swarm worker: execute the command that was copied from the previous step
- Back to swam manager: create a Docker service
1
2
3docker service create --name nginx-app --publish published=8080,target=80 --replicas=2 nginx
docker ps
#verify that the default nginx page loads in the browser (PUBLIC_IP_ADDRESS:8080)
Compose: building services
- Create a Ghost Blog and MySQL Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29version: '3'
services:
ghost:
image: ghost:1-alpine
container_name: ghost-blog
restart: always
ports:
- 80:2368
environment:
database__client: mysql
database__connection__host: mysql
database__connection__user: root
database__connection__password: P4sSw0rd0!
database__connection__database: ghost
volumes:
- ghost-volume:/var/lib/ghost
depends_on:
- mysql
mysql:
image: mysql:5.7
container_name: ghost-db
restart: always
environment:
MYSQL_ROOT_PASSWORD: P4sSw0rd0!
volumes:
- mysql-volume:/var/lib/mysql
volumes:
ghost-volume:
mysql-volume: - Start Ghost blog service
1
docker-compose up -d