Swoft环境搭建

参考资料

预备知识

  • 什么是Dcoker
  • 什么是Docker Machine
  • 什么是Swoole
  • 什么是Swoft

环境配置

  • 安装虚拟机 VirtualBox
  • 安装配置 PHP
  • 安装配置 Docker
  • 安装配置 Swoft

Unbuntu上使用Docker Machine

# 查看docker machine版本
$ docker-machine -v
docker-machine version 0.16.1, build cce350d7

# 查看docker虚拟机
$ docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS

# 创建默认虚拟机
$ docker-machine create default
Creating CA: /home/jc/.docker/machine/certs/ca.pem
Creating client certificate: /home/jc/.docker/machine/certs/cert.pem
Running pre-create checks...
Error with pre-create check: "This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory"

简单描述下事故现场:我的物理机上安装了VirtualBox,在VirtualBox上面安装Ubuntu,在虚拟机上的Ubuntu系统上安装Docker和DockerMachine,由于DockerMachine需要VirtualBox,因此又在Ubuntu上安装了VirtualBox。接下来的一幕就出现了:

Error with pre-create check: "This computer doesn't have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory"

什么意思?大意是:

您的这台电脑,当然就是Ubuntu所在VirtualBox,没有启用虚拟化技术VT-x/AMD-V。

真的是这样的吗?真正的原因是:

VirtualBox不支持在虚拟机里开启另一个嵌套的虚拟机。如果确实需要运行这种嵌套的虚拟化场景,需要尝试VMWare Workstation 11。

反思下,这种操作本身是不是有问题的呢?什么是Docker Machine,它是为了在本地快速创建Docker容器环境用的,如果要在本地快速创建Docker集群环境,总不能一台台的手动创建虚拟机吧,所以Docker Machine可以解决这个问题。最重要的是它是为了在Mac或Windows上运行Docker而诞生的,反观下自己的做法。嘿嘿,不理解人家,还说人家是错的。我想想应该怎么用了,应该是在本地的Windows系统上安装Docker Machine,去管理VirtualBox上Docker,这才是正道。误入歧途,误入歧途,学习不就是这样的吗?久病成良医...

好吧,Ubuntu上卸载掉VirtualBox吧。

# 查看VitualBox版本
$ sudo dpkg -l | grep virtualbox

# 卸载VirtualBox
$ sudo apt remove virutalbox

Windows10安装DockerMachine

首先检查下环境,在Windows命令行下使用systeminfo查看系统信息,重点检查两项:

  • Windows系统版本
  • Hyper-V是否开启
$ systeminfo
OS 名称:          Microsoft Windows 10 家庭中文版
Hyper-V 要求:     虚拟机监视器模式扩展: 是
                  固件中已启用虚拟化: 是
                  二级地址转换: 是
                  数据执行保护可用: 是

为什么要检查下Windows环境呢?因为Docker Machine是在Docker软件包里面的,所以在Windows上必须安装Docker,由于Docker引擎使用定制的Linux内核,所以在Windows下运行Docker就需要使用虚拟机。通过Windows Docker客户端来控制和管理虚拟机中的Docker引擎。官方提供的Docker Desktop的Windows版本是要求的:

Requires Microsoft Windows 10 Professional or Enterprise 64-bit. For previous versions get Docker Toolbox.

人家需要微软64位Windows10专业版或企业版,如果你的系统不符合的话,只能使用 Docker Toolbox。

Windows10安装Docker Toolbox

为避免出乱子节外生枝,我先关掉VirtulBox,然后一路Next,等待良久,终于Finish。安装成功后会有两个工具:

  • Docker Quickstart Terminal :Docker命令行管理工具
  • Kitematic:Docker的GUI图形化界面管理工具
Docker Toolbox

老规矩,GUI看看了解就行,重点是命令行工具。打开Docker Quickstart Terminial,安静的等待从Github上下载boot2docker.iso文件。不过,需要注意的是,系统中必须提前安装VirtualBox。

静静等待从github下载boot2docker.iso镜像文件

最后,装满集装箱的鲸鱼终于出现了。看标题上出现了MINGW64的字眼,我应该是什么时候提前安装过的。所以也没有怎么在意...

Docker Quickstart Terminal

