php - 仅当容器重新启动时,本地更改才会传播到 docker 容器

标签 php wordpress docker nginx docker-compose

编辑

我已经创建了一个存储库,用于在 PHP7.3 上使用 Docker 设置 WP,在 php-fpm 上设置最新的 WordPress,我遇到了同样的问题:https://github.com/dingo-d/wordpress-docker

您可以检查一下,看看可能存在什么问题。我的猜测是 PHP-FPM 存在问题(因为重新启动该容器会使更改传播)。


我按照我找到的教程创建了一个 WordPress docker 本地开发环境 here .

基本上,我所有的 docker 内容都位于 .docker 文件夹中。

我在 .docker 文件夹中有这些文件

|--project-folder
|____.docker
| |____php-fpm
| | |____php.ini
| | |____Dockerfile
| |____nginx
| | |____Dockerfile
| | |____logs
| | | |____error.log
| | | |____access.log
| | |____certs
| | | |____dev.project.com.key
| | | |____dev.project.com.crt
| | |____scripts
| | | |____docker-nginx-entrypoint.sh
| | |____nginx.conf
| |____.dockerignore
| |____.env
| |____docker-compose.yml
| |____.env.example

尝试使用自签名 SSL 证书设置所有内容后,我可以登录到 https://localhost:8443 (我在设置主机文件时遇到一些问题,以便我可以到 https://dev.project.com 但这是另一个问题)。

问题是,当我去更改主题中的某些内容时,例如添加一条应该打印出某些内容的 print_r 语句,只有在重新启动我的应用程序后,我才能在 WP 管理中看到该更改WordPress 应用程序容器。文件夹被映射,当我在本地更改内容并执行到容器时,这些更改会立即存在(当我在容器中执行时删除它们时,它们会立即在编辑器中删除)。

我已经测试过使用我在网上找到的 super 简单的 WordPress Docker 设置是否会发生同样的事情

version: '3'
services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: password
       MYSQL_DATABASE: wordpress
       MYSQL_USER: user
       MYSQL_PASSWORD: password

   app:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     volumes:
       - ./wp-content/:/var/www/html/wp-content
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: user
       WORDPRESS_DB_PASSWORD: password
volumes:
    db_data:

当我启动它并转到 localhost:8000 时,我可以立即看到更改,而无需重新启动容器(当我在编辑器中编辑文件时)。

我的docker-compose.yml看起来像这样:

version: '3.7'

services:

  wordpress:
    build:
      context: ..
      dockerfile: .docker/php-fpm/Dockerfile
      args:
        WP_VERSION: ${WP_VERSION}
    container_name: dev-project-wp
    working_dir: /var/www/html
    tty: true
    depends_on:
      - database
    volumes:
      - ../:/var/www/html
      - ./php-fpm/php.ini:/usr/local/etc/php/conf.d/local.ini
    environment:
      DB_PORT: ${DB_PORT}
      DB_HOST: ${DB_HOST}
      DB_NAME: ${DB_NAME}
      DB_USER: ${DB_USER}
      DB_PASSWORD: ${DB_PASSWORD}
      AUTH_KEY: ${AUTH_KEY}
      SECURE_AUTH_KEY: ${SECURE_AUTH_KEY}
      LOGGED_IN_KEY: ${LOGGED_IN_KEY}
      NONCE_KEY: ${NONCE_KEY}
      AUTH_SALT: ${AUTH_SALT}
      SECURE_AUTH_SALT: ${SECURE_AUTH_SALT}
      LOGGED_IN_SALT: ${LOGGED_IN_SALT}
      NONCE_SALT: ${NONCE_SALT}
      DB_PREFIX: ${DB_PREFIX}
      WP_VERSION: ${WP_VERSION}
    ports:
      - '9000'
    expose:
      - '80'

  nginx:
    build:
      context: ..
      dockerfile: .docker/nginx/Dockerfile
      args:
        DOCKER_IMAGE_NAME_PHP: 'docker_wordpress'
    container_name: dev-project-nginx
    working_dir: /var/www/html
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/certs/dev.project.com.crt:/etc/nginx/dev.project.com.crt
      - ./nginx/certs/dev.project.com.key:/etc/nginx/dev.project.com.key
      - ../:/var/www/html
      - ./nginx/logs:/var/log/nginx
    depends_on:
      - wordpress
    ports:
      - "${NGINX_HOST_HTTP_PORT}:80"
      - "${NGINX_HOST_HTTPS_PORT}:443"

  database:
    image: mariadb:10.3
    volumes:
      - projectdb:/var/lib/mysql
    restart: always
    container_name: ${DB_HOST}
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: 1
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    ports:
      - "${DB_HOST_PORT}:${DB_PORT}"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: dev-project-phpmyadmin
    external_links:
      - database
    depends_on:
      - database
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: 1
      MYSQL_USERNAME: root
      PMA_HOST: ${DB_HOST}
    ports:
      - "${PHPMYADMIN_HOST_PORT}:80"

  mailhog:
    image: mailhog/mailhog
    container_name: dev-project-mailhog
    ports:
      - "${MAILHOG_HOST_PORT_SMTP}:1025"
      - "${MAILHOG_HOST_PORT_WEB}:8025"

