本次作业为Python专题。Python是将练习使用docker容器运行Python程序。Python是很常用的程序设计语言,但是Python程序的运行依赖于提前的系统环境配置,为了降低系统配置的复杂度,同时减小资源开销,将系统环境容器化是一种解决方案。请根据Python官方镜像的镜像说明,自定义Python镜像文件,将Python程序运行起来。
1.项目结构
首先我们先建立好文件结构,便于后续实验
2.搭建python镜像
Dockerfile
FROM python:3
MAINTAINER qaq
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --default-timeout=100 --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
VOLUME /usr/src/app
ENTRYPOINT [ "python" ] # 实现命令行式调用容器
CMD ["python"]
requirements.txt
PyMySQL
opencv-python
搭建镜像
这里需要在root下运行
docker build -t docker:py .
创建一个网络,接下来的Mysql和Python容器均要运行在同一个网络中才能相互访问。
docker network create --subnet=172.1.0.0/16 py_mysql
3、简单程序的部署运行
helloworld
#hello.py
print('hello world!')
print('hello world!!')
print('hello world!!!')
sudo docker run --rm -v /home/qinhonghao/dockpy/app:/usr/src/app docker:py hello.py
日历输出
#date.py
import calendar
year = int(input("输入年份: "))
month = int(input("输入月份: "))
print(calendar.month(year,month))
sudo docker run -it --rm -v /home/qinhonghao/dockpy/app:/usr/src/app docker:py date.py
mysql数据库操作
先开启一个数据库容器,可以用之前搭建好的(例如上次试验创建的mysql容器)
docker start 容器id
测试数据库连接
#ms1.py
#!/usr/bin/python3
import pymysql
# 打开数据库连接
db = pymysql.connect(host="mysql",user="root",password="123456",database="docker_mysql" )
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
# 使用 execute() 方法执行 SQL 查询
cursor.execute("SELECT VERSION()")
# 使用 fetchone() 方法获取单条数据.
data = cursor.fetchone()
print ("Database version : %s " % data)
# 关闭数据库连接
db.close()
sudo docker run -it --rm -v /home/qinhonghao/dockpy/app:/usr/src/app --link=mysql --net compose4_webnet docker:py ms1.py
这样就代表数据库连接成功了!!!
创建表和插入数据
#ms2.py
#!/usr/bin/python3
import pymysql
# 打开数据库连接
db = pymysql.connect(host="mysql",user="root",password="123456",database="docker_mysql" )
# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()
# 使用 execute() 方法执行 SQL,如果表存在则删除
cursor.execute("DROP TABLE IF EXISTS STUDENT")
# 使用预处理语句创建表
sql = """CREATE TABLE STUDENT (
SNO CHAR(20) NOT NULL,
SNAME CHAR(20),
AGE INT,
SEX CHAR(1),
SDEPT CHAR(20),
GRADE INT )"""
cursor.execute(sql)
# SQL 插入语句
sql1 = """INSERT INTO STUDENT(SNO, SNAME,
AGE, SEX, SDEPT, GRADE)
VALUES ('20200437', 'YMT', 20, 'F', 'NEWS', 98)"""
try:
# 执行sql语句
cursor.execute(sql1)
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
db.rollback()
# SQL 插入语句
sql2 = """INSERT INTO STUDENT(SNO, SNAME,
AGE, SEX, SDEPT, GRADE)
VALUES ('20200101', 'QHH', 20, 'M', 'CS', 99)"""
try:
# 执行sql语句
cursor.execute(sql2)
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
db.rollback()
# 关闭数据库连接
db.close()
这里不知道为什么会出现warning,但是不影响表的创建和数据的插入。
查询表中某条数据
#ms3.py
#!/usr/bin/python3
import pymysql
# 打开数据库连接
db = pymysql.connect(host="mysql",user="root",password="123456",database="docker_mysql" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 查询语句
sql = "SELECT * FROM STUDENT
WHERE GRADE > %s" % (98)
try:
# 执行SQL语句
cursor.execute(sql)
# 获取所有记录列表
results = cursor.fetchall()
for row in results:
sno = row[0]
sname = row[1]
age = row[2]
sex = row[3]
sdept = row[4]
grade = row[5]
# 打印结果
print ("sno=%s,sname=%s,age=%s,sex=%s,sdept=%s,grade=%s" %
(sno, sname, age, sex, sdept, grade ))
except:
print ("Error: unable to fetch data")
# 关闭数据库连接
db.close()
可以看到,我想查询的数据已经得到了。
修改数据库中STUDENT表的数据
#ms4.py
#!/usr/bin/python3
import pymysql
# 打开数据库连接
db = pymysql.connect(host="mysql",user="root",password="123456",database="docker_mysql" )
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 更新语句
sql1 = "UPDATE STUDENT SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
# 执行SQL语句
cursor.execute(sql1)
# 提交到数据库执行
db.commit()
except:
# 发生错误时回滚
db.rollback()
# SQL 更新语句
sql2 = "UPDATE STUDENT SET GRADE = 100 WHERE SNAME = '%s'" % ('YMT')
try:
# 执行SQL语句
cursor.execute(sql2)
# 提交到数据库执行
db.commit()
except:
# 发生错误时回滚
db.rollback()
# 关闭数据库连接
db.close()
数据库中STUDENT表数据的更新已经成功。
opencv程序
函数 cv2.moments() 会将计算得到的矩以一个字典的形式返回
#cvv.py
import cv2
import numpy as np
img = cv2.imread('test.jpg',0)
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv2.moments(cnt)
print (M)
sudo docker run --rm -v /home/qinhonghao/dockpy/app:/usr/src/app docker:py cvv.py
4、遇到的问题和解决方法
1、运行hello.py失败
解决办法:我把Dockerfile里面的工作目录WORKDIR换成/usr/src/app,重启docker就好了
2、日历运行错误
解决办法:这里错误的原因是我把运行hello.py的命令复制粘贴了过来只改了文件名,所以我在docker run 后面加上-it,表示声明需要交互式终端,然后才正确运行了,可以输入。
3、数据库连接错误1
解决办法:我百度后发现原因是,Docker 在启动一个容器时,会为其创建一个默认网络-containerName_defaul,所以使用--link方式互联容器时由于默认不在一个网络中,会报上述错误,解决办法:docker inspect [需要link的容器名称或ID]
,查看要link的容器的网络名称,例如下图的红框中标注的bridge,然后添加--net 容器名称,使新的container与link目标在同一个网络中。比如我的就改成这样
sudo docker run -it --rm -v /home/qinhonghao/dockpy/app:/usr/src/app --link=mysql --net compose4_webnet docker:py ms1.py
4、数据库连接错误2
解决办法:这里的错误在于docker_mysql数据库还没创建,所以create database docker_mysql
创建就可以了
5、时间花费
(1)搭建镜像:大约20min
(2)程序部署:大约4h
(3)编写博客:大约1h10min
总计:大约5.5h
6、感想总结
这次作业总体量不多,难度也不大,但是总是会出现各种莫名其妙的意外错误,总之不论如何,要学会自己单独寻找方法、解决问题。