How to configure Phoenix Framework behind Apache - apache2

I'm trying out Phoenix and for reasons beyond my control, I need it to be served through apache2.
There's a guide for serving Phoenix behind a proxy webserver but it only gives an example configuration for nginx (which I would be using if I could).
So I went to the documentation for mod_proxy and added these two lines to my VirtualHost:
<VirtualHost *:443>
...
LoadModule proxy_module modules/mod_proxy.so
ProxyPass /back http://www.example.com:4000 timeout=10
...
</VirtualHost>
I have the default Phoenix app running in development mode on port 4000. I tried going to https://example.com/back and the result is
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
I've checked my logs at /var/log/apache2/error.log and there is no error message corresponding to GET /back, although there IS a corresponding entry in access.log. All of the other things I'm serving are still working fine. I'm at a loss here, any pointers?

The problem was twofold.
Firstly, proxy submodules needed to be enabled.
sudo a2enmod proxy_http && sudo service apache2 restart
What led me to this fix was enabling a higher log level in apache2.conf:
LogLevel debug proxy:trace4
The relevant error was AH01144 (list of apache2 errors).
Secondly, I needed a reverse proxy:
<VirtualHost *:443>
...
ProxyPass /back http://www.example.com:4000 timeout=10
ProxyPassReverse /back http://www.example.com:4000 timeout=10
...
</VirtualHost>

Related