volumes:
  projectdb:

我有一个如下所示的 .env:

# required so we can reach the nginx server from other containers via that hostname
APP_HOST=dev.project.com

# nginx
NGINX_HOST_HTTP_PORT=8180
NGINX_HOST_HTTPS_PORT=8443

# database
DB_HOST_PORT=33060
DB_PORT=3306
DB_HOST=dev-project-db
DB_NAME=docker-project
DB_USER=wp
DB_PASSWORD=wp

#phpmyadmin
PHPMYADMIN_HOST_PORT=8088

# wordpress - https://api.wordpress.org/secret-key/1.1/salt/
AUTH_KEY=':1k7<tW.#pE-O%*nZv7qM@me.#PLE;7).#g<4_.]04,2cM|]:*r8|:osljhB]s*.'
SECURE_AUTH_KEY='N~?~Z0(ijZS%|cHe#~F!O.31N#;VQSI~QBL%~oWZFGfU6R`%k#(eD)2Mcm}wLh0a'
LOGGED_IN_KEY='y7T8hoW|Ik4eBUGWUs6j~O*j)k{hrZ`E.ujW+Za{`WPn9Xk.&g]*F(HsV~q0fL8g'
NONCE_KEY='V0aau(w+|CAW_.+ilIkYaIh]8Bz}@,DdX@yBi+!dD5Zy:,YO+<CF+oYwP+~jYE,r'
AUTH_SALT='_zQ C^rzH%wBmmyjO,KH`J-EIZm$.MIzK[b(ar2+TgO=P&hHQ7d*lPsd8*+xu{4u'
SECURE_AUTH_SALT='EL~r.88e=TYM>W&LP]BI(u_f,PLQY|m%+2(2TF%,|S,Wc4uYV)hVBpZ .KA$cGhY'
LOGGED_IN_SALT='hEoqqkkJO~f`|p~43>gZx$;u&% {qJLe$OnreM,dfR`H?an+q3g`&9>?-v3iSoJ&'
NONCE_SALT='jfEVaR]Od2,yDPN|$o+g7Hd=XIwM,ow#a,,u|~d+pf/<T#NBcm(u9v?qpr#g^q5k'

DB_PREFIX=wp_
WP_VERSION=5.2.2

# mailhog
MAILHOG_HOST_PORT_SMTP=1028
MAILHOG_HOST_PORT_WEB=8028

我的 php dockerfile 看起来像这样

ARG WP_VERSION

# Stage 0, build app
FROM php:7.3-fpm-stretch as build-container

RUN curl -sS https://getcomposer.org/installer | php \
  && chmod +x composer.phar && mv composer.phar /usr/local/bin/composer

RUN apt-get update && apt-get install -y gnupg
RUN curl -sL https://deb.nodesource.com/setup_11.x | bash - && \
    apt-get install -yq nodejs build-essential \
        git unzip \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
        pkg-config \
        libmcrypt-dev \
        libpng-dev \
    && pecl install mcrypt-1.0.2 \
    && docker-php-ext-enable mcrypt \
    && docker-php-ext-install bcmath \
    && docker-php-ext-install -j$(nproc) mysqli \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd

RUN npm install -g npm

WORKDIR /

WORKDIR /build
COPY . /build

RUN cp /build/wp-config.php.template /build/wp-config.php
# RUN bash /build/scripts/build-plugins.sh

# Stage 2, build app container
FROM php:7.3-fpm-stretch
ARG WP_VERSION

RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng-dev \
        libzip-dev \
        unzip \
        mariadb-client \
        libmagickwand-dev \
    && docker-php-ext-configure gd --with-png-dir=/usr/include/ --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) \
        bcmath \
        exif \
        gd \
        mysqli \
        opcache \
        zip \
        pdo \
        pdo_mysql \
        mysqli \
    && docker-php-ext-install -j$(nproc) iconv \
    && export CFLAGS="$PHP_CFLAGS" CPPFLAGS="$PHP_CPPFLAGS" LDFLAGS="$PHP_LDFLAGS" \
    && rm -rf /var/lib/apt/lists/* \
    && pecl install imagick-3.4.4 \
    && docker-php-ext-enable imagick

ADD https://downloads.wordpress.org/release/wordpress-$WP_VERSION-no-content.zip /var/www/latest.zip
RUN cd /var/www && unzip latest.zip && rm latest.zip
RUN rm -rf /var/www/html
RUN mkdir -p /var/www/html \
    && mv /var/www/wordpress/* /var/www/html/

# Copy wp files
COPY --from=build-container /build/ /var/www/html/
RUN chown www-data:www-data /var/www/html/ -R
COPY .docker/php-fpm/php.ini /usr/local/etc/php/
WORKDIR /var/www/html/

CMD ["php-fpm"]

nginx 的 dockerfile 看起来像这样

ARG DOCKER_IMAGE_NAME_PHP
FROM $DOCKER_IMAGE_NAME_PHP as php-image

FROM nginx:latest

COPY .docker/nginx/scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY .docker/nginx/nginx.conf /opt/nginx.conf

COPY --from=php-image /var/www/html/ /var/www/html/

CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]

nginx.conf 如下所示:

worker_processes auto;

events {
  worker_connections  2048;
}


http {

  include       mime.types;

  index index.php index.html index.htm;

  server {
    listen 80;
    listen [::]:80;

    listen 443 ssl;
    listen [::]:443 ssl;

    server_name dev.project.com;

    ssl_certificate /etc/nginx/dev.project.com.crt;
    ssl_certificate_key /etc/nginx/dev.project.com.key;

    root /var/www/html;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    client_max_body_size 128M;

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

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

    location ~ \.php$ {
      include fastcgi_params;
      fastcgi_intercept_errors on;
      fastcgi_pass wordpress:9000;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param QUERY_STRING    $query_string;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
      expires max;
      log_not_found off;
    }
  }
}

docker-nginx-entrypoint.sh 脚本如下所示

#!/bin/bash
set -e

cp /opt/nginx.conf /etc/nginx/conf.d/default.conf

exec nginx -g "daemon off;"

启动我使用的docker

docker-compose -f .docker/docker-compose.yml --project-directory .docker up -d --build

我查看了日志,没有错误(在wp容器或nginx日志中)。当我访问 https://localhost:8443/wp-admin/时,该网站工作正常,但更改仅在容器重置时传播。这毫无意义(更不用说它基本上是一个无法使用的开发环境)。

附注

这是一个有点复杂的设置,如果您有任何简化它的建议,欢迎提出建议。

编辑

我使用 webpack 捆绑资源,当捆绑它们时,更改是可见的。对 PHP 文件的更改不是...

编辑2

我已经使用了 nginx 和 wordpress 的官方镜像,并且 PHP 部分再次仅在重新启动时更改,因此这不是 Dockerfile 中的问题。

最佳答案

事实证明罪魁祸首是opcache。或者更确切地说,我在网上找到一些示例,然后将其添加到我的 php.ini 中,而不试图理解这实际上意味着什么。

阅读后this article还有这个excellent article这解释了一些 opcache 设置,我意识到我的 php.ini 文件有

opcache.revalidate_freq=60

不应该在本地开发环境中使用它!

opcache.validate_timestamps 一起使用时,PHP 会检查 revalidate_freq 设置并将其用作时间戳 - 如果您在 60 秒内发出请求(如上面的示例) ,代码将从 opcache 中提取 - 并且您不会在浏览器中看到任何更改。只有 60 秒后此更改才会可见。

因此将其设置为 0(检查每个请求的代码)可以解决该问题。

故事要点:检查所有内容并阅读您使用的每个设置!

“不幸的是”对我来说,我正在阅读 nginx 配置,因为我认为我搞砸了那里的东西 😁

关于php - 仅当容器重新启动时,本地更改才会传播到 docker 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57347723/

相关文章:

javascript - 在特定的 div 之后插入一些文本到 WordPress 前端

docker - 启动 Docker 的问题 - 无法启动 LSB : Create lightweight, 可移植、自给自足的容器

php - 无法在 Google Glass 上播放视频(附件选项或捆绑选项)

php - Hooks around 添​​加到 Woocommerce 的购物车

javascript - Ajax 函数未调用

javascript - 无法在 Internet Explorer 中嵌入 Youtube mediaelement

php - 如何在一个容器中安装 nginx 而在另一个容器中安装 php-fpm?

Docker:从中间层删除文件

php - KnpMenuBundle - 如何为菜单的每个元素设置图标类?

php - 如何使用 PHP OAuth 设置 "realm"?