Doceker 配置php+nginx+composer+redis等运行环境

585 阅读3分钟

网上已有很多Docker搭建环境的文章,自己则根据项目实际需要,弄了一套自己项目需要的环境。都说好好记性不如烂笔头,文章主要作为自己的Docker学习笔记,便于后续复习。

一、创建DockerFile文件

PHP+nginx的Docker镜像采用Dockerfile的方式进行,相关代码如下:

FROM php:8.1-fpm-alpine

LABEL Maintainer="bac" \
      Description="PHP 8.1 + FPM 镜像,内置 nginx、composer 及 PHP 扩展 gd、opcache、redis、时区设置等支持"

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

RUN apk update \
    && apk add tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && apk add --no-cache nginx libzip libpng git freetype bash supervisor libjpeg-turbo \
    && apk add --no-cache --virtual build-dependencies g++ make autoconf libzip-dev libpng-dev freetype-dev libjpeg-turbo-dev icu-dev libxml2-dev libmcrypt-dev freetype-dev libzip-dev libpng-dev \
    && docker-php-source extract \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && docker-php-ext-configure gd --with-freetype \
    && docker-php-ext-install pdo_mysql zip opcache gd bcmath soap \
    && docker-php-source delete \
    && apk del build-dependencies \
    && curl -sS https://getcomposer.org/installer | php -- \
       --install-dir=/usr/local/bin --filename=composer \
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \
    && mkdir -p /run/nginx \
    && rm -rf /tmp/*

其中 FROM php:8.1-fpm-alpine 为指定要使用的php版本,大家可以根据实际需要进行修改调整。

将DockerFile文件存放到你喜欢的文件夹中。

二、制作镜像

命令如下:

docker build -t 镜像名:tag .

ps:记得在dockfile文件存放的目录执行此命令,否则命令后面的“.”就需要修改为存放路径地址了。

制作完镜像后,将此基础镜像推送到仓库中,作为后续项目的基础运行环境。

可以放阿里云、腾讯云,都有免费的使用配额。

三、编写项目运行的DockerFile文件

在项目根目录创建deploy文件夹,对应目录结构如下

image.png

supervisor.conf 配置文件

[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10           ; (num of main logfile rotation backups;default 10)
loglevel=info                ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false               ; (start in foreground if true;default false)
minfds=1024                  ; (min. avail startup file descriptors;default 1024)
minprocs=200                 ; (min. avail process descriptors;default 200)
user=root            ;

[unix_http_server]
file=/dev/shm/supervisor.sock

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL  for a unix socket

[include]
files = /etc/supervisor/conf.d/*.conf

nginx.default.conf

可以根据需要修改:root中的项目入口地址;

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    root "/app/public";
    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  off;

    sendfile off;

    client_max_body_size 100m;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;

        # Hide PHP headers
        fastcgi_hide_header X-Powered-By;
        fastcgi_hide_header X-CF-Powered-By;
    }

    location ~ /\.ht {
        deny all;
    }
}

supervisor.nginx.conf

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
priority=10
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT

supervisor.phpfpm.conf

[program:php-fpm]
command = /usr/local/sbin/php-fpm --force-stderr --nodaemonize
autostart=true
autorestart=true
priority=5
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT

php-fpm/docker.conf

[global]
error_log = /proc/self/fd/2

; https://github.com/docker-library/php/pull/725#issuecomment-443540114
log_limit = 8192

[www]
; if we send this to /proc/self/fd/1, it never appears
access.log = /proc/self/fd/1

clear_env = no

; Ensure worker stdout and stderr are sent to the main error log.
catch_workers_output = yes
decorate_workers_output = no

项目DockerFile文件配置

FROM ccr.ccs.tencentyun.com/www.92show.cc/php81_nginx:v3

ADD . /app

# Supervisor and Nginx
RUN mkdir -p /etc/supervisor/conf.d
ADD deploy/supervisor.conf /etc/supervisor.conf
ADD deploy/supervisor.phpfpm.conf /etc/supervisor/conf.d/
ADD deploy/supervisor.nginx.conf /etc/supervisor/conf.d/
ADD deploy/nginx.default.conf /etc/nginx/http.d/default.conf

# php-fpm
ADD deploy/php-fpm/docker.conf /usr/local/etc/php-fpm.d/docker.conf

# code
WORKDIR /app
ADD .env.example /app/.env


# composer 基础环境中已有,顾注释掉
# RUN composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 项目中composer 安装
RUN composer install
# #RUN composer install --no-dev --prefer-dist

RUN chown -R www-data:www-data /app/*

# CREATE key:generate
RUN php artisan key:generate

EXPOSE 80

ENTRYPOINT ["supervisord", "--nodaemon", "--configuration", "/etc/supervisor.conf"]

四、制作镜像,本地测试启动

Dockerfile文件配置完毕后,就可以开始进行镜像制作了,制作前确保第三步的文件,均存放到了项目的根目录下。

docker build -t 镜像名:tag .

等待制作完毕后,运行容器即可。

docker run -d -p 宿主机端口:容器端口 --name=容器名称 镜像名:tag

因为在dockerfile配置有ENTRYPOINT,所以运行时,不需要-it以及在后面添加/bin/bash等终端启动命令。

容器启动后,如果需要进入容器可以通过下面的命令进入

docker exec -it 容器名称 /bin/sh

同时也可以通过http://localhost:宿主机端口号/访问启动的容器应用,至此算是大功告成了!

五、宿主机 Apache 代理访问容器服务

用户访问宿主机,由宿主机上的apache进行代理访问容器里面的web应用。

apahce.conf文件修改

需开启如下配置

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_http2_module modules/mod_proxy_http2.so

创建虚拟主机,相关配置如下

<VirtualHost *:80>
    ServerName aa.bb.cc
    DirectoryIndex index.php index.html
    SetOutputFilter SUBSTITUTE,DEFLATE

    ProxyPass / http://localhost:8081/
#    ProxyPassReverse / http://localhost:8081/

##   Substitute "s|http://localhost:8081/|t1.92show.com/|i"
##    AddOutputFilterByType SUBSTITUTE text/html

    <Proxy *>
        Order deny,allow
        Allow from all
        Allow from localhost
    </Proxy>
</VirtualHost>

重新启动apache,浏览器访问:http://aa.bb.cc

image.png

到此即完成了宿主机的apache代理访问容器web应用!!