Docker + Django 一周踩坑记

Stella981
• 阅读 554

    鉴于是公司的项目,项目源码不好公开,就专门讲踩坑的经历好了,我以前没有接触过docker,一直以为它是个轻量化的虚拟机,但在看了《docker - 从入门到实践》前言与介绍后,我意识到我的认识是不全面的,准确来说,docker是一个基于操作系统内核的虚拟化技术,能够低消耗地封装你想要的进程。以往的虚拟机都是在系统上又构建了一个完整的系统,自然耗费巨大,而docker则提供了一个可以让你随心所欲地称王的果壳,让每个进程在这个果壳中都能享有一个自己的宇宙,而这个果壳又立足于真正的宇宙--操作系统内核上。

    docker有三个重要概念:镜像,容器,仓库。按我的理解:

    镜像就是剧本,这个剧本描述了所有的场景布置(系统环境),演员结构(软件依赖),剧情设计(运行程序)等等,是果壳里这场戏的根本,没有剧本,就没有戏。

    容器就是实际演出,是剧本的实现,你作为导演,如果看的不爽,可以闯入进去,进行各种调整与改变,当你调整改变完了,你想沿用下来,那就commit作为新剧本。(但官方推荐使用Dockerfile,因为可以完整地再现一个剧本的创作,相当于给剧本作说明,要不然剧本就成为了黑盒子)

    仓库就是剧本存放箱子,各种各样的剧本都在这里,有的是同一场戏的,但是分新旧版本,你需要给剧本打上标签,标明它是哪个版本的,最近版本就叫latest,仓库的公开服务可以让你向全天下分享你的剧本,别人也可以拿过来就演,也可以改完再演,也可以改完变成新剧本,说到这里,感觉docker跟github的思想非常相近。

    不得不说linux下的docker安装真是轻松+写意,而windows下的docker安装简直就是灾难!虽然官方出了toolbox等一系列工具,做了很多兼容工作,但还是会偶尔出现一些问题(尤其是各种管理工具不能用),安装完docker后,我推荐使用docker管理工具DockerFly,作者helyho是个很不错的人哦。(实际上我是到都快整完了,才发现的。。。唉!早点发现能省多少事!)

    我的项目是使用Django框架开发,现阶段暂时是Django + uwsgi + nginx  + mysql,根据一些好的建议,我使用了多容器部署,这样可以使服务与数据分离,有极大的好处,但相对的,对于我这样的小白,就意味着要有更多的坑要踩。

    我按照这个教程来进行,但一开始就遇到麻烦,我的开发环境是使用conda管理的,其中一些conda找不到的包使用pip安装的,不得已就得自己在镜像中安装miniconda,但是在Dockerfile中安装miniconda真是坑多多,因为miniconda必须要通过sh脚本安装,它途中会各种乱七八糟地问你是否许可这个那个的,导致Docker build不能自动地运行下去,当时没有想到好的解决办法,只好去找miniconda的专门镜像,找到了continuumio/miniconda,但现在我知道,当时可以在运行容器中装好,然后重新生成新镜像。

    有了教程的帮助,我省了不少的力气,于是我在Dockerfile中乱写一气,把本该用bash脚本写的用来“临场指挥”的一些命令也全都用 RUN 写到了Dockerfile中,使得Dockerfile成了一锅杂烩,直到后来,我才知道,Dockerfile中有下面的东西,让你“临场指挥”用,例如启动nginx。

ENTRYPOINT [ "/usr/src/run.sh"]

CMD [ "/bin/bash" ]

    我的web容器要与mysql容器连通,才能让web操作数据库的数据,但即便在教程的帮助下,我依然无法将这两个牵到一起,像这样的代码

docker run --name mysql \
-p 3309:3306 \
-d daocloud.io/mysql:5.6.30 \

-p是将mysql的端口映射到本地,我以为让web程序访问3309的端口,就能连接到数据库,但事实是死活不通,我变换了各种接口,发现172.17.0.×是通的,原来那是docker容器的ip,顿时感觉找到希望和光明,但随即又想到,这是根据容器顺序配给的,mysql容器如果停止重启了,ip改变,难道还要去改程序不成?经过一连串的百度与论坛咨询,(开源中国回答我的技术问题的人实在不算多,也许是太low了),我才知道,我想要的,在docker中叫做容器互联,在我的代码中

docker run --name django \
--link mysql:mysql \
-p 2000:8000 \
-d mine/django-app \

--link就是干这个用的,host就是mysql,而-p映射的端口是给你在本地连接查看用的,不能用作容器互联。

    web容器终于运行起来了,但奇怪的是,容器运行不过几秒就自动退出,这令我倍感惊讶,百度后发现,docker的机制是这样的,docker容器是进程的容器,一个容器里可以运行多个进程,但最后一个运行的进程不能退出,否则进程退出后,容器也就退出了。在容器启动运行run.sh,进程的缺省设置是后台运行,这样导致run.sh运行结束,容器跟着run.sh退出而退出。因此,在run.sh中,最后的进程应强制采用前台运行,例如crond -f。这样run.sh就不会退出, docker run -d 运行时就可以保持容器后台运行。还有同志建议写个死循环

$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"

不过,我觉得不太好,我采用了tail -f ×××.log。   

    最后应该将web落到nginx上了,但nginx要定位static静态文件,但我又不愿意将static目录从web中抽出,放到nginx中(这样是不是好的?如果读者感觉不好,请在评论中指出),怎么好呢,docker的数据卷及时救援了我,docker的数据卷可以有效地解决多容器共享目录的问题,并且数据卷的更新,不会影响到容器,使用-v标记创建数据卷挂载到容器里,也可以挂载一个本地目录到容器,于是我

docker run --name django \
-v /usr/src/backend \
-v /usr/src/backend/static \
-d mine/django-app \

而nginx则使用 --volumes-from django 从而可以访问到静态文件与web目录。

经过这一周的踩坑,我对docker有了初步的了解,有不少心得体会,也还有好多不足,要学习一项新的技术,果然要走不少弯路,docker虚拟化技术的前途,可见其光明。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
4个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这