【问题标题】:Local changes propagate to docker container only when container is restarted仅当容器重新启动时,本地更改才会传播到 docker 容器
【发布时间】:2019-12-12 08:03:15
【问题描述】:

编辑

我创建了一个 repo,用于在 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 语句,我只能在我重新启动我的 WordPress 应用程序容器后才能在 WP 管理员中看到该更改。文件夹已映射,当我在本地更改内容并执行到容器时,这些更改会立即存在(当我在容器中执行时删除它们时,它们会立即在我的编辑器中删除)。

我已经测试了我在网上找到的超级简单的 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 部分再次仅在重启时更改,所以这不是 Dockerfiles 中的问题。

【问题讨论】:

    标签: php wordpress docker nginx docker-compose


    【解决方案1】:

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

    在阅读 this article 和解释一些 opcache 设置的 excellent article 之后,我意识到我的 php.ini 文件有

    opcache.revalidate_freq=60
    

    在本地开发环境中不应该拥有的东西!

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

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

    故事的重点:检查所有内容并了解您使用的每个设置!

    '不幸'对我来说,我正在阅读 nginx 配置,因为我认为我在那里搞砸了一些东西?

    【讨论】:

    • 非常感谢@dingo_d,你为我节省了更多时间撕头发——我确实遇到了这个问题。
    猜你喜欢
    • 2020-01-21
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2019-11-01
    • 2016-12-08
    • 1970-01-01
    相关资源
    最近更新 更多