你先确认这两件事:1)执行 docker exec -it dream.php bash,到 php 存放目录看看,如果看不到你的文件,目录映射多半有问题;2)确认 fastcgi_param 设置的路径,先配成绝对路径(如上文)试试。

--------------------------------------------------------------------------------------------------------------------------------------

0 任务简介

  • 在​​Ubuntu 16.04​​​虚拟机中安装​​docker​
  • 使用​​docker​​​安装​​PostgreSQL​
  • 完成端口映射使得外部机器可以访问虚拟机中的数据库



1 安装docker

这一部分比较简单,不过考虑到完整性,还是列出来吧。 

我这次选择的是​​docker-ce​​,安装流程如下:



1.1 建立 repository

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common



  • 1

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -



  • 1

sudo apt-key fingerprint 0EBFCD88



  • 1

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"



  • 1



1.2 安装docker

sudo apt-get update



  • 1

sudo apt-get install docker-ce



  • 1



2 安装PostgreSQL
docker pull postgres:9.4



  • 1



3 创建容器

docker的容器默认情况下只能由本地主机访问,即A主机上的容器不能被B主机访问,所以要做端口映射。

docker run --name postgres1 -e POSTGRES_PASSWORD=password -p 54321:5432 -d postgres:9.4 



  • 1

解释: 

​run​​,创建并运行一个容器; 

​--name​​,指定创建的容器的名字; 

​-e POSTGRES_PASSWORD=password​​​,设置环境变量,指定数据库的登录口令为​​password​​; 

​-p 54321:5432​​,端口映射将容器的5432端口映射到外部机器的54321端口; 

​-d postgres:9.4​​​,指定使用​​postgres:9.4​​作为镜像。



3.1 验证结果

之后运行​​docker ps -a​​,结果和下表类似:

CONTAINER ID

IMAGE

COMMAND

CREATED

STATUS

PORTS

NAMES

f6951e0c5c77

postgres:9.4

“docker-entrypoint…”

38 minutes ago

Up 38 minutes

0.0.0.0:54321->5432/tcp

postgres1

3.2 关键点

我自己安装的过程中遇到了不少的坑,我认为最重要的一点是docker命令中参数的顺序。

例如端口映射的​​-p 54321:5432​​的位置如果过于靠后,则会导致映射失败。



4 连接数据库

之前的准备工作都已完成,下一步就是从外部访问数据库了。 

这一步就很常规了:

psql -U postgres -h 192.168.100.172 -p 54321



  • 1

注意: 

postgres镜像默认的用户名为​​postgres​​, 

登陆口令为创建容器是指定的值。



假设

  • 你知道 nginx、php-fpm 是什么
  • 你了解 docker 的基本命令

运行环境

MacBook Pro,OSX 10.11.5

启动 php-fpm

解释执行 php 需要 php-fpm,先让它运行起来:

docker run --name dream-php -d \
-v ~/Workspace/tmp/www:/var/www/html:ro \
php:7.1-fpm


说明:


  • dream-php 是容器的名字。
  • ~/Workspace/tmp/www 是本地 php 文件的存储目录,/var/www/html 是容器内 php 文件的存储目录,ro 表示只读。

编辑 nginx 配置文件

本地存储路径:

~/Workspace/tmp/docker/nginx/conf.d/default.conf


配置文件内容:

server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;
include fastcgi_params;
}
}


说明:


  • php:9000 表示 php-fpm 服务的 URL,下文还会提及。
  • /var/www/html 是 dream-php 中 php 文件的存储路径,经 docker 映射,变成本地路径 ~/Workspace/tmp/www(可以再看一眼 php-fpm 启动命令)

启动 nginx

docker run --name dream-nginx -p 80:80 -d \
-v ~/Workspace/tmp/www:/usr/share/nginx/html:ro \
-v ~/Workspace/tmp/docker/nginx/conf.d:/etc/nginx/conf.d:ro \
--link dream-php:php \
nginx


说明:


  • -p 80:80 用于添加端口映射,把 dream-nginx 中的 80 端口暴露出来。
  • ~/Workspace/tmp/www 是本地 html 文件的存储目录,/usr/share/nginx/html 是容器内 html 文件的存储目录。
  • ~/Workspace/tmp/docker/nginx/conf.d 是本地 nginx 配置文件的存储目录,/etc/nginx/conf.d 是容器内 nginx 配置文件的存储目录。
  • --link dream-php:php 把 dream-php 的网络并入 dream-nginx,并通过修改 dream-nginx 的 /etc/hosts,把域名 php 映射成 127.0.0.1,让 nginx 通过 php:9000 访问 php-fpm。

测试结果

在 ~/Workspace/tmp/www 下放两个文件:

index.html

<html><body><h1>Hello World</h1></body></html>


phpinfo.php

<?php phpinfo();


接下来看结果吧:

如果看到 Hello World 和熟悉的 phpinfo,那么大功告成。

访问 index.html 时,nginx 读的是 /usr/share/nginx/html/index.html,这个路径经 dream.nginx 转换变成本地的 ~/Workspace/tmp/www/index.html。

访问 phpinfo.php 时,nginx 让 php-frm 执行 /var/www/html/phpinfo.php,这个路径经 dream.php 转换成 ~/Workspace/tmp/www/phpinfo.php。

FAQ

怎样观察容器内文件系统:


 

docker exec -it dream-nginx bash