Learn docker from scratch to deploy a slightly loaded application

Posted by iShaun on Sat, 29 Jun 2019 20:28:14 +0200

We talked about deploying a simple Python program before.

In this section, we will extend the Python program, connect redis database, and do some operations on redis.

New App.py, as follows:

from flask import Flask
from redis import Redis
import os
import socket

app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello Container World! I have bean seen %s times and my hostname is %s. \n' % (redis.get('hits'), socket.gethostname())

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

New Docker file, as follows:

FROM python:2.7
LABEL maintainer="vincent"
COPY . /app
WORKDIR /app
RUN pip install flask redis
EXPOSE 5000
CMD [ "python", "app.py" ]

Create an image:

docker build -t vincent/flask-redis .

Since we're going to use redis, we're not installing redis in Dockerfile. We're just introducing a Python redis dependency library. How do we use redis services?

When we build a complex App, we need to divide the components of App into different containers to deploy. We deploy redis as a separate App, flask as a separate App, and flask is going to visit redis. Let's first create a container for redis.

docker run -d --name redis redis
docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
1fb5745864cd        redis               "docker-entrypoint.s..."   23 seconds ago      Up 22 seconds       6379/tcp            redis

But our current redis port is 6379. But when we created the container, we did not specify the - p 6379:6379 parameter.

What do you ask? Because redis here is not for outside visitors, it's for our internal App visitors, so we don't need to expose 6379 outside (it's not safe).

In addition, our App.py does not know the IP address of redis, so the address is retrieved as an environment variable (os.environ.get ('REDIS_HOST','127.0.0.1').

We can use the link parameter to access redis by accessing the container name.

Create flask-redis container:

docker run -d --link redis --name flask-redis -e REDIS_HOST=redis vincent/flask-redis

- e REDIS_HOST means setting an environment variable REDIS_HOST=redis in the current container vincent/flask-redis

Let's go into the container and see env:

docker exec -it flask-redis /bin/bash
root@45977ae3cbed:/app# env
REDIS_PORT_6379_TCP_PROTO=tcp
REDIS_PORT=tcp://172.17.0.2:6379
REDIS_NAME=/flask-redis/redis
LANG=C.UTF-8
HOSTNAME=45977ae3cbed
REDIS_PORT_6379_TCP_ADDR=172.17.0.2
REDIS_PORT_6379_TCP=tcp://172.17.0.2:6379
GPG_KEY=C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF
PYTHONIOENCODING=UTF-8
REDIS_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-5.0.5.tar.gz
REDIS_HOST=redis
PWD=/app
HOME=/root
REDIS_PORT_6379_TCP_PORT=6379
TERM=xterm
REDIS_ENV_REDIS_DOWNLOAD_SHA=2139009799d21d8ff94fc40b7f36ac46699b9e1254086299f8d3b223ca54a375
REDIS_ENV_GOSU_VERSION=1.10
PYTHON_VERSION=2.7.16
SHLVL=1
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
REDIS_ENV_REDIS_VERSION=5.0.5
PYTHON_PIP_VERSION=19.1.1
_=/usr/bin/env

You can see that there is an environment variable REDIS_HOST=redis inside.

ping through name:

root@45977ae3cbed:/app# ping redis
PING redis (172.17.0.2) 56(84) bytes of data.
64 bytes from redis (172.17.0.2): icmp_seq=1 ttl=64 time=1.16 ms
64 bytes from redis (172.17.0.2): icmp_seq=2 ttl=64 time=0.105 ms
64 bytes from redis (172.17.0.2): icmp_seq=3 ttl=64 time=0.215 ms

Topics: Programming Redis Docker Python socket