You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSL2 Docker环境下Apache反向代理+Browsersync配置故障排查

WSL2 Docker环境下Browsersync无法访问问题排查

我在WSL2(Ubuntu)的Docker环境中部署Browsersync、WordPress与Apache,此前在Windows的XAMPP中成功配置过Browsersync,但当前环境复杂度更高。

除Browsersync外其余服务均正常:可在Windows浏览器通过80/443端口访问mysite.localhost的WordPress,但访问http://mysite.localhost:3000的Browsersync时,Apache无日志响应,浏览器返回以下错误:

This site can’t be reached
mysite.localhost unexpectedly closed the connection
ERR_CONNECTION_CLOSED

修改文件时Browsersync日志能检测到变更,但浏览器无法加载内容。以下是相关配置文件及日志:


Docker Compose配置

services:

  node:
    build:
      context: .
      dockerfile: ./docker/node/Dockerfile
    image: node:18.16.1-build
    container_name: node
    restart: always
    depends_on:
      - wordpress
    # user: "node"
    expose:
      - 3000
      - 3001
    volumes:
      - ./wordpress/source/themes/omikuji/src:/home/node/omikuji/src
      - ./wordpress/source/themes/omikuji/dist:/home/node/omikuji/dist
      - ./wordpress/source/themes/omikuji/bs-config.js:/home/node/omikuji/bs-config.js
    command: "npm run dev"
    networks:
      - apache

  database:
    #...database stuff
    networks:
      - apache

  wordpress:
    build:
      context: .
      dockerfile: ./docker/wordpress/Dockerfile
    image: wordpress:6.2.2-php8.1-build
    container_name: wordpress
    restart: always
    hostname: mysite.localhost
    depends_on:
      database:
        condition: service_healthy
    expose:
      - 80
    volumes:
      - ./wordpress/source/themes/omikuji/dist:/var/www/html/wp-content/themes/omikuji
    environment:
      TZ: ${TZ} # Set local time
      WORDPRESS_DB_HOST: database
      WORDPRESS_DB_USER: ${MARIADB_USER}
      WORDPRESS_DB_PASSWORD: ${MARIADB_PASSWORD}
      WORDPRESS_DB_NAME: ${MARIADB_DATABASE}
      WORDPRESS_DEBUG: 1
    networks:
      - apache

  phpmyadmin:
    # ...phpmyadmin stuff
    networks:
      - apache

  apache:
    build:
      context: .
      dockerfile: ./docker/apache/Dockerfile
    image: httpd:2.4-build
    container_name: apache
    ports:
      - 80:80
      - 443:443
      - 3000:3000
      - 3001:3001
    environment:
      TZ: ${TZ} # Set local time
    networks:
      - apache

volumes:
  db_data:
    external: true

networks:
  apache:
    name: apache

Browsersync配置

module.exports = {
  "logLevel": "debug",
  "logConnections": false,
  "logFileChanges": true,
  "logSnippet": true,
  "open": false,
  "files": ["./dist/style.css", "./dist/js/*.js", "./dist/*.php"],
  "proxy": "http://node:3000",
  "host": "node",
  "port": 3000,
  "reloadDebounce": 2000,
  "watchOptions": {
    "awaitWriteFinish": true
  }
};

Apache虚拟主机配置(httpd-vhosts.conf)

<VirtualHost *:80>
  ServerName localhost
  RewriteEngine On
  RewriteCond %{HTTP:X-Forwarded-Proto} !https
  RewriteCond %{HTTPS} !=on
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName mysite.localhost

  # SSL redirection is in .htaccess

  # Reverse proxy
  ProxyPreserveHost On
  ProxyPass / http://wordpress:80/
  ProxyPassReverse / http://wordpress:80/
  RequestHeader set X-Forwarded-Proto http
</VirtualHost>

<VirtualHost *:443>
  ServerName mysite.localhost

  # Reverse proxy
  ProxyPreserveHost On
  ProxyPass / http://wordpress:80/
  ProxyPassReverse / http://wordpress:80/
  RequestHeader set X-Forwarded-Proto https

  # Enable SSL
  SSLEngine on
  SSLCertificateFile /etc/ssl/certs/mysite.localhost.pem
  SSLCertificateKeyFile /etc/ssl/private/mysite.localhost-key.pem
