Skip to content

Commit 3c965bf

Browse files
authored
Merge pull request #2 from hlesey/use_redis
Use redis
2 parents 0b828b2 + d56681d commit 3c965bf

30 files changed

+254
-232
lines changed

docker/.dockerignore .dockerignore

File renamed without changes.

.gitignore

+2-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,2 @@
1-
# Created by .ignore support plugin (hsz.mobi)
2-
.project
3-
*/.project
4-
/*.iml
5-
.idea
6-
.vagrant
7-
*.rpm
8-
/vagrant/*.vdi
9-
*.DS_Store
1+
__pycache__
2+
venv

.idea/vcs.xml

-6
This file was deleted.

.vscode/launch.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Python: Current File",
9+
"type": "python",
10+
"request": "launch",
11+
"program": "${file}",
12+
"console": "integratedTerminal",
13+
"args": [
14+
"run",
15+
"--port",
16+
"5000"
17+
],
18+
"env": {
19+
"FLASK_APP": "app.app",
20+
"REDIS_HOST":"127.0.0.1",
21+
"FLASK_PORT": "8080"
22+
},
23+
"pythonPath": "${config:python.pythonPath}",
24+
"cwd": "${workspaceFolder}",
25+
"module": "flask"
26+
}
27+
]
28+
}

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.pythonPath": "venv/bin/python3"
3+
}

Dockerfile

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM python:3.7-alpine
2+
3+
LABEL \
4+
app="docker-cursantX" \
5+
layer="frontend" \
6+
git-url="https://github.com/hlesey/phippy.git"
7+
8+
WORKDIR /app
9+
COPY app/ .
10+
COPY requirements.txt .
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
ENV FLASK_APP=app
14+
15+
CMD ["python", "-m", "flask", "run", "--host", "0.0.0.0"]

Makefile

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
DOCKER_HUB_USER=hlesey
3+
REPO_NAME=phippy
4+
VERSION=$$(cat app/__version__.py | cut -d '=' -f2 | tr -d '"')
5+
6+
build:
7+
docker build -t ${DOCKER_HUB_USER}/${REPO_NAME}:${VERSION} .
8+
9+
push:
10+
docker push ${DOCKER_HUB_USER}/${REPO_NAME}:${VERSION}
11+
12+
run:
13+
docker-compose up
14+
15+
dev_setup:
16+
[ -d venv ] || mkdir venv
17+
[ -f venv/bin/activate ] || python3 -m venv venv
18+
./venv/bin/pip install -r requirements.txt

README.md

+9-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# phippy
1+
# Phippy
22
Simple tutorial to build and deploy a simple Python app in Kubernetes.
33

44

@@ -11,29 +11,19 @@ docker push <DOCKER_HUB_USER>/phippy
1111
```
1212

1313
## Launch the app using Docker
14-
```
15-
docker network create phippy
16-
docker run -d -p 2379:2379 --net phippy --name etcd quay.io/coreos/etcd:3.3.4
17-
docker run -d -p 31380:80 --net phippy --name phippy <DOCKER_HUB_USER>/phippy
18-
```
1914

20-
Or you can use the existing scripts to build/push/run/cleanup the app:
15+
You can use the existing commands to build/push/run the app:
2116

2217
```
23-
./docker_build.sh
24-
./docker_push.sh
25-
./docker_run.sh
26-
./docker_cleanup.sh
18+
make build
19+
make push
20+
make run
2721
```
2822

2923
## Test the app
3024
```
31-
curl localhost:31380
32-
```
33-
34-
## Launch the app with Docker Compose
35-
```
36-
docker-compose up -d
25+
make run
26+
curl localhost:5000
3727
```
3828

3929
## Scale up the app with Docker Compose
@@ -63,13 +53,15 @@ kubectl describe svc phippy
6353
kubectl get nodes
6454
curl <NODE_IP>:<NODEPORT>
6555
```
56+
6657
## Optional - deploy app via ingress
6758

6859
```
6960
kubectl apply -f kubernetes/ingress
7061
```
7162

7263
## Test the app by accessing the ingress name and port
64+
7365
```
7466
kubectl get ingress
7567
kubectl describe ingress phippy

app/__init__.py

Whitespace-only changes.

app/__version__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__version__="1.0"

app/app.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import os
2+
import platform
3+
from prometheus_client import generate_latest, CONTENT_TYPE_LATEST, REGISTRY
4+
from flask import Flask, Response, render_template
5+
from redis import Redis
6+
from app.__version__ import __version__
7+
from app.monitoring import register_metrics
8+
9+
app = Flask(__name__)
10+
redis = Redis(host=os.environ.get('REDIS_HOST', 'redis'), port=int(os.environ.get('REDIS_PORT', 6379)))
11+
redis.set('hits', 0)
12+
register_metrics(app, app_version=__version__)
13+
14+
@app.route('/', methods=['POST'])
15+
def hits_post():
16+
redis.incr('hits')
17+
hits = int(redis.get('hits'))
18+
19+
if hits % 5 == 0:
20+
return render_template("index.html", picture="/static/images/not_ok.png", message="You can do better!")
21+
return render_template("index.html", picture="/static/images/ok.jpg", message="You hit me %s times." % hits)
22+
23+
24+
@app.route('/', methods=['GET'])
25+
def hits_get():
26+
hits = int(redis.get('hits'))
27+
return render_template("index.html", picture="/static/images/ok.jpg", message="You hit me %s times." % hits)
28+
29+
30+
@app.route('/version')
31+
def version():
32+
return "version=" + __version__
33+
34+
35+
@app.route('/healthz')
36+
def healthz():
37+
if redis.ping():
38+
return "healthy"
39+
else:
40+
return "unheathy"
41+
42+
43+
@app.route('/node')
44+
def node():
45+
return platform.node()
46+
47+
48+
@app.route('/metrics')
49+
def metrics():
50+
return Response(generate_latest(), mimetype=CONTENT_TYPE_LATEST)
51+
52+
53+
@app.errorhandler(500)
54+
def handle_500(error):
55+
return str(error), 500

app/monitoring.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import logging
2+
from flask import request
3+
from prometheus_client import Counter, Histogram, Info
4+
from timeit import default_timer
5+
6+
logger = logging.getLogger(__name__)
7+
8+
APP_NAME = "phippy"
9+
APP_INFO = Info("app_version", "Aplication Version")
10+
11+
ERROROS_COUNT = Counter(
12+
"errors_total",
13+
"Number of errors",
14+
["app", "verb", "endpont", "status"]
15+
)
16+
REQUESTS_COUNT = Counter(
17+
"request_total",
18+
"Request duration in seconds",
19+
["app", "verb", "endpoint", "status"]
20+
)
21+
REQUEST_DURATION_HISTOGRAM = Histogram(
22+
"request_duration_seconds",
23+
"Request duration in seconds",
24+
["app", "verb", "endpoint", "status"]
25+
)
26+
27+
28+
29+
def before_request():
30+
"""
31+
Get start time of a request
32+
"""
33+
request._prometheus_metrics_request_start_time = default_timer()
34+
35+
36+
def after_request(response):
37+
"""
38+
Register Prometheus metrics after each request
39+
"""
40+
if hasattr(request, "_prometheus_metrics_request_start_time"):
41+
request_latency = max(
42+
default_timer() - request._prometheus_metrics_request_start_time, 0
43+
)
44+
REQUEST_DURATION_HISTOGRAM.labels(
45+
APP_NAME,
46+
request.method,
47+
request.endpoint,
48+
response.status_code,
49+
).observe(request_latency)
50+
REQUESTS_COUNT.labels(
51+
APP_NAME,
52+
request.method,
53+
request.endpoint,
54+
response.status_code,
55+
).inc()
56+
return response
57+
58+
59+
def register_metrics(app, app_version=None, app_config=None):
60+
"""
61+
Register metrics middlewares
62+
Flask application can register more than one before_request/after_request.
63+
Beware! Before/after request callback stored internally in a dictionary.
64+
Before CPython 3.6 dictionaries didn't guarantee keys order, so callbacks
65+
could be executed in arbitrary order.
66+
"""
67+
68+
app.before_request(before_request)
69+
app.after_request(after_request)
70+
# APP_INFO.info({"version": app_version, "config": app_config})
71+
File renamed without changes.
File renamed without changes.

app/templates/index.html

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{% block content %}
2+
<body>
3+
<h1>{{ message }}</h1>
4+
5+
<img src="{{picture}}" alt="Smiley face" height="300" width="350">
6+
</body>
7+
{% endblock %}

dcos/app.json

-36
This file was deleted.

dcos/db.json

-30
This file was deleted.

docker-compose.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: "3.7"
2+
3+
services:
4+
web:
5+
image: hlesey/phippy:1.0
6+
environment:
7+
REDIS_HOST: redis
8+
REDIS_PORT: 6379
9+
FLASK_ENV: development
10+
ports:
11+
- "5000:5000"
12+
networks:
13+
- phippy
14+
depends_on:
15+
- redis
16+
redis:
17+
image: hlesey/redis:4
18+
ports:
19+
- "6379:6379"
20+
networks:
21+
- phippy
22+
networks:
23+
phippy:
24+
name: phippy

0 commit comments

Comments
 (0)