Application Server & CORS Config
Tags: codenewbie, todayilearned, sideprojects, security
Published: 2021-01-06 23:43:19

At this point basically everything is set up but you probably can't access anything yet or your may only be able to see a landing page with no useful information on it. This is because the Apache HTTP Server doesn't know how to communicate with the Ruby API. ![Communication is key](https://media.giphy.com/media/jRx6JhvYbL6fbC65qF/giphy.gif)

See, for a dynamic application like a Rails API there needs to be some kind of Rack-Compatible Server to handle the incoming requests that the HTTP server isn't able to process. This is where an [Application Server](https://dev.to/caffiendkitten/building-a-home-test-server-27h1#WebServerVsHTTPServer), like [Phusion Passenger](https://www.phusionpassenger.com/) or Apache Tomcat, or a Rack-compatible web server, like [Puma](https://puma.io/), are needed to process the dynamic content requests got the HTTP server.

Because I had built a Rack specific application there are, like always, a few ways you could set this up.
1. You could set up Apache with a reverse proxy for a stand alone Rack-specific web server, like Puma or Unicorn.
2. You could use an Apache module, like Phusion Passenger, to manage the processes and any needed reverse proxying.

Though I was originally using Puma as a stand alone server, and because it's [Heroku's Recommended Ruby Webserver](https://devcenter.heroku.com/changelog-items/594), this section will be about my process of changing over to the [Application Server](https://dev.to/caffiendkitten/building-a-home-test-server-27h1#WebServerVsHTTPServer), Passenger, to help handle the Ruby on Rails routing and how I dealt with [CORS](https://dev.to/caffiendkitten/building-a-home-test-server-27h1#CORS) for my API. That being said, if you created your own Rails API from scratch for this you might not want to use Passenger and use a straight PHP interface or Puma instead. 




# <a name="TOC">Table Of Contents</a>
Step 1: [Adding in an Application Server](#S1)
Step 2: [Setting Apache Passenger configuration](#S2)
Step 3: [Accessing Rails Routes](#S3)









# <a name="S1">Step 1: Adding in an Application Server</a>
First thing first is to add Passenger into the server to be used. 

1. Navigate to the applications "backend" folder, if not there already, with `cd /var/www/etcpasswdapp/backend`.
2. Run `sudo nano Gemfile` to edit the Gemfile.
3. If it's there, "comment out" the Puma gem in the Gemfile by placing a `#` at the beginning of the Puma gem line. 
4. Now add `gem "passenger", ">= 5.0.25", require: "phusion_passenger/rack_handler"` (the Passenger gem) below the commented out Puma gem.![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/utvl5nz8sv0s8lrz5qnx.png)
5. Save and close the file.
6. Add the Passenger packages into Ubuntu with the following `sudo` commands. ```
Install our PGP key and add HTTPS support for APT with:
        sudo apt-get install -y dirmngr gnupg
        sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
        sudo apt-get install -y apt-transport-https ca-certificates
Add our APT repository with:
        sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger focal main > /etc/apt/sources.list.d/passenger.list'
         sudo apt-get update
Install Passenger with:
        sudo apt-get install -y passenger
```
7. Run `bundle install` to ensure that all the gem dependencies are up to date and the passenger gem in installed.
8. Run `passenger-install-apache2-module` to run the Passenger Apache module installer.
9. Check the package was installed correctly with `sudo /usr/bin/passenger-config validate-install`. 
 - It might give you an option to check the path or the install like mine did below. Use the up and down arrows to select one and press "enter" to select it. I recommend running it twice to check both have a valid install.![Validate Passenger](https://dev-to-uploads.s3.amazonaws.com/i/bmorac4v1bhl70uvvtxh.jpg)
10. Now run `sudo a2enmod passenger` to enable the Passenger Apache module.

Because I am using Ubuntu 20.04 for this project got stuck here and found out that I needed to also configure my main Apache "conf" file. If you are not using Ubuntu 20.04 you might skip the next step for setting up the Apache Passenger Configuration, but you might want to read it over if something applies to you.


{[Back to the Table Of Contents](#TOC)}











# <a name="S2">Step 2: Setting Apache Passenger configuration</a>
When I ran the the command `sudo a2enmod passenger` to enable the Passenger Apache module in the previous step, it returned some information about a "passenger.load" file and a "passenger.conf" file. ![Returned Text](https://dev-to-uploads.s3.amazonaws.com/i/xqx1549h0xnyocz3204y.jpg) At the time I didn't understand it but after some research it turns out that for Apache 20.04 some [additional configurations](https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/apache/working_with_the_apache_config_file.html) need to be added to the Apache "conf" file to specify the location of the passenger files. Refer to [this tutorial](https://www.phusionpassenger.com/library/config/apache/intro.html) if something doesn't make since. <sup>[4](#L4)</sup>

1. Navigate into the "mods-enabled" folder with `cd /etc/apache2/mods-enabled`.
2. Run `sudo nano passenger.load` to edit the passenger file.
3. Add the "LoadModule" that was output and comment out the current "LoadModule" location.
 - See pic in part 6 for what it should look like.
4. Save the file and exit the editor.
5. Now run `sudo nano passenger.conf` to edit the passenger conf file.
6. Add the "`<IfModule mod_passenger.c>`" that was output and comment out any other informaiton in the file.
 - Both your "passenger.load" file and a "passenger.conf" file should look like this: ![Modified files](https://dev-to-uploads.s3.amazonaws.com/i/dxv6e7j89c0qo6f97qnb.jpg)
 - Note: Because my files were previously created on the first module install attempt I only needed to modify them. If for some reason the files are not already created you will probably need to create the `/etc/apache2/mods-available/passenger.load` file and add the "LoadModule" directive that passenger-install-apache2-module outputs and create the `/etc/apache2/mods-available/passenger.conf` file and paste the "PassengerRoot" and other Passenger options that were output by the module.
7. Enable the module again by running `sudo a2enmod passenger`.
 - If this doesn't work hopefully you typed in something wrong and it's an easy fix. If not try checking out the [Passenger TroubleShooting](https://www.phusionpassenger.com/docs/advanced_guides/troubleshooting/) pages or the [logs](https://www.phusionpassenger.com/library/admin/apache/log_file/#location-of-the-log-file) and see what it's telling you.
8. Now navigate into the "sites-enabled" folder with `cd /etc/apache2/sites-enabled`.
9. Run `sudo nano etcpasswdapi.conf` to edit the file.
10. Add the Passender specific configuration for "Development" and the "PassengerRuby".
 - For example, ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v76ese393fef9xxyli9c.png)
8. Restart Apache with `sudo apache2ctl restart`
9. Check that it worked by navigating to the site that your API is at on your client computer.
 - Because my API doesn't have an `index.html` landing page I needed to create a temporary `index.html` file in the "public" folder to ensure general connectivity. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xoebgs761r19bfqqur5s.png)


{[Back to the Table Of Contents](#TOC)}












# <a name="S3">Step 3: Accessing Rails Routes</a>
At this point you will probably be able to see the index page (as shown in the previous step) but if you want to access specific API routes to process data, you need to add in some [CORS](https://dev.to/caffiendkitten/building-a-home-test-server-27h1#CORS) specifications to allow access to secure content. See, although the frontend and backend live on the same server they don't have the same origin. ![](https://javascript.info/article/url/url-object.svg) For this to work the Apache headers module will be needed. 

The [Apache headers module](https://httpd.apache.org/docs/current/mod/mod_headers.html) is one that will allow for control over the responses from the server. They can, and should, be set specific to each application on it.

 In my case I am using HTTPS for both the frontend and backend of my application so I need to set up both `conf` files.

1. To enable the headers module run `sudo a2enmod headers`.
2. Navigate to the Apache2 folder with `cd /etc/apache2/sites-enabled`.
3. Edit the frontends "conf" file with `sudo nano etcpasswdapp.conf`.
4. With the editor open add `Header set Access-Control-Allow_Origin "*"` to the `<Directory>` section.
5. Save and close the file.
6. Now open the 'conf' file for the backend with `sudo nano etcpasswdapi.conf`
7. With the editor open add `Header set Access-Control-Allow_Origin "http://etcpasswdapp.com"` to the `<Directory>` section.
8. Save and close the file.
9. Restart apache with `systemctl restart apache2`


If all works you should be able to see your frontend ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5ejbfkafyyygzvmwi2cm.png)
and use it to interact with your API ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/znxgo5drl176v70bz4f9.png)

{[Back to the Table Of Contents](#TOC)}






DONE!!!!
![Glad that is over](https://media.giphy.com/media/eHDYhKUFlSuoIUrVY4/giphy.gif)
This last part was not that easy for me and took a few days to figure out and configure. Between all the spelling errors of mine and the lack of documentation for Ubuntu 20.04 I had to piece together things to make it all work for my set up. Feel free to ask questions and I  hope I can help.

Now that that's done it's time to harden the server, test the application I built, and fix things.




<hr>

Happy Hacking
![Happy Hacking ^_^](https://media.giphy.com/media/l3vRmVv5P01I5NDAA/giphy.gif)

### Resources:
<a name="L1">1.</a> https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/apache/oss/bionic/install_passenger.html
<a name="L2">2.</a> https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/standalone/install/oss/focal.html
<a name="L3">3.</a> https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/apache/install/oss/focal.html
<a name="L4">4.</a> https://www.phusionpassenger.com/library/install/apache/working_with_the_apache_config_file.html
<a name="L5">5.</a> https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/apache/oss/rubygems_norvm/install_passenger.html#step-2:-run-the-passenger-apache-module-installer
<a name="L6">6.</a> https://medium.com/@thorntonbrenden/rails-and-the-legendary-master-key-15c8be7799f1
<a name="L7">7.</a> https://linuxize.com/post/how-to-install-ruby-on-ubuntu-20-04/
<a name="L8">8.</a> https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/apache/working_with_the_apache_config_file.html
<a name="L9">9.</a> https://www.phusionpassenger.com/docs/tutorials/deploy_to_production/deploying_your_app/oss/aws/ruby/apache/#rails_configure-database-yml-and-secrets-yml
<a name="L10">10.</a> https://www.phusionpassenger.com/library/walkthroughs/start/ruby.html
<a name="L11">11.</a> https://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-ruby-on-rails-application-on-ubuntu-18-04
<a name="L12">12.</a> https://www.digitalocean.com/community/tutorials/how-to-set-up-a-ruby-on-rails-project-with-a-react-frontend
<a name="L13">13.</a> https://www.phusionpassenger.com/library/config/apache/intro.html


##### <figcaption>Please Note: that I am still learning and if something that I have stated is incorrect please let me know. I would love to learn more about what I may not understand fully.</figcaption>