how to deploy Next.js website on apache webserver [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 months ago.
Improve this question
I made React.js project , but it needs server side rendering, So now I have to migrate from CRA to next.js . the problem: I have to upload my website on apache web server, from what I gathered from google, I need installed node.js and pm2 (latest versions), also configured apache for reverse proxy. I also created ecoystem for pm2(I guess it was necessary). it looks like this at the moment:
module.exports = {
apps : [{
name: "nextjs-app",
script: "npm",
args: "run build",
env: {
NODE_ENV: "production"
}
}]
};
but when I ran pm2 start npm -- start , terminal is giving me respone like this:
pm2 start npm -- start
[PM2] Spawning PM2 daemon with pm2_home=/home/georgianar/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /usr/local/bin/npm in fork_mode (1 instance)
[PM2] Done.
but when I try to see list of process, there is none, and when user tries to enter the website, site log shows that there is no service on port 3000
AH01114: HTTP: failed to make connection to backend: localhost
and
(111)Connection refused: AH00957: http: attempt to connect to 127.0.0.1:3000 (localhost:3000) failed
any idea why?
Well if you want to run both on the same server you can do it in many ways
To run both Node.js and Apache on the same server, follow these steps: https://nodejs.org/en/download/package-manager/
To run your Node.js application as a service, you can use multiple methods such as creating a service, using a process manager (PM2 is common), or running a script on server startup with a cron job. For more information, see this link: How do I run a node.js app as a background service?. You'll need a server start script, typically named server.js, to do this. An example can be found at Next.js: https://nextjs.org/docs/advanced-features/custom-server. To run the application manually in the background, navigate to the app directory and run node ./server.js &
Set up a tunnel using proxypass on Apache. This is commonly used to run the Node.js application on a specific URL. You'll need to install the Apache module mod_proxy and edit the configuration for your Apache server. An example configuration could look like this:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster#example.com
ProxyPreserveHost On
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
You can also wrap the proxypass to run under a specific path using the location tag, like this:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster#example.com
ProxyPreserveHost On
<Location "/mynodeapplication/">
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</Location>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
This will run your application at https://yoururl/mynodeapplication. For more information, see this link: https://httpd.apache.org/docs/trunk/mod/mod_proxy.html.
I hope this covers most of it.
To run Next on Apache, you'll need to set up the Apache settings so that when the domain or subdomain you want Next to run on is accessed, Apache points the request to the local port on the machine that's running Next. Another issue is that Next's built-in server doesn't support SSL (which I'm assuming you want), and using a custom server instead (like Express) loses you many features and optimizations that would otherwise just work with the Next server. So you'll not only need to have Apache redirect to Next, but also have Apache handle the SSL certificate.
To do this, specify a VirtualHost for the server on port 80 to redirect to HTTPS. For example, at least in Ubuntu, in etc/apache2/sites-available/000-default.conf, you can add:
<VirtualHost *:80>
ServerName subdomain.example.com
Redirect / https://subdomain.example.com/
</VirtualHost>
And then set up the SSL certificate for SSL requests (on port 443), and tell Apache to route client requests to the local machine port, and to route the local machine port's responses back to the client. If you're using LetsEncrypt, you can add this into 000-default-le-ssl.conf:
<VirtualHost *:443>
ServerName subdomain.example.com
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://0.0.0.0:16534/
ProxyPassReverse / http://0.0.0.0:16534/
SSLEngine On
SSLProxyEngine On
SSLCertificateFile <insert path to fullchain.pem>
SSLCertificateKeyFile <insert path to privkey.pem>
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
Above, I'm running Next on port 16534 - this is the port you'd see Next logging when it starts:
ready - started server on 0.0.0.0:49447, url: http://localhost:16534
so substitute it with whichever port you're using.
You'll also need to make sure the DNS server for your website points users to your webserver's external IP address by adding an A record, if you don't have one already. If the Next app is to run on a subdomain, you'll need a separate A record for the subdomain.

Apache2 conf file redirecting requests for other enabled sites

I'm running apache2 on ubuntu 16.04. I've configured apache2 to run multiple sites. One of the sites has https setup and to help support this I've added the following rule to redirect http requests to use https:
<VirtualHost *:80>
ServerName http://example.com
Redirect permanent / https://example.com/
</VirtualHost>
This has been too much of a blanket rule as it's redirecting other site's https requests to the domain above.
How can I re-configure the conf above to only redirect http requests for example.com and not the other sites on the same server?
The first listed virtualhost for each host:port acts as the default, catching all unmatched ServerNames. Make sure you don't define your special-case first.
See apachectl -S output for a summary of where your vhosts are loaded from and which one is the default.

Apache2 cannot run WSGI script

I'm installing Reviewboard on linux, I have copied the config provided by the install package to httpd.conf
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/usr/www/reviewboard/htdocs"
# Error handlers
ErrorDocument 500 /errordocs/500.html
WSGIPassAuthorization On
WSGIScriptAlias "/reviewboard" "/usr/www/reviewboard/htdocs/reviewboard.wsgi/reviewboard"
<Directory "/usr/www/reviewboard/htdocs">
AllowOverride All
Options -Indexes FollowSymLinks
Allow from all
</Directory>
# Alias static media requests to filesystem
Alias /reviewboard/media "/usr/www/reviewboard/htdocs/media"
Alias /reviewboard/errordocs "/usr/www/reviewboard/htdocs/errordocs"
Alias /reviewboard/favicon.ico "/usr/www/reviewboard/htdocs/media/rbcommons/images/favicon.png"
</VirtualHost>
However, when I access "http://SITE/reviewboard/htdocs/reviewboard.wsgi", it just gives me the file in plain text instead of running the script
I have checked the mod_wsgi is running on apache2 by "apache2ctl -t -D DUMP_MODULES"
Did I miss any other configuration?
You should be using the URL:
http://SITE/reviewboard
and the WSGIScriptAlias directive should be:
WSGIScriptAlias "/reviewboard" "/usr/www/reviewboard/htdocs/reviewboard.wsgi"
Do be aware though that it is bad practice to be putting your whole Django site under DocumentRoot. That you are seeing the source code for the WSGI script file highlights why it is bad. That is, have an issue with your Apache configuration and you could expose all your source code for people to download. Especially bad if settings.py is in there and it contains database passwords.
Now, address those issues and update question with what you then have and what next problem is as I don't expect that to completely solve the problem because with those mistakes you should have got a different problem than what you describe, so suspect that your configuration is not even being used.

Subdomain proxy pass all pointing to single server

I have 2 applications hosted on a single apache tomcat on port 8080
>
http://mydomain.com:8080/application1
http://mydomain.com:8080/application2
I would like to run an apache proxy in front of BOTH of them with the following behaviour
>
http://mydomain.com/* (apache2) -> http://mydomain.com:8080/application1/* (tomcat)
http://subdomain.mydomain.com/* (apache2) -> http://mydomain.com:8080/application2/* (tomcat)
The best I have got right now is 2 machines with different IPs and routing the domain and subdomains correspondingly.
Ideally I want the apache proxy and the 2 apps to be on the SAME machine...
Can anyone with kick arse DEVOps skills assist?
In addition to #Jon Lin answer, consider using ProxyPassReverse also, just in case your app do any redirects. It makes Apache correct URL's on responses (More about ProxyPassReverse). It will look like that:
<VirtualHost subdomain.mydomain.com:80>
ProxyPass / http://localhost:8080/application1/
ProxyPassReverse / http://localhost:8080/application1/
</VirtualHost>
<VirtualHost mydomain.com:80>
ProxyPass / http://localhost:8080/application1/
ProxyPassReverse / http://localhost:8080/application1/
</VirtualHost>
I hope it helps.
In the virtualhost config for mydomain.com (apache), you need
ProxyPassMatch ^/(.*)$ http://mydomain.com:8080/application1/$1
In the virtualhost config for subdomain.mydomain.com (apache), you nede
ProxyPassMatch ^/(.*)$ http://mydomain.com:8080/application2/$1
Both config files should be on the same machine, and even the same file. See VirtualHost Examples for some examples on how this is setup.

Redirecting https requests to two different weblogic servers using the Weblogic proxy and Apache2

I have a server serverA running a weblogic application App1, with base url /app1/ on port 7001, and another server serverB, running a weblogic application App2, with base url /app2/ on port 8001. Both servers run Solaris, Apache2 and Weblogic 9.2
(details changed, but these are representantive)
In other words, app1 could be accessed on
http://serverA:7001/app1/
and app2 on
http://serverB:8001/app2/
However, the customer requires that all access to the applications use https on port 443 to server1.
If there was only one application, I could use a virtual host and set the handler for URLS beginning with /app1/ to the Weblogic proxy, which would forward them on to server 1 on port 7001.
With two apps, I would need another virtual host with another Location statement matching /app2/ and forwarding to the current server on port 8001 ... but I don't see how this could work as the first virtual host will have done the SSL negotiation to determine the URL, and Apache presumably can't do that over when things fall through to the second virtual server.
So how do I handle this?
My current idea is to proxy all SSL requests arrving at server1 to the same server server1, on port 80 (so essentially just doing SSL termination), then adding two virtual hosts for the /app1/ and /app2/ URLs in the way described above.
Is this going to work? Have I missed something obvious about other ways of doing this?
EDIT: I think I may have missed that the Weblogic plugin can have several blocks each directing the page to different places. In which case this becomes easy.
I will test tomorrow when back at work and update the question
First, the must read resource for this is of course the official documentation : Installing and Configuring the Apache HTTP Server Plug-In (see also this previous answer for more links about the WLS 9 plugin).
As detailed in the section Configuring the Apache HTTP Server Plug-In, I'd define several IfModule, one for each application (clustered or not), and, indeed, several VirtualHost (which can include IfModule). There is an example in the documentation:
# VirtualHost1 = localhost:80
<VirtualHost 127.0.0.1:80>
DocumentRoot "C:/test/VirtualHost1"
ServerName localhost:80 <IfModule mod_weblogic.c>
#... WLS parameter ...
WebLogicCluster localhost:7101,localhost:7201
# Example: MatchExpression *.jsp <some additional parameter>
MatchExpression *.jsp PathPrepend=/test2
</IfModule>
</VirtualHost>
# VirtualHost2 = 127.0.0.2:80
<VirtualHost 127.0.0.2:80>
DocumentRoot "C:/test/VirtualHost1"
ServerName 127.0.0.2:80
<IfModule mod_weblogic.c>
#... WLS parameter ...
WebLogicCluster localhost:7101,localhost:7201
# Example: MatchExpression *.jsp <some additional parameter>
MatchExpression *.jsp PathPrepend=/test2
#... WLS parameter ...
</IfModule>
</VirtualHost> <IfModule mod_weblogic.c>
Note that this is a Multiple IP-Based Virtual Hosts configuration (and not Name-Based as stated in the documentation). But this is actually good because this is exactly what you need when using SSL as you can't use name-based virtual hosts. Quoting Why can't I use SSL with name-based/non-IP-based virtual hosts? from Apache's SSL/TLS Strong Encryption: FAQ
The reason is very technical, and a somewhat "chicken and egg" problem. The SSL protocol layer stays below the HTTP protocol layer and encapsulates HTTP. When an SSL connection (HTTPS) is established Apache/mod_ssl has to negotiate the SSL protocol parameters with the client. For this, mod_ssl has to consult the configuration of the virtual server (for instance it has to look for the cipher suite, the server certificate, etc.). But in order to go to the correct virtual server Apache has to know the Host HTTP header field. To do this, the HTTP request header has to be read. This cannot be done before the SSL handshake is finished, but the information is needed in order to complete the SSL handshake phase. Bingo!
So, in the sampel above, modify the virtual hosts IP addresses and ports, the ServerName, adapt the IfModule to suit your needs (and set up DNS entries to point on the IPs) and there you go.
I don't have any experience with weblogic, so maybe I'm missing something important. But this sounds like a straightforward application for apache's reverse proxy capability. Set up an apache instance serving https, and configure two locations as follows:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<Location /app1>
ProxyPass http://serverA:7001/app1
ProxyPassReverse http://serverA:7001/app1
</Location>
<Location /app2>
ProxyPass http://serverB:8001/app2
ProxyPassReverse http://serverB:8001/app2
</Location>
The example config from the WebLogic 10.3.x documentation is a perfect fit for your question. Here it is with some other details added:
<VirtualHost _default_:443>
SSLEngine on
# other SSL options here...
LoadModule weblogic_module /home/Oracle/Middleware/wlserver_10.3/server/plugin/linux/x86_64/mod_wl_22.so
<IfModule mod_weblogic.c>
<Location /app1>
WebLogicHost serverA
WebLogicPort 7001
SetHandler weblogic-handler
</Location>
<Location /app2>
WebLogicHost serverB
WebLogicPort 8001
SetHandler weblogic-handler
</Location>
</IfModule>
</VirtualHost>
I use this and works fine.

Resources