</VirtualHost>

<VirtualHost *:3000>
  ServerName mysite.localhost

  # Reverse proxy
  ProxyPreserveHost On
  ProxyPass / http://node:3000/
  ProxyPassReverse / http://node:3000/
  RequestHeader set X-Forwarded-Proto http

  # Enable SSL
  SSLEngine on
  SSLCertificateFile /etc/ssl/certs/mysite.localhost.pem
  SSLCertificateKeyFile /etc/ssl/private/mysite.localhost-key.pem
</VirtualHost>

WordPress根目录.htaccess重写规则

RewriteEngine On

# If the request is not https on the development server (reverse proxy)
RewriteCond %{HTTP:X-Forwarded-Proto} !https

# If the request is not https on the production server
RewriteCond %{HTTPS} !=on

# Redirect to SSL
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Apache Dockerfile

FROM httpd:2.4

# Copy the configuration files
WORKDIR /usr/local/apache2/conf
COPY ./localhost/apache/httpd.conf httpd.conf

# Copy the configuration extra files
WORKDIR /usr/local/apache2/conf/extra
COPY ./localhost/apache/httpd-vhosts.conf httpd-vhosts.conf
COPY ./localhost/apache/httpd-ssl.conf httpd-ssl.conf
COPY ./localhost/apache/proxy-html.conf proxy-html.conf

# Copy the SSL certificates
WORKDIR /etc/ssl/certs
COPY ./localhost/certs/localhost.pem localhost.pem
COPY ./localhost/certs/mysite.localhost.pem mysite.localhost.pem
COPY ./localhost/certs/phpmyadmin.localhost.pem phpmyadmin.localhost.pem

# Copy the SSL certificate private keys
WORKDIR /etc/ssl/private
COPY ./localhost/private/localhost-key.pem localhost-key.pem
COPY ./localhost/private/mysite.localhost-key.pem mysite.localhost-key.pem
COPY ./localhost/private/phpmyadmin.localhost-key.pem phpmyadmin.localhost-key.pem

# Change to default directory
WORKDIR /usr/local/apache2

Node Dockerfile

FROM node:18.16.1

# Copy SSL certificates
WORKDIR /etc/ssl/certs
COPY ./localhost/certs/mysite.localhost.pem mysite.localhost.pem
WORKDIR /etc/ssl/private
COPY ./localhost/private/mysite.localhost-key.pem mysite.localhost-key.pem

# Copy configuration files to root
RUN mkdir /home/node/omikuji
WORKDIR /home/node/omikuji
COPY ./wordpress/source/themes/omikuji/.stylelintrc.json .stylelintrc.json
COPY ./wordpress/source/themes/omikuji/package.json package.json
COPY ./wordpress/source/themes/omikuji/package-lock.json package-lock.json

# Install npm packages
RUN npm install

# Add environment variables after installing npm
ENV NPM_CONFIG_LOGLEVEL info
ENV NODE_ENV development

Node日志(可检测文件变更)

*  Executing task in folder Development: docker logs --tail 1000 -f 78ed8100eca903cd446d057b7da9f05fefac45f31d97d865e9b32a9264c15665 

npm info using npm@9.5.1
npm info using node@v18.16.1

> omikuji@2.0.0 dev
> npm-run-all --parallel localhost dev:scss

npm info using npm@9.5.1
npm info using node@v18.16.1
npm info using npm@9.5.1
npm info using node@v18.16.1

> omikuji@2.0.0 dev:scss
> sass --watch --verbose --style=expanded ./src/scss/style.scss:./dist/style.css


> omikuji@2.0.0 localhost
> browser-sync start --config 'bs-config.js'

