关于如何在windows下安装docker
本文着重阐述如何将docker实用起来
大家在协同开发过程中,通常会遇到各人开发环境不同,导致本地部署开发环境浪费时间、扩展库有差异、甚至系统不同等问题,docker就是为了解决这些问题、快速开发环境、让开发人员迅速进入开发状态而生的
Docker是一个基于Go语言的开源应用容器引擎,可以自动化地部署应用到可移植的的容器中,这些容器独立于硬件、语言、框架、打包系统。
一个标准的Docker容器包含一个软件组件及其所有的依赖——二进制文件,库,配置文件,脚本等等。
Docker扩展了LXC(Linux Container),使用高层的API,提供轻量虚拟化解决方案来实现进程间隔离。可以运行在任何支持cgroups(control groups)跟AUFS的64位Linux内核上。
LXC是docker的核心技术,借助于namespace的隔离机制和cgroup限额功能,提供了一套统一的API和工具来建立和管理container。(类Hypervisor)
Linux Namespace (ns)
Control Groups (cgroups)
LXC 旨在提供一个共享kernel的OS级虚拟化方法,在执行时不用重复加载kernel, 且container的kernel与host共享,因此可以大大加快container的启动过程,并显著减少内存消耗。
在LXC的基础上, Docker额外提供的Feature包括
1、标准统一的打包部署运行方案
2、历史版本控制
3、Image的重用
4、Image共享发布等。
下面是本文重点,安装好docker后如何快速进入开发状态,仅针对web开发:
开始讲述之前,要再次认识到docker只是一个在虚拟机中运行的系统底层,是连接上层宿主windows和下层开发环境容器,container(即开发环境容器)类似于子系统,是在docker虚拟机中像应用程序一样运行的隔离环境,和宿主系统的一切交互都要通过处于中间层的docker,并且默认都是关闭的,可以理解为好多个沙盒
web开发涉及到web服务器和项目代码和数据库,我们一项一项来解决
本文假定docker虚拟机启动后的绑定ip为192.168.59.103
1、web服务器
一、安装nginx并设置端口映射
一开始docker安装好并且启动container后,container内的服务端口(例如nginx启动后监听的80端口)是不对外暴露的,在宿主windows下用浏览器访问docker虚拟机ip是访问不到container内的80端口的
必须做端口映射操作,只要在container启动时,docker run命令带上端口映射参数就可以了:
docker run -it -p 22222:33333 fe65a2781dae /bin/bash
解释:
-it参数在启动container为tty形式时必带,否则无法做命令行交互
-p 22222:33333 关键参数,指定docker虚拟机的22222端口,映射为container的33333端口,即对192.168.59.103:22222的访问,统统访问到container的33333端口。如果要映射80端口,设置-p 80:80就好
fe65a2781dae 指定docker要运行的imageid,也可以是REPOSITORY:TAG形式
/bin/bash docker启动container后要运行的命令,一般启动命令行交互就用这个就好了
所以要把nginx调通,要做以下步骤:
1、docker run -it -p 80:80 fe65a2781dae /bin/bash
2、container内运行nginx
3、宿主windows浏览器访问192.168.59.103
4、Welcome to nginx!
二、配置nginx在容器启动时自动启动
最简单的方法:
vi /etc/bashrc
添加一行类似
/usr/sbin/nginx -c /etc/nginx/nginx.conf
保存并推出
docker commit 保存容器修改,下次再启动容器时,自动就把nginx启动起来了,要添加其他自启动程序同样操作
docker commit 如何使用,不在本文范围,请自行百度
其他还有通过Dockerfile的方法,还有一种通过linux进程管理工具supervisor的方法
2、项目代码
docker只是一个开发环境的容器,一般不用来做代码持久化的容器,如果这样做,很容易丢代码,因为docker并不主动保存在container内的修改除非你手动操作
最好的解决办法就是,有一个共享文件夹,从宿主windows共享至container内,作为项目代码根目录
过程大致如下:
一、建立virtualbox和docker虚拟机的共享
可以参考http://jingyan.baidu.com/article/2fb0ba40541a5900f2ec5f07.html
打开virtualbox并且选择到boot2docker-vm虚拟机,右键点设置
- 点击共享文件夹设置框,右上角的添加按钮
- 选择之前本机设置的共享文件夹,此时一定不可以勾选自动挂载
-
设置好共享名后,进入docker虚拟机系统,打开终端,先执行命令,在挂载点目录添加“bdshare”目录,接着执行"mount -t vboxsf BaiduShare /mnt/bdshare/",就能完成共享文件夹的设置。请记住mount命令一定要带上参数-t vboxsf,BaiduShare就是共享文件夹名称,/mnt/bdshare/就是要在docker虚拟机中挂载的绝对路径 - docker虚拟机系统默认使用docker用户,可能会遇到Permission denied错误,即权限不足,需要切换到root账户操作,只要输入“sudo su”命令即可,无需密码
二、docker容器挂载docker虚拟机的目录
docker可以支持把一个宿主机上的目录挂载到镜像里。
docker run -it -v /home/dock/Downloads:/usr/Downloads ubuntu64 /bin/bash
通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径。
现在镜像内就可以共享宿主机里的文件了。
此处要挂载上一步virtualbox和docker虚拟机共享的文件夹,就在docker启动container时加上参数:
-v /mnt/bdshare/:/data
命令类似:
docker run -it -p 80:80 -v /mnt/bdshare/:/bdshare fe65a2781dae /bin/bash
这样就把宿主windows的K:\BaiduShare目录,挂载到了container的/bdshare目录
3、数据库
同样因为docker只是一个容器,不具备主动持久化的原因,所有会记录状态的数据(例如数据库)都无法被保存下来
解决的方法还是通过使用挂载的共享目录,将所有需要持久化的数据保存目录都放在共享目录中即可,下次container启动的时候挂载上共享目录,数据保持原样
4、docker虚拟机和container的持久化
我们可能想对docker虚拟机本身做些配置,以便在虚拟机启动时自动启动一些程序,比如自动挂载共享目录,正常的linux系统只要往/etc/fstab文件或者/etc/rc.local文件里写执行语句,系统启动时就会自动执行
但是往docker虚拟机的自启动文件里写语句的话,下次启动就不见了,这是为什么呢,是因为:
docker虚拟机里面跑的是TinyCoreLinux,这个OS的rootfs是临时性的(放在内存的,实际上就是boot2docker.iso文件里面的一个rootfs),因此其根目录/下的东西(包括/home)根本不会持久化,只有/mnt/sda1这个目录下的才能持久化。如果你放在/home目录下,只要VM一重启,就会丢失的,/mnt/sda1则不会,实际上就是那个~/.boot2docker-vm.vmdk文件挂载到了/mnt/sda1目录下
docker里跑的container只是docker系统底层的上层隔离沙盒,container里持久化的一切内容,最终都持久化到docker虚拟机里
这样方法就清楚了,没办法针对docker虚拟机做自启动配置,但是可以写好自启动的sh脚本,放在/mnt/sda1这个目录下,下次启动虚拟机时,手动切换到这个目录下运行sh脚本。目前没有找到更好的方法, 如果有更好的方法,欢迎告诉我谢谢
而container的持久化,除了挂载宿主windows的共享目录外,还有就是映射的目录设置到虚拟机的/mnt/sda1目录下,这两种方法一个是持久化到宿主系统中,一个是持久化到虚拟机的虚拟磁盘中。两种方法都可以,就看自己选择了
举例,我的/mnt/sda1/的sh脚本内容是:
sudo mount -t vboxsf sync /mnt/sync/ #挂载宿主windows的共享目录
docker run -it -p 80:80 -v /mnt/sync:/sync -v /mnt/sda1/data:/data centos:centos6 /bin/bash #映射共享目录,和虚拟机磁盘