Adding Ruby on Rails to a Server
Tags: codenewbie, todayilearned, sideprojects, security
Published: 2021-01-06 19:32:38

This series is so close to being done but not quite.
![the end is near!](https://media.giphy.com/media/eXo5eC1tK7cas/giphy.gif)
If you've kept up till now your application's frontend is (hopefully) functional on your home server with Heroku hosting its backend API. It's now time to migrate the Rails API and its Database into the server.

At this point there are, again, a few options you could do: 
1. Set up the "pgAdmin", PostgreSQL Tools, and interact with the admin and development platform in a GUI.
2. Create a fresh Rails API for the application to interface with the PostgreSQL database on the server.
3. Rewrite the application have the frontend and backend together with something like a Ruby on Rails base and React functionality to display the public "views" folder of the Ruby application.
4. Create a PHP interface for the frontend to interact with the ProgreSQL database.

Because I already have a Ruby on Rails API built I'm going to download that repository and configure a private endpoint for the frontend to interact with it.
If you need a refresher the difference between an API and a database, refer to my [API =/= Database](https://dev.to/caffiendkitten/api-database-4le6) post.


# <a name="TOC">Table Of Contents</a>
Step 1: [Installing Ruby and Rails](#S1)
Step 2: [Downloading and Configuring the API Repository](#S2)
Step 3: [Adding the Backend Endpoints](#S3)
Step 4: [Adding SSL](#S4)
Step 5: [Adding in an Application Server](#S5)
Step 6: [Configure database.yml and secrets.yml](#S6)









# <a name="S1">Step 1: Installing Ruby and Rails</a>
Before I add the API repository onto the server both [Ruby](https://www.ruby-lang.org/en/) and [Rails](https://rubyonrails.org/) need to be installed. For this I'm going to follow the [Digital Ocean tutorial](https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntu-18-04) for installing Ruby on Rails with [rbenv](https://github.com/rbenv/rbenv) on my Ubuntu server, with a few changes for my specific system that I will list as needed.

__Note:__ For this step I did find that if you run the commands as the "Root" user you will run into some issues; so I recommend using the `sudo` command as needed.

1. First I will run `sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev`. For this command I will need to change the `libgdbm5` (that's for Ubuntu 18) to `libgdbm6` (that's for Ubuntu 20).
 - `autoconf` is " a tool for producing shell scripts that automatically configure software source code packages to adapt to many kinds of Posix-like systems" <sup>[19](#L19)</sup>
 - `bison` "is a general-purpose parser generator that converts an annotated context-free grammar into a deterministic LR or generalized LR (GLR) parser employing LALR(1), IELR(1) or canonical LR(1) parser tables." <sup>[20](#L20)</sup>
 - `build-essential` is "a meta-package that includes the GNU compiler collection, GNU debugger, and other development libraries and tools required for compiling software." <sup>[21](#L21)</sup>
 - `libssl-dev` is the OpenSSL project's implementation of the SSL/TLS cryptographic protocols for secure communication over the Internet. <sup>[22](#L22)</sup>
 - `libyaml-dev` "is a C library for parsing and emitting data in YAML 1.1, a human-readable data serialization format." <sup>[23](#L23)</sup>
 - `libreadline6-dev` is the GNU readline and history library that "aids in the consistency of user interface across discrete programs that need to provide a command line interface." <sup>[24](#L24)</sup>
 - `zlib1g-dev` "is a library implementing the deflate compression method found in gzip and PKZIP." <sup>[25](#L25)</sup>
 - `libncurses5-dev` is the "ncurses library routines are a terminal-independent method of updating character screens with reasonable optimization." <sup>[26](#L26)</sup>
 - `libffi-dev` is "a foreign function interface... that allows code written in one language to call code written in another language." <sup>[27](#L27)</sup>
 - `libgdbm6` and `libgdbm-dev` are both a version of the GNU dbm ('gdbm') "library of database functions that use extendible hashing and works similarly to the standard UNIX 'dbm' functions." <sup>[28](#L28)</sup>
 - The `-dev` part speaks to the development libraries, header files, and manpages for the packages.
2. Clone the "rbenv" repository into the "~/.rbenv" folder with `git clone https://github.com/rbenv/rbenv.git ~/.rbenv`.
3. Add "rbenv" to your command line `$PATH` with the following commands![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/x09nop0ojhglalk4ojo8.png)
 - To get this command to permanently take hold I needed Root privileges and not just run the commands with `sudo`. Without Root privileges my system would not product any output for the next step. I am not sure if this will effect things with other imaginary users but it was the only way I could get the `source ~/.bashrc` command to work.
4. Test the configuration with `type rbenv` which should produce the output of ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2tagb388bygbcifs34gg.png)
5. Clone the rbenv ruby build part of the repository into the `~/.rbenv/plugins/ruby-build` folder with `git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build` 
6. Install the version of Ruby that you need with `rbenv install 2.6.6`. 
 - I needed Ruby Version 2.6.6 but you can install any one you need. To see available versions to install run `rbenv install -l`.
 - At this point I actually had a weird thing happen where I think I installed Ruby Version 2.7 and I ended up needing uninstall ruby with the command `sudo apt purge ruby` as "Root" and then I was able to install the proper version of Ruby with the rbenv.
7. At this point you can run `gem install bundler`  to manage the gem dependencies for your application.

To reiterate... If you installed rbenv as Root you might have trouble. Rbenv seems to not like being installed as root so only run with "sudo" if it insists.

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









# <a name="S2">Step 2: Downloading and Configuring the API Repository</a>
Depending on if you are downloading an already built API from GitHub, downloading one from your client computer over SSH, or creating a new API will depend on how you do this step. 
Because I already have a Rails API built for my application on GitHub I will go through the same steps here to download the repository as I did with my [React frontend](https://dev.to/caffiendkitten/adding-react-to-a-server-nm6#S2) into a folder named "backend" in the application's main folder.

1. Navigate into the folder your application will live in with `cd /var/www/etcpasswdapp`
2. Same as with the React frontend, run `sudo git clone https://github.com/yourGitHubProject.git backend` to clone the backend repository into a new folder named "backend", in the "etcpasswdapp" folder.
 -  Now if you `cd backend` into the "backend" folder you just created and run `git status` you can see that the folder is linked up to GitHub for some great version control and backup ability of your application.
3. If `Gemfile.Lock` is there delete it with `sudo rm Gemfile.Lock`.
4. Make a copy of the `.env.sample` file, or whatever you named it, with `cp .env.sample .env`.
 - You can delete the `.env.sample` file once you have a copy of it.
5. Edit the file with `sudo nano .env`, add in any keys needed for your application and save the file.
 - For example `HASH_KEY=SomeSuperSecretRandonString` would be added to the `.env` file.
6. Now navigate into the `config` folder with `cd config`.
7. Here you will run `sudo nano master.key` to either edit an existing "key" file or create one.
8. Add a key to the file that was previously used.
 - This is only for if you are working with a previously created repository and is specific to it's creation.
9. Back out into the main "backend" folder and read the `.gitignore` file with `less .gitignore` to make sure that both the `.env` and the `master.key` files are listed so they won't be uploaded to GitHub accidently. ![Sample GitIgnore File](https://dev-to-uploads.s3.amazonaws.com/i/pf9aqui7s0e0m8m2yyaw.png)
 - Mine were in there already but good to double check. Don't want any private folders escaping into the Internets.
10. Now you should be able to run `bundle install` to install any needed gem dependencies.
 - You night need to "bundle" things again later so, your call if you care to do this now and/or later.


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








# <a name="S3">Step 3: Adding the Backend Endpoints</a>
Now that Ruby and Rails are both installed on the server it's time to configure the endpoint for the backend API. This step will be similar to the [process for the frontend](https://dev.to/caffiendkitten/a-is-for-apache-3iem#S2-1) but you will need to make a few naming modifications.

1. Navigate to the Apache2 "sites-available" folder with `cd /etc/apache2/sites-available`.
2. Make a copy of the applications "conf" file with a different name by running `sudo cp etcpasswdapp.conf etcpasswdapi.conf`.
 - I recommend making a copy of the frontend "conf" file because we will a lot of the info in it for the backend to be running over HTTPS.
3. Run `sudo nano etcpasswdapi.conf` to open up the new file in the nano editor.
 - You will be editing a few things so be sure to leave it open for a bit.
4. With the editor open change the first `<VirtualHost *:443>` section's "DocumenRoot" to the location of the backends' "public" folder.
 - For example, mine will be `/var/www/etcpasswdapp/backend/public`
5. With the editor open change the "ServerName" and "ServerAlias" to the API's nameing scheme.
 - For example, my "ServerName" will be `api.etcpasswdapp.com` and my "ServerAlias" will be `*.etcpassedapp.com`.
6. In the second `<VirtualHost *:80>` section use the same naming scheme and change its "DocumentRoot, "ServerName", and "Redirect" accordingly. ![example conf file](https://dev-to-uploads.s3.amazonaws.com/i/7cbze418g1bog49dyve7.png)
7. Now save the file and exit the editor.

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










# <a name="S4">Step 4: Adding SSL</a>
Now that there is an end point you will need to follow the [same process as the frontend](https://dev.to/caffiendkitten/adding-ssl-to-a-server-28p9#S2) and [configure a new SSL certificate](https://dev.to/caffiendkitten/adding-ssl-to-a-server-28p9#S1) with different names for the endpoint to work for testing.

1. Create the SSL certificate for the backend with `sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache_cert2.key -out /etc/ssl/certs/apache_cert2.crt`. It will prompt you for some basic information about your site. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/163v1it8f7g651xr1igc.png)
 - Note: that `req` is like "request" with a 'Q' and not a 'G' and you can name the cert anything. I chose the "apache_cert2" because it was convenient for me to type for this project.
2. Now that the certs are generated you need to navigate into the Apache2 "sites-available" folder, if not there already, with `cd /etc/apache2/sites-available`.
3. Open the "conf" file for the backend to edit it with `sudo nano etcpasswdapi.conf`.
4. Add the SSL configuration into the `<VirtualHost *:443>` section below the  "DocumentRoot" somewhere. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t5h3rd1lt17zm1nkvpx3.png)
5. Once you have edited the locations of the certs in the first `<VirtualHost *:443>` section save the file and exit nano.

You may still get betting the pesky error from the browsers when trying to access the page but you should be able to go into the "Advanced" button and allow the "unsafe site". ![Site Error](https://dev-to-uploads.s3.amazonaws.com/i/oekv8ko00o223cfrwkri.png)
 
{[Back to the Table Of Contents](#TOC)}

 
 
 
 
 
 
 
 
 


# <a name="S5">Step 5: Configure database.yml and secrets.yml</a>
Now that the API is on the server, it has an endpoint, and SSL is enabled you now need to configure the applications `database.yml` and `secrets.yml`/`secrets.yml.enc` (depending on your set up) files for the database to work. "As of Rails 5.2, config/secrets.yml, config/secrets.yml.enc and SECRET_BASE_KEY are no longer being used to store encrypted keys. From now on, you are to use these files instead: config/credentials.yml.enc and config/master.key." <sup>[11](#L11)</sup>

1. Navigate to the API's `database.yml` file with `cd /var/www/etcpasswdapp/backend/config` 
2. Run `sudo nano master.key` or `sudo nano secrects.yml` to create the file, or edit an existing file, and add in your secret to interact with the database in it.
 - In my case I needed to add in a _secret string_ that I'd previously set up into my `master.key` file and made a `secrets.yml` file and put the same key that my `master.key` file had in it, just to be safe if it's needed. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xlbie9txfflfsz3dvyds.png)
 - Also, this the key not a variable. Just add in the string on the first line all by itself save it. It is case sensitive.
3. Now run `sudo nano database.yml` and configure it according to [Passenger's Walkthrough step 2.3](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/apache/oss/bionic/deploy_app.html#rails_configure-database-yml-and-secrets-yml). It will look something like this when done. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qzori55r2gexn0kblpyu.png)
 - This will depend a lot on your own set up so take a min with it. (We will be using Passenger in the next section so this will do well.)
 - You might need to delete your database configuration if you had set one up previously because it will interfere with Rails' configuration of its database based on the information in the `database.yml` file.
4. Now that the database configuration is set up be sure to edit the `.gitignore` file again and add in any missing files you don't want on the internet. 
 - For example, I added the `database.yml` file because of the password for my development configuration as so. ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mslc5uug59m3ncum6h81.png)
5. If everything works you will hopefully be able to now run `rake db:create` to finish setting up the database.
6. Hopefully you were able to create the database ok. If so you can now run `rake db:migrate` and `rake db:seed` to populate your database with the seed data for testing.
 - If you run into an error try running `rake db:reset` or try deleting the database in the `psql` command line interface and recreating it.
7. You should now be able to check the configuration of the database within the `psql` command line interface and interact with the database. <sup>[18](#L18)</sup>
 

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













Sorry but...![](https://media.giphy.com/media/ItjO4QS1WeAjATXrid/giphy-downsized.gif)
There are a few more things to do as I need to set up [application server](https://dev.to/caffiendkitten/building-a-home-test-server-27h1#WebServerVsHTTPServer) and go through server hardening.



<hr>

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

### Resources:
<a name="L1">1.</a> https://www.postgresql.org/docs/12/tutorial-createdb.html
<a name="L2">2.</a> https://www.postgresqltutorial.com/postgresql-data-types/
<a name="L3">3.</a> https://www.postgresqltutorial.com/postgresql-create-table/
<a name="L4">4.</a> https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntu-18-04
<a name="L5">5.</a> https://devhints.io/rbenv
<a name="L6">6.</a> https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/apache/oss/bionic/install_passenger.html
<a name="L7">7.</a> https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/standalone/install/oss/focal.html
<a name="L8">8.</a> https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/apache/install/oss/focal.html
<a name="L9">9.</a> https://www.phusionpassenger.com/library/install/apache/working_with_the_apache_config_file.html
<a name="L10">10.</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="L11">11.</a> https://medium.com/@thorntonbrenden/rails-and-the-legendary-master-key-15c8be7799f1
<a name="L12">12.</a> https://linuxize.com/post/how-to-install-ruby-on-ubuntu-20-04/
<a name="L13">13.</a> https://www.phusionpassenger.com/docs/advanced_guides/install_and_upgrade/apache/working_with_the_apache_config_file.html
<a name="L14">14.</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="L15">15.</a> https://www.phusionpassenger.com/library/walkthroughs/start/ruby.html
<a name="L16">16.</a> https://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-ruby-on-rails-application-on-ubuntu-18-04
<a name="L17">17.</a> https://www.digitalocean.com/community/tutorials/how-to-set-up-a-ruby-on-rails-project-with-a-react-frontend
<a name="L18">18.</a> http://postgresguide.com/utilities/psql.html
<a name="L19">19.</a> https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#Introduction
<a name="L20">20.</a> https://www.gnu.org/software/bison/manual/bison.html#Introduction
<a name="L21">21.</a> https://linuxize.com/post/how-to-install-gcc-on-ubuntu-20-04/#:~:text=The%20default%20Ubuntu%20repositories%20contain,tools%20required%20for%20compiling%20software.
<a name="L22">22.</a> https://packages.debian.org/jessie/libssl-dev
<a name="L23">23.</a> https://packages.debian.org/buster/libyaml-dev
<a name="L24">24.</a> https://packages.debian.org/buster/libreadline-dev
<a name="L25">25.</a> https://packages.debian.org/buster/zlib1g
<a name="L26">26.</a> https://packages.debian.org/buster/libncurses5
<a name="L27">27.</a> https://packages.debian.org/buster/libffi-dev
<a name="L28">28.</a> https://packages.debian.org/buster/libgdbm6







##### <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>