**本文年代久远,可能已经不适用。仅供参考!**新的php镜像参考maoxuner/php 。
多容器 apache+php+mariadb+redis
主要配置
构建php镜像
基于官方php镜像进行定制,增加所需的php扩展,修改php配置,以及创建虚拟主机。
Dockerfile
文件php/Dockerfile
FROM php:apache
# php configure
COPY php.ini /usr/local/etc/php/php.ini
# php extension
COPY sources.list /etc/apt/sources.list
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libbz2-dev \
libfreetype6-dev libjpeg62-turbo-dev libpng-dev \
&& rm -r /var/lib/apt/lists/* \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) zip bz2 gd mysqli pdo_mysql sockets \
&& pecl install redis \
&& docker-php-ext-enable redis
# php composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');"
# apache configure
RUN a2enmod rewrite.load
# apache vhosts
COPY vhosts/* /etc/apache2/sites-available/
RUN a2ensite demo.conf
说明
FROM php:apache未指定php版本号,默认使用最新的版本,当前7.2docker-php-ext-install可以安装的组件如下,curl组件默认已经安装bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap interbase intl json ldap mbstring mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml snmp soap sockets sodium spl standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zend_test zip
- 必要时需要安装一些依赖,并用
docker-php-ext-configure配置编译参数 pecl可以安装pecl支持的组件,如redis
遇到的问题
直到我看到这个Installation of curl fails - easy.h should be in
Installation of curl fails - easy.h should be in
/include/curl/
缺少依赖,而且依赖的路径不正确,解决方法
apt-get install -y libcurl4-openssl-dev
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"
if [ ! -d /usr/include/curl ]; then
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl
fi
docker-compose
mariadb和redis基本不需要定制,可以直接使用官方的镜像。我这里稍微做了一点定制。
docker-compose.yml
文件docker-compose.yml
version: '2'
services:
mariadb:
build: ./mariadb
container_name: wx-mariadb
hostname: wx-mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: cm9vdA==
ports:
- 3306:3306
volumes:
- db:/var/lib/mysql
redis:
build: ./redis
container_name: wx-redis
hostname: wx-redis
restart: always
ports:
- 6379:6379
php:
build: ./php
container_name: wx-php
hostname: wx-php
restart: always
ports:
- 80:80
volumes:
- ./html:/var/www/html
depends_on:
- mariadb
- redis
volumes:
db:
说明
ports暴露端口80:80前一个是宿主机端口,后一个是容器端口volumes分区映射./html:/var/www/html前者是宿主机的路径,后者是容器内的路径(不存在时会自动创建),可以理解为挂载。前者不能包含软连接,因为软连接只能在容器内部连接,因而找不到宿主机内的文件db:/var/lib/mysql前者是创建的分区文件,后者是容器内的路径,可以理解为虚拟磁盘 分区映射是在镜像构建以后的操作。因此在镜像构建过程中,无法使用docker-compose.yml中定义的volumes
容器间的连接
localhost和127.0.0.1
- 容器内的
localhost和127.0.0.1永远是指当前容器 - 同一个
docker-compose.yml创建的容器在同一个网络下 - 同一个网络下的容器可以直接通过容器的ip或者名称?连接,Connect containers(写文章时找文档可找了好久)
You can connect an existing container to one or more networks. A container can connect to networks which use different network drivers. Once connected, the containers can communicate using another container’s IP address or name.
link/links参数不再推荐使用(自动在/etc/hosts里添加各主机的ip主机名的记录)- 宿主机通过暴露的端口连接容器,尽量用
127.0.0.1
注意
- 在宿主机内,用mysql的web客户端(如
adminer.php)连接数据库时,主机地址填service中的主键名mariadb(容器名wx-mariadb不能用来连接,可能是我的理解有问题,详细参考文档)。不能填写localhost或者127.0.0.1。 同理,连接redis要用主机名redis进行连接。 进行连接时,发送请求的主机是wx-php。 - 利用宿主机内的mysql客户端连接服务器的话,主机地址填写
127.0.0.1。使用localhost连接mysql时,会使用sock进行连接,因而出错。ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2 “No such file or directory”)
开发调试
IP白名单
Web框架往往只能在本机上(localhost或者127.0.0.1)进行开发调试。根据上述说明,此时的“本机”是指容器本身。因此,需要在框架的设置中,将宿主机在docker网络中的ip设置到白名单里。