Skip to content

Instantly share code, notes, and snippets.

@revans
Last active October 27, 2020 18:16
Show Gist options
  • Save revans/8202040 to your computer and use it in GitHub Desktop.
Save revans/8202040 to your computer and use it in GitHub Desktop.
AWS User Script for getting a server ready for Ruby, Rails, Sinatra, or Rack apps.
#!/usr/bin/env bash
#
# Author: Robert R Evans
#
# Description: AWS Ubuntu 13 Ruby Setup Script
#
# This script will setup a ubuntu box for Ruby, Rails, Sinatra, and/or Rack
# development/staging/production usage. It also installs Nodejs, Nginx, Git,
# Rbenv, and PostgreSQL adapters for using RDMS PostgreSQL. It assumes that
# git-deploy will be used, in place of the traditional capistrano deployments.
#
# Rational: Why not just use Puppet, Chef, or the many other systems?
#
# I'm tired of keeping up with everyone's projects, fixing things when they break
# them; having to update/change my code/process because 3rd party software either
# doesn't support their own API or decides to change it all together when it is
# working great for me. Lastly, I'm just tired of learning and relearning tools
# that will soon be out of fashion only to have to learn some new tool that will
# have a limited lifespan.
#
# That's not say the above tools are as I described, but rather I'd just like to
# stick to what I know and what works. I can then spend my time on things that I
# really want to do instead of on tools that I don't care about.
#
# I'm over the "shiny new toy" syndrome. I just want to get things done.
set -ex
# These can be changed to represent the GIT user. Ideally, the 'name' would be changed to the
# name of the application that is deployed to the machine it sits on.
name="Ubuntu Deploy User"
email="[email protected]"
app="rubyapp"
# log everything that runs in this script
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
# mark the start time of the script
echo BEGIN
date '+%Y-%m-%d %H:%M:%S'
# update & upgrade
sudo apt-get update -y
sudo apt-get upgrade -y
# install base packages
sudo apt-get install -y libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev build-essential libpq-dev zlib1g-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libyaml-dev curl libxml2 lobxslt1-dev
# add some repositories that have more up-to-date packages
sudo add-apt-repository ppa:nginx/stable
sudo add-apt-repository ppa:git-core/ppa
sudo add-apt-repository ppa:chris-lea/node.js
# update
sudo apt-get update -y
# install nginx, git, and nodejs
sudo apt-get install -y nginx git-core nodejs
# install rbenv in the /home/ubuntu directory
cd
git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL
# install rbenv's ruby-build for easy new ruby installs
git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
# install some rbenv plugins
git clone https://github.com/sstephenson/rbenv-vars.git ~/.rbenv/plugins/rbenv-vars
git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash
exec $SHELL
# install the latest ruby version
rbenv install 2.1.0
# set the latest ruby version globally
rbenv global 2.1.0
# set gems to not install any documentation
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
# update to the latest RubyGem release
gem update --system
# install bundler
gem install bundler --pre
# configure git
git config --global color.ui true
git config --global user.name $name
git config --global user.email $email
# create ssh keys for git deploys
ssh-keygen -t rsa -C $email
# add some aliases to the ubuntu user
echo 'alias c="clear"' >> ~/.bashrc
# Setup the Nginx Conf file
sudo tee /etc/nginx/sites-available/nginx_puma.conf <<EOTL
upstream puma_server {
server unix:<%= puma_sock %> fail_timeout=0;
}
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;
server {
listen 80 default deferred;
# listen 443 ssl;
# server_name example.com;
# client_max_body_size 8m; # Default is set to 1k for protection against buffer overflows
# keepalive_timeout 70; # default is set to 5 5 for performance
# ssl_certificate <%= shared_path + "/certs/server.crt" %>;
# ssl_certificate_key <%= shared_path + "/certs/server.key" %>;
server_name $app.com;
root /home/ubuntu/$app/public;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_request_headers on;
proxy_redirect off;
# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://puma_server;
break;
}
}
location ~* ^/assets/ {
root <%= current_path %>/public;
gzip_static on;
expires 1y;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "":
break;
}
# this rewrites all the requests to the maintenance.html
# page if it exists in the doc root. This is for capistrano's
# disable web task
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html last;
break;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root <%= current_path %>/public;
}
error_page 404 /404.html;
location = /404.html {
root <%= current_path %>/public;
}
}
EOTL
sudo ln -sf /etc/nginx/sites-available/nginx_puma.conf /etc/nginx/sites-enabled/nginx_puma.conf
sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old
sudo tee /etc/nginx/nginx.conf <<EOTL
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 1024;
# multi_accept on;
}
http {
##
# Basic Settings
##
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# do not display version numbers in the browser
server_tokens off;
# server_names_hash_bucket_size 64;
server_name_in_redirect off;
# control buffer overflow attacks
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
# control timeouts, improve performance, and cut clients
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
types_hash_max_size 2048;
##
# Logging Settings
##
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log notice;
##
# Gzip Settings
##
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_buffers 4 16k;
gzip_min_length 0;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
#
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
#
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
EOTL
sudo service nginx restart
# mark the end time of the script
date '+%Y-%m-%d %H:%M:%S'
echo END
@tkambler
Copy link

tkambler commented Apr 4, 2016

"I'm over the "shiny new toy" syndrome. I just want to get things done."

👍

@dpawluk
Copy link

dpawluk commented Jun 29, 2016

https://gist.github.com/revans/8202040#file-user_script-sh-L47

looks like lob should be lib. P sure, but I've been more embarrassingly wrong before

@8parth
Copy link

8parth commented Jul 30, 2018

https://gist.github.com/revans/8202040#file-user_script-sh-L65

exec $SHELL command fails script by throwing super user permission errors. Is there any workaround for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment