Configuring Apache to run SvelteKit frontend alongside PHP backend

I’ve developed a SvelteKit frontend and a PHP backend which includes an API and database connection files. However, I’m struggling to get Apache to serve both segments of my application concurrently.

When I access mydomain.com/api/users.php, I receive database connection errors, and my PHP code displays as plain text rather than being executed. Interestingly, when I go to the same file with my server’s IP directly, it functions correctly.

The odd part is that my domain won’t run PHP files properly, while my IP fails to show the frontend—just the standard Apache landing page.

I’ve been adjusting my virtual host configuration for several days without success. Here’s how it’s currently set up:

<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/html
    
    # Process API requests
    Alias /api/ /var/www/html/api/
    <Directory "/var/www/html/api">
        AllowOverride All
        Require all granted
        <FilesMatch "\.php$">
            SetHandler application/x-httpd-php
        </FilesMatch>
    </Directory>
    
    # Forward frontend to SvelteKit side
    ProxyPass /api/ !
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>

My directory structure appears as follows:

html/
├── sveltekit-app/
├── api/
│   ├── users.php
│   └── database.php
├── src/
│   └── routes/
└── package.json

I utilize pm2 to manage my SvelteKit application running on port 3000. The database access works without issues via IP, yet fails with the domain. Can anyone suggest what might be creating this problem?

Your directory structure doesn’t match your virtual host config. DocumentRoot points to /var/www/html, but your SvelteKit app is in /var/www/html/sveltekit-app/ and your API is in /var/www/html/api/. When you access via domain, the proxy sends everything except /api/ to localhost:3000, but your SvelteKit app might not be serving from the right spot. Make sure your SvelteKit build output is set to serve from the document root or change your DocumentRoot to point to the actual build directory. Also, check that your database connection file uses absolute paths or relative paths that work no matter how you access it. The plain text display means PHP isn’t being processed—either the FilesMatch directive isn’t working or the PHP module isn’t loaded for that virtual host.

Hmm, interesting. When you say the database connection works with IP but fails with domain - are you using the same credentials for both? Maybe your DB config has hostname restrictions, or the connection string’s hardcoded differently? What do the error logs show when you try domain vs IP?

the proxy config’s probably messing with php execution. try moving your ProxyPass directives above the directory block, or add ProxyPreserveHost On to keep the server context right. also check that your php module’s actually enabled for SSL vhosts - i’ve seen it configured only for port 80 before.