在一个dockerfile中将PHP-fpm与nginx结合

And*_*ndy 12 php nginx docker dockerfile fpm

我需要将php-fpm与nginx结合在一个dockerfile中进行生产部署。

所以更好:

(1)使用php:7.1.8-fpm启动dockerfile,然后在其上面安装nginx图像层?

(2)还是建议使用Nginx映像,然后使用apt-get安装php-fpm?

PS:我没有用于生产部署的docker-compose构建选项。在我的开发环境中,我已经使用docker-compose并从两个映像轻松构建多容器应用程序。我们的组织开发人员不支持针对产品环境的基于docker-compose的部署。

Ale*_*din 13

Nginx的安装比PHP容易得多,因此您应该更容易将Nginx安装到现成的官方PHP映像中。这是示例Dockerfile,显示了如何通过安装一些PHP扩展示例来实现您的目标:

FROM php:7.2-fpm

RUN apt-get update -y \
    && apt-get install -y nginx

# PHP_CPPFLAGS are used by the docker-php-ext-* scripts
ENV PHP_CPPFLAGS="$PHP_CPPFLAGS -std=c++11"

RUN docker-php-ext-install pdo_mysql \
    && docker-php-ext-install opcache \
    && apt-get install libicu-dev -y \
    && docker-php-ext-configure intl \
    && docker-php-ext-install intl \
    && apt-get remove libicu-dev icu-devtools -y
RUN { \
        echo 'opcache.memory_consumption=128'; \
        echo 'opcache.interned_strings_buffer=8'; \
        echo 'opcache.max_accelerated_files=4000'; \
        echo 'opcache.revalidate_freq=2'; \
        echo 'opcache.fast_shutdown=1'; \
        echo 'opcache.enable_cli=1'; \
    } > /usr/local/etc/php/conf.d/php-opocache-cfg.ini

COPY nginx-site.conf /etc/nginx/sites-enabled/default
COPY entrypoint.sh /etc/entrypoint.sh

COPY --chown=www-data:www-data . /var/www/mysite

WORKDIR /var/www/mysite

EXPOSE 80 443

ENTRYPOINT ["/etc/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

nginx-site.conf文件包含您的nginx http主机配置。以下示例适用于Symfony应用程序:

server {
    root    /var/www/mysite/web;

    include /etc/nginx/default.d/*.conf;

    index app.php index.php index.html index.htm;

    client_max_body_size 30m;

    location / {
        try_files $uri $uri/ /app.php$is_args$args;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        # Mitigate https://httpoxy.org/ vulnerabilities
        fastcgi_param HTTP_PROXY "";
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index app.php;
        include fastcgi.conf;
    }
}
Run Code Online (Sandbox Code Playgroud)

entrypoint.sh将运行nginx的和容器启动(否则只能PHP-FPM将开始作为PHP官方图片的默认操作)PHP-FPM:

#!/usr/bin/env bash
service nginx start
php-fpm
Run Code Online (Sandbox Code Playgroud)

从最佳实践的角度来看,这当然不是最佳方法,但我希望这是您的问题的答案。

  • 并在 COPY 之后添加“RUN chmod +x /etc/entrypoint.sh”将防止权限错误。 (5认同)
  • 使用`ENTRYPOINT [“ sh”,“ /etc/entrypoint.sh”]`可以避免出现“权限被拒绝”错误。 (3认同)
  • 最佳实践是为每个容器保留一项服务。从长远来看,在单个容器内混合多个服务可能会导致支持此类 dockerfile 的问题。我并不是说有更好的方法来实现主题问题。我的意思是合并并不是一个完美的方法。 (3认同)
  • 你说这不是最好的做法。你能推荐另一种方法吗? (2认同)
  • 虽然这可能不是“最佳”docker 实践,但在某些只能部署单个容器(例如 google cloud run)的环境中,这是唯一的方法。 (2认同)

Blu*_*sky -10

您应该部署两个容器,一个带有fpm,另一个带有nginx,并且应该链接它们。尽管您可以使用它supervisor来监视同一容器中的多个进程,但Docker原则是每个容器有一个进程。

就像是:

docker run --name php -v ./code:/code php:7-fpm
docker run --name nginx -v ./code:/code -v site.conf:/etc/nginx/conf.d/site.conf --link php nginx:latest
Run Code Online (Sandbox Code Playgroud)

site.conf

server {
    index index.php index.html;
    server_name php-docker.local;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /code;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
Run Code Online (Sandbox Code Playgroud)

(可耻地受到http://geekyplatypus.com/dockerise-your-php-application-with-nginx-and-php7-fpm/的启发)