{"action":"opened","issue":{"url":"https://api.github.com/repos/Ge-yuan-jun/fe-blog/issues/2","repository_url":"https://api.github.com/repos/Ge-yuan-jun/fe-blog","labels_url":"https://api.github.com/repos/Ge-yuan-jun/fe-blog/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/Ge-yuan-jun/fe-blog/issues/2/comments","events_url":"https://api.github.com/repos/Ge-yuan-jun/fe-blog/issues/2/events","html_url":"https://github.com/Ge-yuan-jun/fe-blog/issues/2","id":189723368,"number":2,"title":"搭建前端开发环境—docker篇","user":{"login":"Ge-yuan-jun","id":11786638,"avatar_url":"https://avatars.githubusercontent.com/u/11786638?v=3","gravatar_id":"","url":"https://api.github.com/users/Ge-yuan-jun","html_url":"https://github.com/Ge-yuan-jun","followers_url":"https://api.github.com/users/Ge-yuan-jun/followers","following_url":"https://api.github.com/users/Ge-yuan-jun/following{/other_user}","gists_url":"https://api.github.com/users/Ge-yuan-jun/gists{/gist_id}","starred_url":"https://api.github.com/users/Ge-yuan-jun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ge-yuan-jun/subscriptions","organizations_url":"https://api.github.com/users/Ge-yuan-jun/orgs","repos_url":"https://api.github.com/users/Ge-yuan-jun/repos","events_url":"https://api.github.com/users/Ge-yuan-jun/events{/privacy}","received_events_url":"https://api.github.com/users/Ge-yuan-jun/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-11-16T14:38:33Z","updated_at":"2016-11-16T14:38:33Z","closed_at":null,"body":"### 一、解决痛点\r\n1. 免搭建前端静态环境\r\n2. 分支切换，无需重新启动编译（`package.json`或`gulpfile.js`文件改变除外）\r\n3. `nginx`可自行配置，满足不同项目的需求\r\n\r\n### 二、前端静态搭建思路\r\n基于`ubuntu`系统环境，利用`nginx`静态资源服务器经过`docker`暴露出来的端口进行请求转发，这样后端的开发机上面只需要安装`docker`就能够访问前端的静态资源，不需要访问前端开发机。\r\n\r\n### 三、具体解决方案\r\n\r\n1. 用 Kitematic 客户端实现跨平台运行 Docker\r\n2. 用端口映射预览 Docker 里的文件\r\n3. 用 nginx + 端口映射编辑 Docker 里的文件\r\n4. 配置一个通用的 Image（镜像）\r\n\r\n这里面有几个概念需要先解释一下。\r\n\r\n首先，`Kitematic` 是一个 `Docker GUI`，配置非常方便。\r\n\r\n其次，Docker 中最重要的三个概念是 Container（容器）、Image（镜像）和 Volume（卷）。\r\n\r\nImage 是静态内容，如果你要把某个 Image 跑起来，那就需要一个 Container。这里面有一点很重要：Container 中所做的改动不会保存到 Image。如果需要保存改动，很简单，执行` docker commit ContainerID TAG` 即可，类似于 git 的 commit\r\n\r\n如果不想使用`commit`仍想保存文件，docker 也提供了一个方法：使用 Volume。\r\n\r\nVolume 就是专门存放数据的文件夹，启动 Image 时可以挂载一个或多个 Volume，Volume 中的数据独立于 Image，重启不会丢失。\r\n\r\n最后说端口映射。前面说过，Docker 可以看做一个虚拟机，你的所有文件都在里面。如果你在 Container 中运行一个服务器，监听 `127.0.0.1:8000`，从你自己的机器上直接访问 `http://127.0.0.1:8000` 是不行的，因为 Container 和你的机器是两个不同的环境。\r\n\r\n那怎么办呢？我们先来看一个大家都熟悉的问题。\r\n\r\n日常开发中我们经常需要让同事预览网页效果，常用的方法是监听 `0.0.0.0:8000`，然后让同事连接同一个局域网，访问 `http://你的机器IP:8000` 即可。\r\n\r\nContainer 的问题非常相似，只不过我们自己变成了“同事”，需要访问 Docker 内部的网页。看起来只要拿到 Container 的 IP 问题就解决了。\r\n\r\n幸运的是，Container 确实有 IP。\r\n\r\n通常情况下这个 IP 是 `192.168.99.100`（利用 Kitematic 启动 docker），只能从 Container 的宿主机（也就是运行 Docker 的机器）访问。不过 Container 的情况有些特别，它只关联了 IP，没有关联端口。因此如果想要访问 Container 内部的端口（比如 8000），你需要手动配置端口映射，把 Container 内部的端口映射到 IP 上。\r\n\r\n### 四、动手\r\n##### 1. 下载`Docker Toolbox`\r\nDocker Toolbox 支持 Windows 和 Mac OS，可以到[官网](https://www.docker.com/products/docker-toolbox)下载安装，耗时较严重，建议找直接找下下好的包。\r\n\r\n安装完毕之后打开 Kitematic，注册一个 Docker Hub 账号，方便之后的操作。\r\n\r\n##### 2. 下载`Ubuntu`镜像\r\n在 Katematic 里面的搜索 Ubuntu\r\n\r\n选择第二排第一个，点击 `create` 按钮。\r\n\r\n这里插一句，`fuck GFW` ，100M的文件能花两个小时下载，也是醉了。\r\n\r\n下载完成后，在 Kitematic 左侧的 Container 列表中选择 ubuntu，然后点击上方的“START”按钮执行。点击“EXEC”可以进入系统命令行，输入 su 开启 root 权限。\r\n\r\n这个时候，可以点击 Kitematic 右上角的“Settings”，点击“Ports”，你会看到一个 IP 地址，通常情况下是 192.168.99.100。打开自己的电脑的命令行，输入 ping 192.168.99.100，应该是通的。\r\n\r\n##### 3. 常规初始化工作\r\n\r\n受够了渣下载速度，决定换源。采用的是中科大的源，你也可以尝试阿里云的源，速度都不错~\r\n\r\n```\r\nsed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list\r\napt-get update\r\n```\r\n\r\n先安装必要的编辑器以及路径补全：\r\n`apt-get install vim bash-completion`\r\n\r\n其它的工具可以自行添加\r\n\r\n##### 4. 安装nginx以及nvm\r\n\r\n`nvm`是一个 node 版本管理器，利用它可以进行多个node版本的管理。\r\n\r\n在开启root权限的终端输入：\r\n```\r\napt-get update\r\napt-get install nginx\r\napt-get install curl\r\ncurl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash\r\nsource ~/.bashrc\r\nnvm install node\r\n```\r\n安装完成不忙做nginx配置，我们需要等其挂载数据卷之后，再做nginx配置文件修改。\r\n\r\n`nvm`可以采用国内的淘宝源，速度比较快。\r\n\r\n##### 5. 导出image\r\n在 mac 平台上面可以直接操作 Katematic 进行端口映射配置，但在 windows 平台上面只能通过 `命令行` 进行配置。挂载卷目前只能通过`命令行`进行配置。基于这种情况，我们统一利用`命令行`来配置。\r\n\r\n首先，`commit`。点击 Kitematic 左下角 “DOCKER CLI”，执行：\r\n\r\n`docker ps`\r\n\r\n类似于如下的输出：\r\n```\r\n➜  ~ docker ps\r\nCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                                                                      NAMES\r\nb357a78dc95e        f753707788c5        \"/bin/bash\"         3 days ago          Up 4 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:8088->8088/tcp   iwjwdocker\r\n\r\n```\r\n\r\n`copy` 出 `container id`，这里是`b357a78dc95e`。\r\n\r\n然后执行：\r\n`docker commit b357a78dc95e username/imagename`\r\n\r\n接下来，导出Image\r\n\r\n`docker export b357a78dc95e -o ubuntu.tar`\r\n\r\n查看你的个人目录。mac上面就是 `/Users/你的用户名`，就能找到`ubuntu.tar`文件。\r\n\r\n接下来，我们会新建一个 image，在这个 image 上面进行整个的配置。\r\n\r\n##### 6. 配置端口映射以及挂载卷\r\n配置流程：\r\n\r\n1. 在 Kitematic 中点击左下角“DOCKER CLI”打开 Docker 命令行\r\n2. 输入命令docker import，从文件夹中直接把 ubuntu 文件拖拽到命令行中（注意 ubuntu 文件路径中不能有中文，如果有，先把文件移动到另一个纯英文路径的文件夹中）\r\n3. 输入命令docker images，复制出镜像的 IMAGE ID（类似b357a78dc95e）\r\n4. **最重要的一步**，输入命令：\r\n```\r\ndocker run -t -i --privileged -p 80:80/tcp \\\r\n    -p 443:443/tcp -p 8088:8088/tcp \\\r\n    -p 8000:8000/tcp -p 8080:8080/tcp -d --name iwjw \\\r\n    -v /Users/aaaa/test:/static \\\r\n    -v /Users/aaa/nginxconf:/etc/nginx/sites-enabled \\\r\n    -v /Users/aaa/www:/www  IMAGEID \\\r\n    /bin/bash\r\n```\r\n\r\n解释一下上面的命令行：\r\n\r\n- `-p 80:80/tcp`:docker基于 TCP 协议暴露 80 端口\r\n- `--name iwjw`:在 Katematic 显示这个 image 的名称为 `iwjw`\r\n- `-v /Users/aaaa/test:/static`:将`/Users/aaaa/test`这个文件夹挂载到 docker 内Ubuntu系统的`/static`文件夹。简单说来，就是在docker命令行内 进入 `/static`文件夹，能访问到宿主机（本人电脑）中的`/Users/aaaa/test`文件夹。\r\n- **注意**：挂载`/Users/aaaa/test`这个文件夹是用来存放 静态资源代码，挂载`/Users/aaa/nginxconf`是用来编写`nginx`配置文件的，挂载`/Users/aaa/www`可以用来存放一些自动化脚本\r\n\r\n*如果需要使用80端口，注意需要删除`sites-enabled`文件夹里面的`default`文件，`default`文件里面存在对80端口的默认设置（利用root进行的配置）*\r\n\r\n\r\n##### 7. 根据自己的项目进行个性化配置\r\n\r\n个性化配置：\r\n1. nginx\r\n2. 运行脚本编写，可以考虑放在`/www`文件夹里进行管理。\r\n\r\nshell脚本类似如下：\r\n```\r\n\r\nfunction init() {\r\n  nginx\r\n  npm install gulp -g\r\n  npm install\r\n}\r\n# 打开命令行提示\r\n\r\necho \" -aaainit 进入 aaa 文件夹，并初始化aaa项目\"\r\necho \" -aaa 进入 aaa 文件夹，并初始化aaa项目\"\r\necho \" -h 帮助\"\r\n\r\nwhile [ -n \"$1\" ]\r\ndo\r\n    case \"$1\" in\r\n    \"-aaainit\")\r\n        echo \"进入 aaa 文件夹，并初始化运行 aaa 项目\"\r\n\r\n        cd /static/aaa\r\n        init\r\n        npm run start\r\n\r\n        ;;\r\n    \"-aaa\")\r\n        echo \"进入 aaa 文件夹，并运行 aaa 项目\"\r\n\r\n        cd /static/aaa\r\n        npm run start\r\n\r\n        ;;\r\n\r\n    \"-h\")\r\n        echo \" -aaainit 进入 aaa 文件夹，并初始化aaa项目\"\r\n        echo \" -aaa 进入 aaa 文件夹，并初始化aaa项目\"\r\n        echo \" -h 帮助\"\r\n        ;;\r\n    esac\r\n    shift\r\ndone\r\n```\r\n\r\n### 五、结语\r\n\r\n基本上，完成上面的docker配置，后端就可以自己在前端代码的分支进行自己接口的测试了。\r\n\r\n引入docker之后，可以大大减少前后端联调的时间，从而加快开发进度。\r\n\r\n这篇文章是在基于梁杰的这篇[用 Docker 快速配置前端开发环境][3]进行的开发，建议大家首先阅读这篇文章。\r\n\r\n  [3]: http://numbbbbb.com/2016/09/26/20160926_%E7%94%A8%20Docker%20%E5%BF%AB%E9%80%9F%E9%85%8D%E7%BD%AE%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/"}}
{"actor":{"display_login":"Ge-yuan-jun"}}