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

单域名下多应用及多版本的Apache适配配置技术问询

Great question—this is a common pain point when running multiple app environments on a single server, and the solution lies in using Apache VirtualHosts to isolate each app instance completely. Let's break this down step by step:

Solution Overview

The core fix is to give each production/staging app instance its own VirtualHost with a unique hostname (either a subdomain of your company's domain or an internal custom hostname). This way, each app's code root becomes the web server's DocumentRoot, so relative paths and root-based routing work exactly as the app expects—no more hardcoding absolute paths.

1. Using Subdomains (For External/Internal Production/Staging Access)

If you want these apps accessible via your company's official domain structure, use subdomains like app1.example.com (production) and app1-staging.example.com (staging). Here's how to configure Apache:

Step 1: DNS Setup

First, add A records for each subdomain in your company's DNS manager, pointing all of them to your server's public IP address.

Step 2: Apache VirtualHost Config

Create separate VirtualHost blocks for each app environment. For example:

# Enable required modules first (if not already enabled)
# a2enmod rewrite proxy proxy_fcgi

# App 1 - Production Environment
<VirtualHost *:80>
    ServerName app1.example.com
    # Point DocumentRoot directly to the app's public/web root (e.g., Laravel's public folder)
    DocumentRoot /var/www/app1/production/public

    <Directory /var/www/app1/production/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All  # Enables .htaccess for framework routing
        Require all granted

        # Configure PHP-FPM (adjust socket path to match your PHP version)
        SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
    </Directory>

    # Logging for debugging
    ErrorLog ${APACHE_LOG_DIR}/app1-prod-error.log
    CustomLog ${APACHE_LOG_DIR}/app1-prod-access.log combined
</VirtualHost>

# App 1 - Staging Environment
<VirtualHost *:80>
    ServerName app1-staging.example.com
    DocumentRoot /var/www/app1/staging/public

    <Directory /var/www/app1/staging/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/app1-staging-error.log
    CustomLog ${APACHE_LOG_DIR}/app1-staging-access.log combined
</VirtualHost>

After adding these configs, restart Apache:

sudo systemctl restart apache2

2. Using /etc/hosts + VirtualHosts (Internal-Only Access)

Absolutely—this is a perfect approach for internal testing, development, or staging environments where you don't want to expose hostnames to public DNS. Here's how:

Step 1: Configure /etc/hosts

On every machine that needs to access these apps (including the server itself), edit /etc/hosts to map custom hostnames to your server's IP. For example:

# Replace 192.168.1.100 with your server's internal IP
192.168.1.100 app1-local.example.com
192.168.1.100 app1-staging-local.example.com

Step 2: Apache VirtualHost Config

Create VirtualHost blocks matching the hostnames you defined in /etc/hosts. The config is nearly identical to the subdomain setup—just change the ServerName:

<VirtualHost *:80>
    ServerName app1-local.example.com
    DocumentRoot /var/www/app1/production/public
    # Same directory and PHP config as production
</VirtualHost>

<VirtualHost *:80>
    ServerName app1-staging-local.example.com
    DocumentRoot /var/www/app1/staging/public
    # Same directory and PHP config as staging
</VirtualHost>

Restart Apache, and you can now access http://app1-local.example.com or http://app1-staging-local.example.com from any machine with the updated /etc/hosts file.

Why This Works

  • Each app instance has its own isolated DocumentRoot, so relative paths like <link href="css/style.css"> resolve to the app's own css folder, not a shared path.
  • Root-based routes (e.g., $router->map("GET", "/action", SomeController)) work because the app's root is the web server's root—no need to prefix routes with app-specific paths.
  • Production and staging code can be identical because they're running from separate directories, each mapped to its own hostname.

Key Notes

  • SSL: If you need HTTPS, generate SSL certificates for each hostname (use Let's Encrypt for public subdomains, or self-signed certificates for internal hosts). Update the VirtualHosts to use *:443 and add SSLCertificateFile/SSLCertificateKeyFile directives.
  • Module Checks: Ensure Apache has mod_rewrite, mod_proxy, and mod_proxy_fcgi enabled (use a2enmod <module> to enable them).
  • Directory Permissions: Make sure Apache has read access to your app directories (set appropriate ownership, e.g., chown -R www-data:www-data /var/www/app1).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:38:05