关于如何在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虚拟机,右键点设置

  1. 点击共享文件夹设置框,右上角的添加按钮

    安装docker没有daemon文件 windows下的docker没意义_docker



  2. 选择之前本机设置的共享文件夹,此时一定不可以勾选自动挂载

    安装docker没有daemon文件 windows下的docker没意义_docker_02





  3. 设置好共享名后,进入docker虚拟机系统,打开终端,先执行命令,在挂载点目录添加“bdshare”目录,接着执行"mount -t vboxsf BaiduShare /mnt/bdshare/",就能完成共享文件夹的设置。请记住mount命令一定要带上参数-t vboxsf,BaiduShare就是共享文件夹名称,/mnt/bdshare/就是要在docker虚拟机中挂载的绝对路径
  4. docker虚拟机系统默认使用docker用户,可能会遇到Permission denied错误,即权限不足,需要切换到root账户操作,只要输入“sudo su”命令即可,无需密码

二、docker容器挂载docker虚拟机的目录


docker可以支持把一个宿主机上的目录挂载到镜像里。

docker run -it -v /home/dock/Downloads:/usr/Downloads ubuntu64 /bin/bash

通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径。

安装docker没有daemon文件 windows下的docker没意义_安装docker没有daemon文件_03

现在镜像内就可以共享宿主机里的文件了。



此处要挂载上一步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        #映射共享目录,和虚拟机磁盘