Ubuntu上部署docker

docker自 2013 年发布以来,已经 5 年了,很遗憾我没有在更早的时候接触 docker.刚好最近实战了一把docker.所以在此将这个过程记录下来,供以后有相关需求的时候参考.

Docker 是什么

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

Docker 解决了什么问题

我们知道软件开发最大的麻烦事之一,就是环境配置。用户计算机的环境都不相同,用户必须保证两件事:操作系统的设置,各种库和组件,还必须有各种依赖,可能还要配置环境变量,只有它们都正确,软件才能运行。如果某些老旧的模块与当前环境不兼容,那就麻烦了。开发者常常会说:”我本地是正常的”,言下之意就是,其他环境下很可能有问题。环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。

虽然虚拟机也可以实现类似的需求,但是和 docker 对比有以下缺点:

  1. 资源占用多
  2. 冗余步骤多
  3. 启动慢

解决环境是配置问题,是 docker 的主要应用场景之一.

本地安装配置 Docker

下载安装 docker

鉴于大部分开发者开发环境都是 windows 和 mac 下,所以官网下载对应安装包直接安装即可.安装并运行后,在命令行工具中输入docker,可以看到以下信息则说明安装成功
201812071500.png

搜索镜像

1
2
// 搜索docker hub上的ubuntu镜像
docker search ubuntu

结果如下:
201812071504.png

其中 NAME、DESCRIPTION 和 OFFICIAL 字段分别表示镜像仓库源的名称、镜像描述和是否 docker 官方发布

拉取镜像

1
docker pull ubuntu:version

如果不加版本号则默认拉取最新的版本,我本地已经安装了,就不在截图说明了

查看本地镜像

1
docker images

如图:
201812071515.png

使用 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

如图:
201812071557.png

至此,本地 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,如图:
201812071628.png

部署到远程服务器

按照上面的安装方法,在服务器上安装docker
我们用两种方法将本地docker部署到远程服务器上

上传本地镜像到远程服务器

1、保存 docker 镜像到本地

1
2
docker save [image id] -o [target]
// docker save ubuntu -o ubuntu.tar

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,刚使用的时候发现每次使用我都要重新安装vimnginx等,后来发现修改docker后需要提交,不然退出docker后,这些修改都不会保存.

1
docker commit -m="[commit description]" -a="[author]" [image id] [image name]

我们可以将新提交到镜像覆盖原来到镜像以达到更新镜像的目的.

apache 配置反向代理

由于之前的远程服务器上已经安装部署了apache服务器,所以我还需要配置apache方向代理,将进入宿主机的http请求转发到docker容器在宿主机上的端口.

  1. 加载 apache 模块,使用a2enmod命令加载模块
1
a2enmod proxy proxy_balancer proxy_http
  1. 配置反向代理服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<VirtualHost *:80>
#配置站点的域名
ServerName xxx.com
#配置站点的管理员信息
ServerAdmin xxx@gmail.com

#off表示开启反向代理,on表示开启正向代理
ProxyRequests Off
ProxyMaxForwards 100
ProxyPreserveHost On
#这里表示要将现在这个虚拟主机跳转到本机的9999端口
ProxyPass / http://127.0.0.1:9999/
ProxyPassReverse / http://127.0.0.1:9999/
</VirtualHost>

<Directory />
Options FollowSymLinks
AllowOverride All
Require all granted
Allow from all
</Directory>

重启 apache 服务器,打开域名,访问成功就说明配置成功了.

参考文章:Docker 到底是什么,要解决什么问题,好处又在哪里?
参考文章:Docker 教程 | 菜鸟教程
参考文章:ubuntu apache 反向代理配置

[越努力,越幸运!]