Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Mojolicious+OpenAPI behind Apache Proxy

by Anonymous Monk
on Jan 07, 2022 at 10:22 UTC ( [id://11140240]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I'm trying to use the Mojolicious plugin OpenAPI to serve two APIs (https://api1.example.com and https://api2.example.com) and a website (https://www.example.com)

I started from the very useful page https://perlmaven.com/deploying-a-mojolicious-application and enabled my sites on Apache with a conf file like this below.

<VirtualHost *:443> ServerAdmin info@example.com ServerName www.example.com SSLProxyEngine on SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyRequests Off ProxyPreserveHost On ProxyPass "/" "http://127.0.0.1:3000/" keepalive=On # :3000 for morbo, :8082 for hypnotoad ProxyPassReverse "/" "http://127.0.0.1:3000/" RequestHeader set X-Forwarded-HTTPS "0" ErrorLog /home/common/logs/www.example.com/error.log LogLevel warn CustomLog /home/common/logs/www.example.com/access.log combined # Use the multisites cert SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain +.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privke +y.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> <VirtualHost *:443> ServerAdmin info@example.com ServerName api1.example.com SSLProxyEngine on SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyRequests Off ProxyPreserveHost On ProxyPass "/" "http://127.0.0.1:3000/" keepalive=On ProxyPassReverse "/" "http://127.0.0.1:3000/" RequestHeader set X-Forwarded-HTTPS "0" LogLevel debug ErrorLog /home/common/logs/api1.example.com/error.log CustomLog /home/common/logs/api1.example.com/access.log combined SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain +.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privke +y.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> <VirtualHost *:443> ServerAdmin info@example.com ServerName api2.example.com SSLProxyEngine on SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyRequests Off ProxyPreserveHost On ProxyPass "/" "http://127.0.0.1:3000/" keepalive=On ProxyPassReverse "/" "http://127.0.0.1:3000/" RequestHeader set X-Forwarded-HTTPS "0" ErrorLog /home/common/logs/api2.example.com/error.log LogLevel warn CustomLog /home/common/logs/api2.example.com/access.log combined Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain +.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privke +y.pem </VirtualHost> <VirtualHost *:80> ServerAdmin info@example.com ServerName www.example.com RewriteEngine on RewriteCond %{SERVER_NAME} =www.example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=perma +nent] </VirtualHost> <VirtualHost *:80> ServerAdmin info@example.com ServerName api1.example.com RewriteEngine on RewriteCond %{SERVER_NAME} =api1.example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=perma +nent] </VirtualHost> <VirtualHost *:80> ServerAdmin info@example.com ServerName api2.example.com RewriteEngine on RewriteCond %{SERVER_NAME} =api2.example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=perma +nent] </VirtualHost>

I then start my application (with morbo or hypnotoad) like so:

use Mojolicious::Lite; app->config( hypnotoad => { listen => [ 'http://127.0.0.1:8082/' ], proxy => 1, }, morbo => { listen => [ 'http://127.0.0.1:3000/' ], proxy => 1, }, ); plugin Mount => { 'api1.example.com' => '/home/common/api1.example.com +/script/api' }; # API1 plugin Mount => { 'api2.example.com' => '/home/common/api2.example.com +/script/api' }; # API2 plugin Mount => { 'www.example.com' => '/home/common/www.example.com/s +cript/website' }; #WEBSITE

API1 and API2 use the OpenAPI plugin. When I test from prompt the two APIs with prove I see they work. Similarly, if I run api routes I see all the endpoints defined in the yaml API definition file.
Instead, when I call these APIs from remote, the endpoint I request is always routed via the first specified Mount, i.e., assuming the order above, when I call an endpoint of API2 it is not found because I see the GET operation is for a route in API1.
If I invert the mount order, the endpoints of API1 are searched as routes of API2.
The same happens when browsing the index.html page in the public folder of API2: I get the index.html page of API1. I don't know if that means the problem has nothing to do with OpeAPI
The website (third Mount, no OpenAPI) is instead working as expected.
I hope you can give me some hint, I'm lost. Thanks

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11140240]
Approved by kcott
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2024-03-28 22:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found