NOTE: We can now use an AMI for this. Once you enter the launch wizard make sure that "My AMIs" and "Shared with me" is selected and then search for the term "Rotati". Select the Rotati Staging AMI and continue with the wizard. This AMI will have everything you need to run the staging application (so no need to run though the process below if everything is working on the AMI already!)
- Launch the AWS instance in Singapore region (unless the client specially stated to launch in a different region). For Staging use t2.micro. For Production use t2.micro (and higher).
- Configure the settings as per the wizard. Ensure to enable termination protection. Most other settings can remain unchanged.
- Create a new security group for the server giving it a meaningful name (e.g. the name of the project). Open only the ports that are required which are generally HTTP, HTTPS and SSH. Ensure that SSH is only accessible from your current IP.
- Verify the settings and launch the instance.
- For Production servers only, create a new Elastic IP and accociate that to the new instance by right clicking on the new IP address and selecting 'Associate Address'
- SSH into the server using the following command. Ensure that you have allowed your IP address in the SSH settings for the servers security group!
chmod 600 keypair.pem
ssh -i keypair.pem [email protected]
- Add you and your admins SSH key(s) to the .ssh/authorized_keys file on the server. Log out of the server and then SSH back in using:
ssh [email protected]
Everything from now on assumes that you have already SSH into your ubuntu server, and you are currently on the remote server machine.
If your server memory (RAM) is low (2GB or less), it is a good practice to create another swap memory in case your memory is full.
sudo apt-get -y update
sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=2048
sudo /sbin/mkswap /var/swap.1
sudo /sbin/swapon /var/swap.1
then add this line of code in to your /etc/fstab
:
/var/swap.1 swap swap defaults 0 0'
Rebooting your server
sudo reboot
sudo apt-get -y install curl git-core python-software-properties htop git-core curl build-essential zlib1g-dev libssl-dev libreadline6-dev libcurl4-openssl-dev
The above command will install git
, curl
, htop
and some other required softwares.
Installing imagemagick
sudo apt-get install libmagickwand-dev imagemagick
Installing Postfix if your app need to send out email:
sudo apt-get -y install telnet postfix
Just select all the default options.
sudo apt-get install nodejs
sudo apt install nodejs-legacy
sudo apt-get -y install postgresql libpq-dev
It's a good practice to add password to the postgres
user:
Login to database console with user postgres
sudo -u postgres psql
In the database console, type the following command:
\password
Input your password, then type \q
to exit the console.
We would suggest to create a database user rather using postgres user, usually the user you will be using in your rails app
sudo -u postgres psql
In your database console, type the following command:
Note: replace the any_user
to the username you want to created, and change the secret
to any password to you want to use.
create user any_user with password 'secret';
ALTER USER any_user CREATEDB;
In the PRODUCTION environment we use RDS for the database so we DON'T need to install PostgresSQL on the EC2 application server instance, however we DO need the psql client tools which can be installed by running apt-get install postgresql-client
and sudo apt-get install libpq-dev
.
To install Postgres using RDS just follow the wizard in the RDS console and use the following settings:
- DB Engine Version: Latest Version of Postgres
- DB Instance Class: db.t2.micro
- Multi-AZ Deployment: NO (unless there is budget)
- Storage Type: General Purpose (SSD)
- Allocated Storage*: 20GB
- DB Instance Identifier: (Use the project name)
- Availability Zone: (Use the same as the EC2 Instance that will connect to this database)
- Backup Retention Period: 7 days
- Auto Minor Version Upgrade: Yes
- Public Accessibility: No
- Enable Deletion Protection: Yes
Other settings, use your judgment!
NOTE You must make sure that security group in RDS accept your EC2 private IP (Not public IP).
Type the following command then enter the password for the new user (change 'deployer' to the username you desire):
sudo adduser deployer --ingroup admin
Login to the deployer
user:
sudo su deployer
With deployer user, now we could start installing RVM, Ruby, Rails and Passenger
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s stable
Reload .bash_profile
by running: source ~/.bash_profile
.
rvm install 2.2.0
rvm use --default 2.2.0
rvm rubygems current
Command above will install ruby version 2.2.0 and uses it as a default, and use rubygems.
_Note_ If you're using Ruby 2.2.3 . Run the below command, otherwise skip it!*
sudo apt-get install libgmp3-dev
sudo apt-get install libpcre3 libpcre3-dev
# Install PGP key and add HTTPS support for APT
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates
# Add APT repository
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
# Install Passenger + Nginx
sudo apt-get install -y nginx-extras passenger
Edit /etc/nginx/nginx.conf and uncomment include /etc/nginx/passenger.conf;. For example, you may see this:
include /etc/nginx/passenger.conf;
Type the following command to start server
sudo service nginx start
You should be able to visit your website through your server public IP via any browser now. The Nginx Welcome page should appear.
Once nginx installed, all the configuration files should be located in /etc/nginx/sites-available
Open /etc/nginx/sites-available/default
with sudo privilege using your favorite editor, in our case, we use Vim:
sudo vim /etc/nginx/sites-available/default
Replace the file content with the following content:
server {
listen 80;
server_name default _;
location / {
root /var/www/test_app/current/public;
passenger_enabled on;
rails_env staging;
}
location ~ \.(js|css|png|jpg|jpeg|gif|ico|html)$ {
root /var/www/test_app/current/public;
expires max;
gzip_static on;
add_header Cache-Control public;
break;
}
location ^~ /assets/ {
root /var/www/test_app/current/public;
gzip_static on;
expires max;
add_header Cache-Control public;
}
# Drop requests to non-rails requests
location ~ \.(aspx|php|jsp|cgi|asp) {
return 410;
}
}
Replace the test_app
with your project directory name.
You need to make sure that you clone your project and put it under /var/www/test_app
You need to create a /var/www/
directory
sudo mkdir /var/www
Then change the ownership of the directory to deployer
cd /var
sudo chown -R deployer:admin www
Clone your rails app into the /www
directory.
cd www
git clone [email protected]:rotati/test_app.git
Create a restart.txt
file in test_app
tmp
folder.
cd /test_app
mkdir tmp
touch tmp/restart.txt
Restart your Nginx Service (NOTE: this also restarts Passenger)
sudo service nginx restart
To reload Nginx configuration you may need to run:
sudo service nginx reload
Visit your public IP or domain and you should see your app is live.
If your project requires, setup upstart files:
rvmsudo foreman export upstart /etc/init -a appname -u deployer --env=/var/.env --log=/var/log
cat /etc/init/...
Note that in the /var/.env file you need to put all the environment variables for the application so they are picked up by the upstart script. For example some environment variables might be:
export RACK_ENV=production
export RAILS_ENV=production
etc...
View production logs:
sudo tail /var/log/upstart/appname-web-1.log
Start appname service (other commands e.g. stop follow a similar pattern)
sudo service appname start
Suggested Services for an Application
Main services are:
- Error management handling using Errbit
- User profiling and statistics monitoring using Google Analytics
- Application performance monitoring using NewRelic
- Server performance monitoring using CloudWatch
Go to init.d folder (place where linux execute when server started)
cd /etc/init.d
Create service file to run on boot
sudo vim service-name.sh
In service-name.sh file, place code we want to make it run Eg: ``` #!/bin/bash
# this script starts the nginx process attached to passenger
sudo /opt/nginx/sbin/nginx
```
Make the file executable
sudo chmod +x /etc/init.d/service-name.sh
You can test if the file run correctly by running the script
sudo /etc/init.d/service-name.sh
Update it to make changes
sudo update-rc.d service-name.sh defaults