Docker容器技术-创建一个简单的Web应用
一、创建一个简单的Web应用
1.identicon
基于某个值而自动产生的图像,这个值是IP地址或用户名的散列值。
用途:
通过计算用户名或IP地址的散列值,在网站上提供用于识别用户的图像,以及自动生成网站的favicon。
2.创建一个基本网页
[root@bogon app]# cat identidock.py
from flask import Flask
app = Flask(__name__)
default_name = 'Xiaoda'
@app.route('/')
def mainpage():
name = default_name
header = '<html><head><title>Identidock</title></head><body>'
body = '''<form method="POST">
Hello <input type="text" name="name" value="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>'
return header + body + footer
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0')
[root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
- "6900:6900"
environment:
ENV: DEV
volumes:
- ./app:/app
[root@bogon identidock]# docker-compose up -d
Building identidock
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> b13830295303
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in 8d69046d66d7
---> 92852ec52596
Removing intermediate container 8d69046d66d7
Successfully built 92852ec52596
Successfully tagged identidock_identidock:latest
WARNING: Image for service identidock was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating identidock_identidock_1 ...
Creating identidock_identidock_1 ... done
2.利用现有镜像
[root@bogon app]# cat identidock.py
from flask import Flask,Response
import requests
app = Flask(__name__)
default_name = 'Xiaoda'
@app.route('/')
def mainpage():
name = default_name
header = '<html><head><title>Identidock</title></head><body>'
body = '''<form method="POST">
Hello <input type="text" name="name" value="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>'
return header + body + footer
@app.route('/monster/<name>')
def get_identicon(name):
r = requests.get('http://dnmonster:8080/monster/' + name + '?size=80')
image = r.content
return Respinse(image, mimetype='image/png')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
[root@bogon identidock]# cat Dockerfile.1031
FROM python:3.4
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8 requests==2.5.1
WORKDIR /app
COPY app /app
EXPOSE 9090 9191
USER uwsgi
CMD ["/cmd.sh"]
[root@bogon identidock]# docker build -t identidock .
Sending build context to Docker daemon 7.168kB
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> 3080bcfb4b16
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in ea63b5069cc2
---> 3966bef511e5
Removing intermediate container ea63b5069cc2
Successfully built 3966bef511e5
Successfully tagged identidock:latest
[root@bogon identidock]# docker run -d --name dnmonster amouat/dnmonster:1.0
Unable to find image 'amouat/dnmonster:1.0' locally
1.0: Pulling from amouat/dnmonster
a3ed95caeb02: Pull complete
453d13af6c96: Pull complete
Digest: sha256:e9e991ffa0d05583af0ed0541d03c519d37762750c462bd86b3546f600e11231
Status: Downloaded newer image for amouat/dnmonster:1.0
4136951e5602ccb1939a0d47552b0fc9f2bf217baef640837e152cb09e5fdc11
[root@bogon identidock]# docker run -d -p 6800:6800 -e "ENV=DEV" --link dnmonster:dnmonster identidock
dd27f8941770b13b18a3b48157f440f91081a73655bc7ca25a11dcf1c244ddcb
改进版:
[root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
- "6900:6900"
environment:
ENV: DEV
volumes:
- ./app:/app
links:
- dnmonster
dnmonster:
image: amouat/dnmonster:1.0
[root@bogon identidock]# docker rm $(docker stop $(docker ps -q))
dd27f8941770
4136951e5602
f0a6553a9c33
[root@bogon identidock]# docker-compose build
dnmonster uses an image, skipping
Building identidock
Step 1/5 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/5 : RUN pip install Flask==0.10.1 uWSGI==2.0.8
---> Using cache
---> bb39db2742b4
Step 3/5 : WORKDIR /app
---> Using cache
---> 7159f825056f
Step 4/5 : COPY app /app
---> 4258a3f27a07
Step 5/5 : CMD uwsgi --http 0.0.0.0:9090 --wsgi-file /app/identidock.py --callable app --stats 0.0.0.0:9191
---> Running in 7898c0f79b37
---> 6eda3dd73c7a
Removing intermediate container 7898c0f79b37
Successfully built 6eda3dd73c7a
Successfully tagged identidock_identidock:latest
[root@bogon identidock]# docker-compose up -d
Creating identidock_dnmonster_1 ...
Creating identidock_dnmonster_1 ... done
Creating identidock_identidock_1 ...
Creating identidock_identidock_1 ... done
[root@bogon app]# cat identidock.py
from flask import Flask,Response
import requests
import hashlib
app = Flask(__name__)
salt = "UNIQUE_SALT"
default_name = 'Xiaoda'
@app.route('/')
def mainpage():
name = default_name
if request.method == 'POST':
name = request.form['name']
salted_name = salt + name
name_hash = hashlib.sha256(salted_name.encode()).hexdigest()
header = '<html><head><title>Identidock</title></head><body>'
body = '''<form method="POST">
Hello <input type="text" name="name" value="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>'
return header + body + footer
@app.route('/monster/<name>')
def get_identicon(name):
r = requests.get('http://dnmonster:8080/monster/' + name + '?size=80')
image = r.content
return Respinse(image, mimetype='image/png')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
二、实现缓存功能
1.在一个容器中运行多个进程
使用进程管理器supervisord,负责进程的启动和监视。
[root@bogon app]# cat identidock.py
from flask import Flask,Response
import requests
import hashlib
import redis
app = Flask(__name__)
cache = redis.StrictRedis(host='redis',port=6379,db=0)
salt = "UNIQUE_SALT"
default_name = 'Xiaoda'
@app.route('/',methods=['GET','POST'])
def mainpage():
name = default_name
if request.method == 'POST':
name = request.form['name']
salted_name = salt + name
name_hash = hashlib.sha256(salted_name.encode()).hexdigest()
header = '<html><head><title>Identidock</title></head><body>'
body = '''<form method="POST">
Hello <input type="text" name="name" value="{}">
<input type="submit" value="submit">
</form>
<p>You look like a:
<img src="/monster/monster.png"/>
'''.format(name)
footer = '</body></html>'
return header + body + footer
@app.route('/monster/<name>')
def get_identicon(name):
image = cache.get(name)
if image is None:
print("Cache miss",flush=True)
r = requests.get('http://dnmonster:8080/monster/' + name + '?size=80')
image = r.content
cache.set(name,image)
return Respinse(image, mimetype='image/png')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
[root@bogon identidock]# cat Dockerfile.1031
FROM python:3.4
RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
RUN pip install Flask==0.10.1 uWSGI==2.0.8 requests==2.5.1 redis==2.10.6
WORKDIR /app
COPY app /app
COPY cmd.sh /
EXPOSE 9090 9191
USER uwsgi
CMD ["/cmd.sh"]
[root@bogon identidock]# cat docker-compose.yml
identidock:
build: .
ports:
- "7000:7000"
environment:
ENV: DEV
volumes:
- ./app:/app
links:
- dnmonster
- redis
dnmonster:
image: amouat/dnmonster:1.0
redis:
image: redis:3.0
[root@bogon identidock]# docker-compose build
dnmonster uses an image, skipping
redis uses an image, skipping
Building identidock
Step 1/9 : FROM python:3.4
---> 9ff45ddb54e9
Step 2/9 : RUN groupadd -r uwsgi && useradd -r -g uwsgi uwsgi
---> Using cache
---> 1aa7c9d755eb
Step 3/9 : RUN pip install Flask==0.10.1 uWSGI==2.0.8 requests==2.5.1 redis==2.10.6
---> Running in 107013f2d391
Collecting Flask==0.10.1
Downloading Flask-0.10.1.tar.gz (544kB)
Collecting uWSGI==2.0.8
Downloading uwsgi-2.0.8.tar.gz (775kB)
Collecting requests==2.5.1
Downloading requests-2.5.1-py2.py3-none-any.whl (464kB)
Collecting redis==2.10.6
Downloading redis-2.10.6-py2.py3-none-any.whl (64kB)
Collecting Werkzeug>=0.7 (from Flask==0.10.1)
Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting Jinja2>=2.4 (from Flask==0.10.1)
Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting itsdangerous>=0.21 (from Flask==0.10.1)
Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->Flask==0.10.1)
Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: Flask, uWSGI, itsdangerous, MarkupSafe
Running setup.py bdist_wheel for Flask: started
Running setup.py bdist_wheel for Flask: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/b6/09/65/5fcf16f74f334a215447c26769e291c41883862fe0dc7c1430
Running setup.py bdist_wheel for uWSGI: started
Running setup.py bdist_wheel for uWSGI: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/04/43/f1/b6308e3b9ea71a31b9e5b69b6fe50bea89e852688bf46e8b92
Running setup.py bdist_wheel for itsdangerous: started
Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
Running setup.py bdist_wheel for MarkupSafe: started
Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built Flask uWSGI itsdangerous MarkupSafe
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask, uWSGI, requests, redis
Successfully installed Flask-0.10.1 Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 itsdangerous-0.24 redis-2.10.6 requests-2.5.1 uWSGI-2.0.8
---> 25710c7b3813
Removing intermediate container 107013f2d391
Step 4/9 : WORKDIR /app
---> 9178ae566c42
Removing intermediate container 541c592bf996
Step 5/9 : COPY app /app
---> 756498c4229c
Step 6/9 : COPY cmd.sh /
---> 67416d7b3c6b
Step 7/9 : EXPOSE 9090 9191
---> Running in e3fb71c7cb6a
---> e9c0c03315ad
Removing intermediate container e3fb71c7cb6a
Step 8/9 : USER uwsgi
---> Running in f952ebf8f50b
---> 732e703b3373
Removing intermediate container f952ebf8f50b
Step 9/9 : CMD /cmd.sh
---> Running in 9943687a5efa
---> 94f20e22970d
Removing intermediate container 9943687a5efa
Successfully built 94f20e22970d
Successfully tagged identidock_identidock:latest
[root@bogon identidock]# docker-compose up -d
Pulling redis (redis:3.0)...
3.0: Pulling from library/redis
f5cc0ee7a6f6: Pull complete
5fc25ed18e87: Pull complete
e025bc8872f6: Pull complete
77c68b51b836: Pull complete
7c403ece3755: Pull complete
0a653bd338f4: Pull complete
31531fd948c6: Pull complete
Digest: sha256:730b765df9fe96af414da64a2b67f3a5f70b8fd13a31e5096fee4807ed802e20
Status: Downloaded newer image for redis:3.0
Starting identidock_dnmonster_1 ...
Starting identidock_dnmonster_1
Creating identidock_redis_1 ...
Creating identidock_redis_1 ... done
Recreating identidock_identidock_1 ...
Recreating identidock_identidock_1 ... done
三、微服务
微服务:由多个独立的小服务组成;
单一服务架构:该系统包含在一个单独的大型的服务之中(dnmonster、redis和identidock使用同一种编程语言实现)。
优点:
- 适合横向扩展到多态机器
- 轻松快速地被其他效能更高且功能相同的服务替代
- 若发生意外,可只对部分微服务进行回滚
- 不同微服务可以用不同的语言实现,使开发者更好适用任务语言
缺点:
- 分布式组件所导致的额外开销
- 通信必须通过网络,而不是库的调用
- 服务编排和服务发现
Docker容器技术-创建一个简单的Web应用的更多相关文章
- 利用HTML5与jQuery技术创建一个简单的自动表单完成
来源:GBin1.com 在线演示 在线下载 谷歌快速搜索自带大量自动完成插件——库中甚至还有一个附带的jQuery UI共享选项.然而今天我要寻找一个替代的解决方案.由DevBridge开发的j ...
- IntelliJ IDEA 15 部署Tomcat及创建一个简单的Web工程
一.部署Tomcat 二.创建一个简单的Web工程 2.1创建一个新工程 创建一个新工程 设置JDK及选择Web Application (创建的是Web工程) 点击Next,选择工作空间,起个工程名 ...
- Symfony2之创建一个简单的web应用
Symfony2——创建bundle bundle就像插件或者一个功能齐全的应用,我们在应用层上开发的应用的所有代码,包括:PHP文件.配置文件.图片.css文件.js文件等都会包含在bu ...
- 使用 CodeIgniter 创建一个简单的 Web 站点
原文:使用 CodeIgniter 创建一个简单的 Web 站点 参考源自: http://www.ibm.com/developerworks/cn/web/wa-codeigniter/index ...
- SharePoint 创建一个简单的Web Part 部分
SharePoint 创建一个简单的Web Part 部分 标准Web零件有时会很强大,运行多个功能的能力. 本文介绍了如何使用Visual Studio 创建一个简单的Web部分. 1. 打开VS, ...
- 用 Eclipse 创建一个简单的web项目
Eclipse neon 汉化版 ; 1;右击新建 --> 选择 动态Web项目 2: 填写 项目名 项目位置 ; 选择 Dynamic web module version 和 tomca ...
- django创建一个简单的web站点
一.新建project 使用Pycharm,File->New Project…,选择Django,给project命名 (project不能用test命名) 新建的project目录如下: ...
- node创建一个简单的web服务
本文将如何用node创建一个简单的web服务,过程也很简单呢~ 开始之前要先安装node.js 1.创建一个最简单的服务 // server.js const http = require('http ...
- Symfony2之创建一个简单的web应用 Symfony2——创建bundle
bundle就像插件或者一个功能齐全的应用,我们在应用层上开发的应用的所有代码,包括:PHP文件.配置文件.图片.css文件.js文件等都会包含在bunde系统中. 可以通过两种方法 ...
随机推荐
- IE6鼠标悬停Bug
当鼠标放置于某个文字链接之上,文字或文字背景改变为其他颜色或样式的效果是我们最经常见到的鼠标悬停效果.在CSS中,这个效果靠伪元素:hover来实现,只不过在文字链接中:hover被应用在了锚点元素& ...
- pycharm2018.1.4激活破解方法与汉化包-2018年6月19日
记录下来备用,顺便分享给大家,有能力的还是希望能够支持正版!支持正版!支持正版! 方法1:激活服务器,最简单快速(截止2018年6月19日可用) 在激活Jetbrains旗下任意产品的时候选择激活服务 ...
- virtualenv使用说明
创建虚拟环境virtualenv [虚拟环境名称] 如:virtualenv ENV 启动虚拟环境 cd ENV source ./bin/activate 注意此时命令行会多一个(ENV),ENV为 ...
- 这篇文章主要为大家详细介绍了jQuery密码强度验证控件使用详解的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了jQuery密码强度验证控件,供大家参考,具体内容如下 <html> <head> <meta http-equiv="Cont ...
- day12闭包,装饰器
一.闭包:内部函数引用了外部函数的变量. # f1() #闭包的定义 #内部的函数引用了外部函数的变量 # def f1(b): #闭包的常用状态 # def f2(): # print(b) # r ...
- pyhon多进程知识整理
多进程概要: 在Unix/Linux下,可以使用fork()调用实现多进程. 要实现跨平台的多进程,可以使用multiprocessing模块. 进程间通信是通过Queue.Pipes等实现的. 要让 ...
- Laravel创建模型
laravel中创建模型 <?php /** * Created by PhpStorm. * 新建模型 * User: chuang * Date: 17-1-15 * Time: 上午9:1 ...
- cocos2d-x - android 学习(集成NDK、配置开发环境)
先来贴上一大神的博客:日月之明 --- http://www.cnblogs.com/lhming/tag/cocs2d-x/ 需要工具和软件包:Eclipse.Android SDK.Android ...
- java编程:将数组的第一个为最大第二个为最小以此类推
import java.util.Scanner; public class Max_Min { public static void main(String[] args) { int[] a = ...
- Jmeter与LoadRunner 测试Java项目的坑
32位的JDK,Jmeter.bat 最大内存只能配置1G,测不了大并发,所以用Jmeter测试时一定要改成64位的Jmeter用LR测试java程序的时候必须用32位的JDK 环境变量 在path的 ...