1.避免每次更新代码后都重新安装依赖
最简单的Dockerfile指令打包一个项目(以某python项目为例):
# 选择一个基础镜像 FROM python:3.6 # 设置虚拟机中的工作路径 WORKDIR /qqzone # 将当前目录下所有文件拷贝到工作路径中 COPY . /qqzone # 执行命令,安装依赖 RUN pip install -r requirements.txt # 执行命令,启动服务 CMD python src/web/server.py
但是这样存在一个巨大的问题,每次更新代码后重新build镜像都会重新安装依赖,会浪费大量时间
有两种途径可以解决这个问题,一是将安装依赖后的环境打包为一个镜像,但是这样做显然有点麻烦,并且每次更新依赖后都得重新打包,因此推荐下面这种方式:使用缓存
只需要更改上面的Dockerfile命令如下:
FROM python:3.6 WORKDIR /qqzone # 先将依赖文件拷贝到项目中 COPY requirements.txt /qqzone # 执行指令,安装依赖 RUN pip install -i -r requirements.txt # 拷贝项目文件和代码 COPY . /qqzone CMD python src/web/server.py
与之前代码不同的是,先单独拷贝依赖文件(requirements.txt)到docker中,再立即安装依赖。由于通常在更新代码之后,依赖文件并没有改变(改变的代码部分在下一步才会被拷贝到镜像中),因此docker在build中会显示“using cache”(调用缓存),从而避免了重新安装依赖。
2. 配置国内Docker镜像(阿里云)
默认的docker镜像在国外,特别慢。这里改为阿里云的镜像,如果是部署到阿里云的服务器的话,速度飞快。
vim /etc/docker/daemon.json
添加如下内容:
{ "registry-mirrors": [ "https://kfwkfulq.mirror.aliyuncs.com", "https://2lqq34jg.mirror.aliyuncs.com", "https://pee6w651.mirror.aliyuncs.com", "https://registry.docker-cn.com", "http://hub-mirror.c.163.com" ], "dns": ["8.8.8.8","8.8.4.4"] }
3.修改Docker0默认网段
这简直是个神坑,遇见的情况很罕见!
docker 默认的网络模式是桥接模式,它会在启动时创建一个虚拟的以太网桥,docker0。这个docker0的默认网段是:172.17.0.1/16
一般是没什么问题的,然而,很不幸,这和我们学院提供的免费云服务器的网段冲突了……这就会导致一旦在这个服务器上开启docker,服务器和docker都无法访问(最直接的表现就是ssh直接中断,但还是能通过VNC访问)。所以,这个时候最简单的解决方式就是修改docker的默认网段。
vim /etc/docker/daemon.json
添加如下内容:
{
"bip":"192.168.100.1/24"
}
其中ip和网关都可以自己选,只要不和宿主机的网段冲突就行
4.docker-compose
docker-compose是用来同时启动多个docker容器的工具。比如我写了一个爬虫项目,需要访问redis,最好的方法就是把爬虫项目和redis分布打包为docker镜像,然后用docker-compose来管理(构建、启动、停止等)。
docker-compose 使用yaml做为配置文件,使用时需要和在Dockerfile同一路径下新建文件docker-compose.yml,下面给出一个简单的示例:
version: '2'
services:
web:
build: .
ports:
- "80:5000"
volumes:
- .:/qqzone
depends_on:
- redis
redis:
image: redis
command: redis-server
这里定义了两个镜像,web和redis,其中web是需要构建,redis直接从远程仓库下载镜像,注意其中的depends_on,它表示web模块依赖于redis。
5.访问docker中的redis(Docker 中出现Redis Connection refused)
一般情况下,python连接redis的核心代码如下(使用连接池):
pool = redis.ConnectionPool(host="127.0.0.1", port=6379, decode_responses=True) conn = redis.Redis(connection_pool=pool)
127.0.0.1表示的是本地访问,但是在docker-compose 启动程序之后,由于redis和web容器其实属于两个不同的镜像,就是两个不同的虚拟机,所以web容器中再使用127.0.0.1访问redis时就会出现Connection refused。所以,此时应该把host替换为镜像的名称,默认是“redis”。即:
pool = redis.ConnectionPool(host="redis", port=6379, decode_responses=True) conn = redis.Redis(connection_pool=pool)
参考博客:Docker Redis Connection refused解决方法
但这样也有不方便的地方,比如我在本地开发时,是用pyCharm直接运行,线上部署才是用的docker,这意味着我需要频繁手动更换host,所以我写了一个用于判断当前应该连接哪个host的函数:
(其中get_pool()和get_docker_pool()是返回两个不同的redis连接池)
本质上就是用try except的方法试一下哪个host能正常连接,然后将正确的结果保存下来。因为我开发的是web程序,所以将结果保存在session中,避免频繁的进行判断。
6.清理无用的docker镜像
使用docker在build镜像时,由于各种各样的原因,经常产生一些失败的镜像,并且这些镜像往往体积很大,非常浪费硬盘空间,所以最好经常清理。
查看全部镜像:
docker images
其中REPOSITORY和TAG都为none的镜像就是垃圾镜像,可以使用docker rmi <IMAGE ID> 删除
7.Docker 中使用apt-get 安装东西显示没有public key,
参考:
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak RUN echo "deb http://mirrors.ustc.edu.cn/ubuntu/ trusty main restricted universe multiverse\n\ deb http://mirrors.ustc.edu.cn/ubuntu/ trusty-security main restricted universe multiverse\n\ deb http://mirrors.ustc.edu.cn/ubuntu/ trusty-updates main restricted universe multiverse\n\ deb http://mirrors.ustc.edu.cn/ubuntu/ trusty-proposed main restricted universe multiverse\n\ deb http://mirrors.ustc.edu.cn/ubuntu/ trusty-backports main restricted universe multiverse\n\ deb-src http://mirrors.ustc.edu.cn/ubuntu/ trusty main restricted universe multiverse\n\ deb-src http://mirrors.ustc.edu.cn/ubuntu/ trusty-security main restricted universe multiverse\n\ deb-src http://mirrors.ustc.edu.cn/ubuntu/ trusty-updates main restricted universe multiverse\n\ deb-src http://mirrors.ustc.edu.cn/ubuntu/ trusty-proposed main restricted universe multiverse\n\ deb-src http://mirrors.ustc.edu.cn/ubuntu/ trusty-backports main restricted universe multiverse\n\ " > /etc/apt/sources.list RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32 RUN apt-get update --allow-unauthenticated
点击量:18472
1 条评论
【特性还是bug?】Docker-compose 网段冲突,即使修改了默认网段也不行 – 小麦冬 · 2019年12月28日 下午8:59
[…] 一般情况下网段冲突都可以通过这篇文章第3小节中介绍的方法来解决,但是在使用docker-compose的时候,偶尔会有一种情况居然无法解决。 […]