说实话,一直不太习惯很多命令行工具,直到有一天遇到了Cmder,于是乎怎么才能在Cmder里面使用Docker命令呢?

Cmder中输入:

$ @FOR /f "tokens=*" %i IN ('docker-machine env default') DO @%i
'docker-machine' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

嗯~ o( ̄▽ ̄)o,为什么不行了,上次就可以啊。算了不纠结,还是传统手工方式靠谱,将docker安装目录设置到windows系统环境变量path中。

# 临时仅对当前命令行窗口有效
$ set path=%path%;C:\Program Files\Docker Toolbox
$ echo %path%

# 永久生效,`/m`是系统环境变量。
$ setx PATH "%PATH%;C:\Program Files\Docker Toolbox" /m

以防万一,检查下,检查下。果然没有,但是在用户环境变量Path里面却找到了。算了不折腾,原始方式来吧。


设置系统环境变量

来来来,检查下Docker版本验证下安装成功。

$ docker -v
Docker version 18.03.0-ce, build 0520e24302

$ docker-machine -v
docker-machine version 0.14.0, build 89b8332

查看docker machine默认安装的虚拟机

# 查看docker安装的虚拟机列表
$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Stopped                 Unknown

# 开启default默认虚拟机
$ docker-machine start default

设置default虚拟机的共享目录


设置虚拟机共享目录

测试共享目录是否成功工作,在Windows共享目录下新建文件test.txt,然后进入default虚拟机中查看。

# 使用SSH连接进入default虚拟机
$ docker-machine ssh default 
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@default:~$

# 查看共享目录下文件
docker@default:~$ ls -ali /share/
total 0
      0 drwxrwxrwx    1 docker   staff            0 Apr 19 17:00 .
  11162 drwxr-xr-x   18 root     root           440 Apr 19 16:57 ..
      2 -rwxrwxrwx    1 docker   staff            0 Apr 19 17:00 test.txt
检查共享目录是否设置成功

到这里基本上告一段落,小结一下,为什么要设置共享目录呢?

设置本地机器与VirtualBox共享目录是为了写代码用,在Windows系统的共享目录下将会存在Swoft项目源码,通过VirtualBox共享目录使Windows中的代码可以同步到default虚拟机下设置的/share目录中,下一步的任务就使让default虚拟机的share共享目录与Docker容器中的项目代码同样进行共享,这样一层层的实现了在Windows上修改代码,Docker容器中的代码就会同步更新。

使用Docker本地搭建Swoft开发环境

接上述,时间过去许久,我们已经设置好共享目录,这是第一个需要非常非常注意的地方,接下来进入正题:

如何在Docker中安装Swoft并搭建本地开发环境呢?

首先安装官方提供的Swoft项目工程

# 查看docker虚拟机
$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Stopped                 Unknown

# 开启默认default的docker虚拟机
$ docker-machine start default
Starting "default"...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

# 查看docker的默认虚拟机default是否开启
$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default   *        virtualbox   Running   tcp://192.168.99.100:2376           v18.09.5


# 查看default虚拟机IP地址
$ docker-machine ip default
192.168.99.100
# 使用SSH进入默认default虚拟机
$ docker-machine ssh default
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

# 查看默认default虚拟机中所有的容器列表
docker@default:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

# 后台运行swoft容器,若本地不存在则先会去下载。
docker@default:~$ docker run -d -p 80:80 --name myswoft swoft/swoft
Unable to find image 'swoft/swoft:latest' locally
latest: Pulling from swoft/swoft
177e7ef0df69: Pull complete
9bf89f2eda24: Pull complete
350207dcf1b7: Pull complete
a8a33d96b4e7: Pull complete
bdf13640ae19: Pull complete
61a6857c7236: Pull complete
2918a8d29448: Pull complete
03d889ff4798: Pull complete
37cb0809dd09: Pull complete
dee720195aa0: Downloading [=================================================> ]  31.59MB/31.91MB
cceae20a736f: Download complete
3fa52edcdb62: Download complete
b8fce7ac7556: Download complete
29bf687e6ed1: Downloading [=============================================>     ]  617.2kB/679.5kB
f26ae7635cf0: Download complete
1e4f488d1bc9: Download complete
58c2980c6e23: Download complete
feaab8c224b7: Download complete