[Browsersync] [debug] -> Starting Step: Finding an empty port
[Browsersync] [debug] Found a free port: 3000
[Browsersync] [debug] Setting Option: {cyan:port} - {magenta:3000
[Browsersync] [debug] +  Step Complete: Finding an empty port
[Browsersync] [debug] -> Starting Step: Getting an extra port for Proxy
[Browsersync] [debug] +  Step Complete: Getting an extra port for Proxy
[Browsersync] [debug] -> Starting Step: Checking online status
[Browsersync] [debug] Resolved www.google.com, setting online: true
[Browsersync] [debug] Setting Option: {cyan:online} - {magenta:true
[Browsersync] [debug] +  Step Complete: Checking online status
[Browsersync] [debug] -> Starting Step: Resolve user plugins from options
[Browsersync] [debug] +  Step Complete: Resolve user plugins from options
[Browsersync] [debug] -> Starting Step: Set Urls and other options that rely on port/online status
[Browsersync] [debug] Setting multiple Options
[Browsersync] [debug] +  Step Complete: Set Urls and other options that rely on port/online status
[Browsersync] [debug] -> Starting Step: Setting Internal Events
[Browsersync] [debug] +  Step Complete: Setting Internal Events
[Browsersync] [debug] -> Starting Step: Setting file watchers
[Browsersync] [debug] +  Step Complete: Setting file watchers
[Browsersync] [debug] -> Starting Step: Merging middlewares from core + plugins
[Browsersync] [debug] Setting Option: {cyan:middleware} - {magenta:List []
[Browsersync] [debug] +  Step Complete: Merging middlewares from core + plugins
[Browsersync] [debug] -> Starting Step: Starting the Server
[Browsersync] [debug] Proxy running, proxing: {magenta:http://node:3000}
[Browsersync] [debug] Running mode: PROXY
[Browsersync] [debug] +  Step Complete: Starting the Server
[Browsersync] [debug] -> Starting Step: Starting the HTTPS Tunnel
[Browsersync] [debug] +  Step Complete: Starting the HTTPS Tunnel
[Browsersync] [debug] -> Starting Step: Starting the web-socket server
[Browsersync] [debug] Setting Option: {cyan:clientEvents} - {magenta:List [ "scroll", "scroll:element", "input:text", "input:toggles", "form:submit", "form:reset", "click" ]
[Browsersync] [debug] +  Step Complete: Starting the web-socket server
[Browsersync] [debug] -> Starting Step: Starting the UI
[Browsersync] [debug] Setting Option: {cyan:session} - {magenta:1690129836067
[Browsersync] [UI] Starting Step: Setting default plugins
[Browsersync] [UI] Step Complete: %s Setting default plugins
[Browsersync] [UI] Starting Step: Finding a free port
[Browsersync] [UI] Step Complete: %s Finding a free port
[Browsersync] [UI] Starting Step: Setting options also relevant to UI from BS
[Browsersync] [UI] Step Complete: %s Setting options also relevant to UI from BS
[Browsersync] [UI] Starting Step: Setting available URLS for UI
[Browsersync] [debug] Getting option via path: {magenta:[ 'urls' ]
[Browsersync] [UI] Step Complete: %s Setting available URLS for UI
[Browsersync] [UI] Starting Step: Starting the Control Panel Server
[Browsersync] [UI] Using port 3001
[Browsersync] [UI] Step Complete: %s Starting the Control Panel Server
[Browsersync] [UI] Starting Step: Add element events
[Browsersync] [UI] Step Complete: %s Add element events
[Browsersync] [UI] Starting Step: Registering default plugins
[Browsersync] [UI] Step Complete: %s Registering default plugins
[Browsersync] [UI] Starting Step: Add options setting event
[Browsersync] [UI] Step Complete: %s Add options setting event
[Browsersync] [debug] +  Step Complete: Starting the UI
[Browsersync] [debug] -> Starting Step: Merge UI settings
[Browsersync] [debug] Setting Option: {cyan:urls} - {magenta:Map { "local": "http://localhost:3000", "external": "http://node:3000", "ui": "http://localhost:3001", "ui-external": "http://localhost:3001" }
[Browsersync] [debug] +  Step Complete: Merge UI settings
[Browsersync] [debug] -> Starting Step: Init user plugins
[Browsersync] [debug] Setting Option: {cyan:userPlugins} - {magenta:
[Browsersync] [debug] +  Step Complete: Init user plugins
[Browsersync] Proxying: http://node:3000
[Browsersync] Access URLs:
 ----------------------------------
       Local: http://localhost:3000
    External: http://node:3000
 ----------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 ----------------------------------
[Browsersync] Watching files...
Sass is watching for changes. Press Ctrl-C to stop.

[2023-07-23 16:30] Compiled src/scss/style.scss to dist/style.css.
[Browsersync] File event [change] : dist/style.css

内容的提问来源于stack exchange,提问作者edwinbradford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:55:55