docker自 2013 年发布以来,已经 5 年了,很遗憾我没有在更早的时候接触 docker.刚好最近实战了一把docker.所以在此将这个过程记录下来,供以后有相关需求的时候参考.
Docker 是什么
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker 解决了什么问题
我们知道软件开发最大的麻烦事之一,就是环境配置。用户计算机的环境都不相同,用户必须保证两件事:操作系统的设置,各种库和组件,还必须有各种依赖,可能还要配置环境变量,只有它们都正确,软件才能运行。如果某些老旧的模块与当前环境不兼容,那就麻烦了。开发者常常会说:”我本地是正常的”,言下之意就是,其他环境下很可能有问题。环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。
虽然虚拟机也可以实现类似的需求,但是和 docker 对比有以下缺点:
- 资源占用多
- 冗余步骤多
- 启动慢
解决环境是配置问题,是 docker 的主要应用场景之一.
本地安装配置 Docker
下载安装 docker
鉴于大部分开发者开发环境都是 windows 和 mac 下,所以官网下载对应安装包直接安装即可.安装并运行后,在命令行工具中输入docker,可以看到以下信息则说明安装成功
搜索镜像
1 | // 搜索docker hub上的ubuntu镜像 |
结果如下:
其中 NAME、DESCRIPTION 和 OFFICIAL 字段分别表示镜像仓库源的名称、镜像描述和是否 docker 官方发布
拉取镜像
1 | docker pull ubuntu:version |
如果不加版本号则默认拉取最新的版本,我本地已经安装了,就不在截图说明了
查看本地镜像
1 | docker images |
如图:
使用 docker 镜像
1 | docker run [OPTIONS] IMAGE [COMMAND] [ARG...] |
OPTIONS 说明如下:
| 指令 | 说明 |
|---|---|
| -a stdin | 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项 |
| -d | 后台运行容器,并返回容器 ID |
| -i | 以交互模式运行容器,通常与 -t 同时使用 |
| -p | 端口映射,格式为:主机(宿主)端口:容器端口,也可以直接使用 -P,这样内部端口随机映射到主机的高端口 |
| -t | 为容器重新分配一个伪输入终端,通常与 -i 同时使用 |
| –name=”name” | 为容器指定一个名称 |
| –dns 8.8.8.8 | 指定容器使用的 DNS 服务器,默认和宿主一致 |
| –dns-search example.com | 指定容器 DNS 搜索域名,默认和宿主一致 |
| -h “hostname” | 指定容器的 hostname |
| -e evar=”evar” | 设置环境变量 |
| –env-file=[] | 从指定文件读入环境变量 |
| –cpuset=”0-2” or –cpuset=”0,1,2” | 绑定容器到指定 CPU 运行 |
| -m | 设置容器使用内存最大值 |
| –net=”bridge” | 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型 |
| –link=[] | 添加链接到另一个容器 |
| –expose=[] | 开放一个端口或一组端口 |
1 | docker run -ti -p 8888:80 ubuntu /bin/bash // 我们将本机的8888端口绑定到ubuntu的80端口并启动bash |
如图:
至此,本地 docker 已经运行起来了!下面我们先在本地 docker 中将我们的网站运行起来.
本地 docker nginx 安装
本来我们完全可以只配置宿主机的http服务器,转发端口到对应docker容器端口即可,但是也可以在一个docker容器中继续安装配置http服务器,实现一个docker容器运行多个web服务.
我们上面的容器运行的是 ubuntu 镜像,那么这里安装nginx和在ubuntu中安装nginx一样.需要注意的是,容器中可能不识别一些linux命令,需要先更新apt-get:
1 | sudo apt-get update |
然后安装所需要的软件包.
最后把我们的网站环境搭建好,在运行起来,和在ubuntu服务器上操作完全一样,是不是很简单.
打开localhost:8888,如图:
部署到远程服务器
按照上面的安装方法,在服务器上安装docker
我们用两种方法将本地docker部署到远程服务器上
上传本地镜像到远程服务器
1、保存 docker 镜像到本地
1 | docker save [image id] -o [target] |
2、上传到远程服务器
3、加载镜像
1 | docker load -i [image] |
4、运行镜像
dockerHub
1、先提交本地 docker
1 | docker commit -m="[commit description]" -a="[author]" [image id] [image name] |
-m: 提交描述
-a: 镜像作者
image id: 容器 id
image name: 创建目标容器的镜像名
**注意:**容器 id 是上面标注到容器 id,不要弄成docker images的 image id 了,另外image name要和 hub.docker 上创建的仓库名一致,否则上传会失败
如果镜像名称不一致,可以通过下面到命令重新设置镜像名称
1 | docker tag [image id] [repository name]:[tag] |
2、注册一个 hub.docker 账号并创建自己到镜像,然后在本地登陆 docker
1 | docker login |
3、推送到 hub.docker
1 | docker push [repository name]:[tag] |
4、在远程服务器上登陆并拉去镜像,后台运行镜像就 ok 了
我遇到的问题
镜像的提交更新
由于我先是在本地运行docker,刚使用的时候发现每次使用我都要重新安装vim、nginx等,后来发现修改docker后需要提交,不然退出docker后,这些修改都不会保存.
1 | docker commit -m="[commit description]" -a="[author]" [image id] [image name] |
我们可以将新提交到镜像覆盖原来到镜像以达到更新镜像的目的.
apache 配置反向代理
由于之前的远程服务器上已经安装部署了apache服务器,所以我还需要配置apache方向代理,将进入宿主机的http请求转发到docker容器在宿主机上的端口.
- 加载 apache 模块,使用
a2enmod命令加载模块
1 | a2enmod proxy proxy_balancer proxy_http |
- 配置反向代理服务器
1 | ErrorLog ${APACHE_LOG_DIR}/error.log |
重启 apache 服务器,打开域名,访问成功就说明配置成功了.
参考文章:Docker 到底是什么,要解决什么问题,好处又在哪里?
参考文章:Docker 教程 | 菜鸟教程
参考文章:ubuntu apache 反向代理配置
[越努力,越幸运!]