由于网络情况不同,有的下载很快,也有的会很慢。

docker@default:~$ docker pull swoft/swoft
Using default tag: latest
latest: Pulling from swoft/swoft
177e7ef0df69: Already exists
9bf89f2eda24: Pulling fs layer
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
bb19cde7d20a        swoft/swoft         "php /var/www/swoft/…"   3 seconds ago       Up 3 seconds        0.0.0.0:80->80/tcp   myswoft

$ docker exec -it myswoft bash
root@bb19cde7d20a:/var/www/swoft#

root@bb19cde7d20a:/var/www/swoft# composer install
root@bb19cde7d20a:/var/www/swoft# composer update

# 退出容器
root@bb19cde7d20a:/var/www/swoft# exit

官方Swoft项目安装成功后,可在本地浏览器输入网页进行查看http://192.168.99.100:80

Swoft项目

接下来是重点,思路是这样的:

首先我们将swoft的官方项目在docker中运行起来,然后使用composer安装好它的依赖后。在将容器内的swoft项目拷贝到宿主机中的共享目录,记住宿主机的共享目录通过VirtualBox已经设置与本地Windows系统做了共享,这一点是个关键。接下删除掉官方swoft项目,然后重新运行并设置共享目录的swoft,完成最终的环境搭建。

# 停止myswoft容器
docker@default:~$ docker stop myswoft
myswoft

# 将容器中的项目拷贝到宿主机的共享目录下
docker@default: docker cp myswoft:/var/www/swoft /share
remove /share/swoft/.git/objects/pack/pack-1d5696b166afa70ef87c6b4ed4b9dca2bcb9cfd8.idx: operation not permitted

# 删除容器
docker@default:~$ docker rm myswoft

此处需要注意下拷贝的语法

docker cp 容器名称:容器内源文件的路径 宿主机目的路径

设置宿主机与容器共享文件,注意共享的前提是docker容器中的文件地址应该和宿主机对应的文件是一摸一样的。

# 建立共享目录
$ docker run -it --rm  -d -p 80:80 -v /share/swoft:/var/www/swoft --name myswoft swoft/swoft /bin/bash

# 查看当前所有容器
docker@default:/share/swoft$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
db68453f8674        swoft/swoft         "php /var/www/swoft/…"   3 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp   myswoft

到这里,基本山已经搭建完毕,注意最后一步很关键,如果设置共享目录不能成功,则整个搭建是失败的。在这里饶了很久很久。此时,只要在本地windows的共享目录修改文件,在docker的default虚拟机中的myswoft项目会同步更新,此时再次访问http://192.168.99.100:80

后记:swoft环境搭建好了,下一步就要看看swoft项目如何使用。


这又过了一段时间了,今天碰到一个比较奇怪的文件,不知道那一步操作将已经运行很久的myswoft容器给整没了。什么意思了,就是使用docker ps -a查看的时候,原来的myswoft容器现在已经没有了...

好吧,第一反应就是给运行起来,执行运行命令:

docker@default: ~$ docker run -it  -d -p 80:80 -v /share/swoft:/var/www/swoft --name myswoft swoft/swoft /bin/bash

docker@default:~$ docker ps -a | grep myswoft
cc81ba6cdcf0        swoft/swoft         "php /var/www/swoft/…"   5 minutes ago       Exited (0) 3 minutes ago                                       myswoft

心中顿时凉凉,Exited (0) 3 minutes ago 三分钟前已经退出。

看看日志怎么说的吧

docker@default:~$ docker logs --details myswoft
 The server have been running!(PID:
 )

恭喜你,The server have been running! 服务器正在运行,容器已经退出了,怎么办???

phpStorm Docker

发现PHPStorm上面Docker的面板,发现挂载数据卷旁边有个Save按钮,一顿狂点。

docker@default:~$ docker ps -a | grep myswoft
91cf88a63a99        swoft/swoft         "php /var/www/swoft/…"   7 minutes ago       Created                                                 myswoft

忽然发现容器的状态,从之前的Exited变成了Created,然并卵~

一旦开启容器docker start myswoft,瞬间状态又回到了Exited,日志里面仍旧是The server have been running!

docker@default:~$ free -mh
              total        used        free      shared  buff/cache   available
Mem:           989M        555M        283M         59M        151M        356M
Swap:          1.1G        349M        814M
Kitematic (Alpha)

Kitematic (Alpha)上面显示的是一直处于运行状态RUNNING,可使用docker ps -a中仍旧显示的是Exited

改变端口也无济于事,怎么办呢?

现在查看状态

docker@default:~$ docker logs myswoft
Could not open input file: /var/www/swoft/bin/swoft

怎么办呢?

当我静静的关闭电脑后,第二天打开电脑,Docker被停了,里面什么都没有了。该死!Shit,Shit,Shit...!

我的MySQ,我的Redis,一切又从0开始,还好我写了日志,留了点备份。

问题还是之前的问题,还是从日志那点儿蛛丝马迹下手吧。日志里面有个漏掉的地方:

The server have been running!(PID:
)

这里显示的PID为什么是空的,记得开启调试模式后会在runtime文件夹下生成一个swoft.pid文件,里面记录的是Swoft的进程ID,这个地方很值得怀疑。不管那么多,先在环境变量中关闭调试模式,另外将runtime文件夹给删除掉,是不是这货的问题很有可能,是不是启动后找不到PID才导致的,这些猜测边做边验证。

重启docker run,OK天下太平了,Swoft又跑起来了。回头想想,开始并没有注意到日志中的PID位置,才感觉无从下手,日后日志自己还是要记录清晰些,这些细节防微杜渐引以为戒。


关于Swoft关联本地镜像启动时日志文件中出现的Could not open input file: /var/www/swoft/bin/swoft错误,错误很清晰的描述说没有/bin/swoft这个问题,这个时候要问下自己对-v参数的理解到底是什么样的,-v是本地文件夹关联到容器内的文件夹,前提条件是什么,是本地文件夹内是需要有代码的,不然关联到容器内干嘛?难道让容器会见代码复制到本地吗,注意你是在本地修改然后同步到Docker容器内的,所以是本地首先要有代码。到这里这个问题的答案基本也就清楚了。

首先需要在共享文件夹中下载Swoft项目

$ git clone https://github.com/swoft-cloud/swoft

这里使用git clone下载的Swoft项目工程默认的文件夹名称为swoft,第一步完成后就可以了吗?如果现在使用docker run命令的-v选项去关联,是会出现错误的。

$ docker run -it -d -p 80:80 -v /share/swoft:/var/www/swoft --name myswoft swoft/swoft /bin/bash
Warning: require_once(/var/www/swoft/vendor/autoload.php): failed to open stream: No such file or directory in /var/www/swoft/bin/bootstrap.php on line 3

Fatal error: require_once(): Failed opening required '/var/www/swoft/vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /var/www/swoft/bin/bootstrap.php on line 3

警告Warning和致命错误Fatal error很清晰的告诉你项目的依赖没有安装,现在需要做的是进入swoft项目工程中使用Composer工具安装依赖。

$ cd swoft
$ composer install

如果安装依赖没有出错,再运行容器并关联本地文件,按道理来说应该是没有问题的,等一等,我的Composer还是下载安装依赖中。

$ docker run -it -d -p 80:80 -v /share/swoft:/var/www/swoft --name myswoft swoft/swoft /bin/bash
$ docker@default:/share$ docker logs myswoft

Fatal error: Uncaught Error: Class 'Swoole\Runtime' not found in /var/www/swoft/bin/swoft:7
Stack trace:
#0 {main}
  thrown in /var/www/swoft/bin/swoft on line 7

问题又来了,这个时候又出现了一个致命的错误:Class 'Swoole\Runtime' not found in /var/www/swoft/bin/swoft:7


安装配置

# 在docker中拉取swoft最新镜像
$ docker pull swoft/swoft:latest

# 运行swoft启动一个HTTP服务器
$ docker run -p 80:80 --name myswoft --rm -d swoft/swoft:latest

# 将myswoft容器中的项目文件拷贝到当前目录下
$ docker cp myswoft:/var/www/swoft .

# 重新启动容器时映射文件
$ docker stop myswoft
$ docker run -p 80:80 --name myswoft --rm -d -v /share/swoft:/var/www/swoft  swoft/swoft:latest

梳理下流程:拉取镜像->启动服务->拷贝镜像->挂载文件

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容