Forked from aquaflamingo/1-Nginx-Unicorn-Rails-DO-Ubuntu-16.md
Created
June 22, 2020 17:18
-
-
Save tsipiniuk/deb4b53a3195a3de550465b52dba71e8 to your computer and use it in GitHub Desktop.
Revisions
-
aquaflamingo revised this gist
Aug 26, 2018 . 5 changed files with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -296,14 +296,14 @@ If test fails allow firewall to port 3000 temporarily[1](https://www.digitalocea Add `gem 'unicorn'` to `Gemfile` and `bundle`. Edit `config/unicorn.rb` paste [**Appendix B: config/unicorn.rb**](config-unicorn.md) Save and add logging to Rails App: ``` $ mkdir -p shared/pids shared/sockets shared/log ``` Edit and add unicorn init script from [**Appendix C: Unicorn Init Script**:](UNICORN-INIT.md) ``` $ sudo nano /etc/init.d/unicorn_APPNAME ``` @@ -336,7 +336,7 @@ If run fails and `systemctl` reveals little, ensure that you `rbenv`'s installat $ sudo apt-get install nginx ``` Add NGINX reverse proxy config with block in [**Appendix D: NGINX Reverse Proxy**](NGINX-REV-PROXY.md) ``` $ sudo vi /etc/nginx/sites-available/default @@ -353,7 +353,7 @@ Restart NGINX ---- ## 🙀 8. Complete Make sure you have all passwords: [**Appendix A: Inside Password Manager**](INSIDE-PW-MANAGER.md) All System Operational. File renamed without changes.File renamed without changes.File renamed without changes.File renamed without changes. -
aquaflamingo revised this gist
Aug 17, 2018 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -100,6 +100,8 @@ Test Login: `ssh deploy@server_ip` # Enter: y $ sudo ufw status # Status: active $ sudo ufw allow 80/tcp $ sudo ufw allow 443/tcp ``` ---- ## 💎 3. Install Ruby on Rails & rbenv [[Guide]](https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntu-16-04) @@ -290,7 +292,7 @@ If test fails allow firewall to port 3000 temporarily[1](https://www.digitalocea ``` ---- ## 🦄 6. Installing Unicorn [[Guide]](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04#configure-unicorn) OR [[Passenger Phusion Guide]](https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/digital_ocean/nginx/oss/xenial/deploy_app.html) Add `gem 'unicorn'` to `Gemfile` and `bundle`. -
aquaflamingo renamed this gist
Aug 15, 2018 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
aquaflamingo revised this gist
Aug 15, 2018 . 4 changed files with 132 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ ``` Digital_Ocean: root_pass: deploy_pass: Postgres: appname: appname_password: Rails_Credentials RAILS_MASTER_KEY: AWS: access_key_id: secret_access_key: ``` This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ ``` # Configures Unicorn with the location of your application, and the location of its socket, logs, and PIDs. # set path to application app_dir = File.expand_path("../..", __FILE__) shared_dir = "#{app_dir}/shared" working_directory app_dir # Set unicorn options worker_processes 2 preload_app true timeout 30 # Set up socket location listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64 # Logging stderr_path "#{shared_dir}/log/unicorn.stderr.log" stdout_path "#{shared_dir}/log/unicorn.stdout.log" # Set master PID location pid "#{shared_dir}/pids/unicorn.pid" ``` This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ #!/bin/sh ### BEGIN INIT INFO # Provides: unicorn # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the unicorn app server # Description: starts unicorn using start-stop-daemon ### END INIT INFO set -e USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>" # app settings USER="deploy" APP_NAME="appname" APP_ROOT="/home/$USER/$APP_NAME" ENV="production" # environment settings PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH" CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D" PID="$APP_ROOT/shared/pids/unicorn.pid" OLD_PID="$PID.oldbin" # make sure the app exists cd $APP_ROOT || exit 1 sig () { test -s "$PID" && kill -$1 `cat $PID` } oldsig () { test -s $OLD_PID && kill -$1 `cat $OLD_PID` } case $1 in start) sig 0 && echo >&2 "Already running" && exit 0 echo "Starting $APP_NAME" su - $USER -c "$CMD" ;; stop) echo "Stopping $APP_NAME" sig QUIT && exit 0 echo >&2 "Not running" ;; force-stop) echo "Force stopping $APP_NAME" sig TERM && exit 0 echo >&2 "Not running" ;; restart|reload|upgrade) sig USR2 && echo "reloaded $APP_NAME" && exit 0 echo >&2 "Couldn't reload, starting '$CMD' instead" $CMD ;; rotate) sig USR1 && echo rotated logs OK && exit 0 echo >&2 "Couldn't rotate logs" && exit 1 ;; *) echo >&2 $USAGE exit 1 ;; esac This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,24 @@ upstream app { # Path to Unicorn SOCK file, as defined previously server unix:/home/deploy/<APPNAME>/shared/sockets/unicorn.sock fail_timeout=0; } server { listen 80; server_name localhost; root /home/deploy/<APPNAME>/public; try_files $uri/index.html $uri @app; location @app { proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } error_page 500 502 503 504 /500.html; client_max_body_size 4G; keepalive_timeout 10; } -
aquaflamingo created this gist
Aug 15, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,505 @@ # 🚂 Deploy Ubuntu 16.04 Rails Server on Digital Ocean using Unicorn, Nginx, PostgreSQL, active_storage, Amazon S3. Combined summary of all guides. ## 💧 1. Basic Droplet/SSH Set Up ### Create Droplet: Ubuntu 16.04 Your `root` password is e-mailed to you. ### Create SSH Key [[Guide]](https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/create-with-openssh/) Enter `.ssh` directory: ```$ cd ~/.ssh``` Generate Key: ```$ ssh-keygen``` Save DigitalOcean (`DO`) key with created `key-password` ```$ ~/.ssh/id_do_mac``` *Save `key-password` in password manager* ### Add Public Key To Digital Ocean [[Guide]](https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/to-account/) Copy public key to clip board: ```$ cat ~/.ssh/id_do_mac.pub | pbcopy``` Add SSH Key to Digital Ocean Account Name `MacOS`: `Home>Security>Add SSH Key` ---- ## 💻 2. Initial Server Setup [[Guide]](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04) ### Create Non Root User ``` $ ssh root@your_server_ip $ adduser deploy ``` Create `deploy-password` add to password manager. Give `deploy` root privileges: ``` $ usermod -aG sudo deploy ``` ### Add Public Key Auth to Your Server Use already created **local** SSH key and add to the server. ``` ## Local Machine $ cat ~/.ssh/id_do_mac.pub | pbcopy ``` Paste SSH Key to Deployed User's Authorized Keys ``` ## Server $ su - deploy $ mkdir ~/.ssh $ chmod 700 ~/.ssh $ nano ~/.ssh/authorized_keys # Paste Key ``` Change permissions back: ``` $ chmod 600 ~/.ssh/authorized_keys ``` ### Remove Password Auth ``` $ sudo nano /etc/ssh/sshd_config ``` Find: `PasswordAuthentication` change to ``` PasswordAuthentication no ``` Reload: `sudo systemctl reload sshd` Test Login: `ssh deploy@server_ip` ### Add Firewall ``` $ sudo ufw allow OpenSSH $ sudo ufw enable # Enter: y $ sudo ufw status # Status: active ``` ---- ## 💎 3. Install Ruby on Rails & rbenv [[Guide]](https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntu-16-04) Login as `deploy` (i.e. `ssh deploy@server_ip` or `su - deploy`) ### Add dependencies, rbenv & rails Install `nodejs` dependence for Asset Pipeline ``` $ curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh $ sudo bash nodesource_setup.sh $ sudo apt-get install nodejs $ nodejs -v # Output: v8.10.0 ``` Ruby + `rbenv` dependencies` ``` $ sudo apt-get update $ sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev ``` Add `rbenv` & `ruby-build` ``` $ git clone https://github.com/rbenv/rbenv.git ~/.rbenv $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc $ echo 'eval "$(rbenv init -)"' >> ~/.bashrc $ source ~/.bashrc $ type rbenv # output: ... $ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build ``` Install `ruby 2.5.0` & gems ``` $ rbenv install 2.5.0 $ rbenv global 2.5.0 $ echo "gem: --no-document" > ~/.gemrc # No Docs $ gem install bundler $ gem install rails # rails -v: Rails 5.2 ``` ---- ## 🐘 4. Add PostgreSQL Add dependencies: ``` $ sudo apt-get install postgresql postgresql-contrib libpq-dev ``` Create user (this will be same user in your `database.yml`, `username` field for the `production` tag): ``` $ sudo -u postgres createuser -s <APPNAME> ``` Set password for `APPNAME` ``` $ sudo -u postgres psql $ \password <APPNAME> ``` **Save Postgres User and Password in password manager** ## 🔑 5. Rails Encrypted Credentials & Active Storage (for Database Keys, S3 and Secrets) **ON SERVER**: Install [`rbenv-vars`](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04#install-rbenv-vars-plugin) for environment variable management. ``` $ cd ~/.rbenv/plugins $ git clone https://github.com/sstephenson/rbenv-vars.git ``` **ON LOCAL TERMINAL/PROJECT**: Generate `config/master.key` for [Rails Encrypted Credentials](https://www.engineyard.com/blog/rails-encrypted-credentials-on-rails-5.2) by editing credentials ``` bin/rails credentials:edit # generates credentials.yml.enc ``` ### Adding Postgres Database Add the postgres production database password to `credentials.yml.enc`. ``` ## credentials.ymc.enc database: production_password: <PASSWORD-CREATED-IN-STEP-3-ABOVE> ``` Edit `database.yml` ``` ## database.yml production: adapter: postgresql encoding: unicode database: <APPNAME_production> host: localhost pool: 5 username: <APPNAME-CREATED-IN-STEP-3-ABOVE> password: <%= Rails.application.credentials.dig(:database, :production_password) %> ## ... ``` Copy the `RAILS_MASTER_KEY` from `config/master.key`. *Save RAILS_MASTER_KEY in Password Manager* ``` $ cat config/master.key # cfda33e2583... ``` **ON SERVER:** Edit `rbenv-vars` to add the `RAILS_MASTER_KEY` (because Encrypted Credentials looks for `ENV['RAILS_MASTER_KEY']`) ``` $ nano .rbenv-vars ``` ``` ## .rbenv-vars RAILS_MASTER_KEY=<MASTER-KEY-HERE> ``` ### Adding Amazon S3 1. [Create S3 Bucket](https://docs.aws.amazon.com/quickstarts/latest/s3backup/step-1-create-bucket.html) 2. [Create an S3 Access Key](https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) - *Save ACCESS_KEY_ID and SECRET_ACCESS_KEY in Password Manager* **ON LOCAL TERMINAL/PROJECT**: Add S3 Keys to Encrypted Credentials ``` bin/rails credentials:edit ``` ``` # credentials.yml.enc aws: access_key_id: <s3_key_id> secret_access_key: <s3_secret> ``` Edit `storage.yml` ``` ## storage.yml amazon: service: S3 access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> region: us-east-1 bucket: <%= Rails.application.credentials.dig(:aws, :bucket) %> ## ... ``` Add, Commit & Push Changes to Remote Repo ``` $ git add -A $ git commit -m "Add and encrypt deploy credentials" $ git push origin master ``` **ON SERVER**: Pull Git Repo with Rails app: ``` $ git clone https://github.com/username/repo $ bundle install # Installed ``` ### Build Database, and Production Environment ``` $ RAILS_ENV=production rake db:create $ RAILS_ENV=production rake db:migrate $ RAILS_ENV=production rake assets:precompile $ RAILS_ENV=production rails server --binding=server_public_IP # test http://server_ip:3000 ``` If test fails allow firewall to port 3000 temporarily[1](https://www.digitalocean.com/community/questions/rails-binding-to-ip-3000-is-giving-me-connection-timeout?comment=72308): ``` $ sudo ufw allow 3000 ``` ---- ## 🦄 6. Installing Unicorn [[Guide]](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04#configure-unicorn) Add `gem 'unicorn'` to `Gemfile` and `bundle`. Edit `config/unicorn.rb` paste [**Appendix B: config/unicorn.rb**](B-config-unicorn.md) Save and add logging to Rails App: ``` $ mkdir -p shared/pids shared/sockets shared/log ``` Edit and add unicorn init script from [**Appendix C: Unicorn Init Script**:](C-UNICORN-INIT.md) ``` $ sudo nano /etc/init.d/unicorn_APPNAME ``` **Ensure You Change APPNAME in Init Script to actual app** Update permissions for init script: ``` $ sudo chmod 755 /etc/init.d/unicorn_appname $ sudo update-rc.d unicorn_appname defaults ``` Run via: ``` sudo service unicorn_appname start ``` If run fails and `systemctl` reveals little, ensure that you `rbenv`'s installation added the `RBENV_ROOT` properly. Otherwise edit your `deploy` `~/.profile` file and [add](https://stackoverflow.com/questions/31971806/unicorn-service-upstart-script-throws-su-bundle-command-not-found) the following and resart the service. ``` $ export RBENV_ROOT=/home/YOUR_USER_PATH/.rbenv $ export PATH=$RBENV_ROOT/shims:$RBENV_ROOT/bin:$PATH ``` ---- ## 🎡 7. Installing NGINX Reverse Proxy [[Guide]](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04#install-and-configure-nginx) ``` $ sudo apt-get install nginx ``` Add NGINX reverse proxy config with block in [**Appendix D: NGINX Reverse Proxy**](D-NGINX-REV-PROXY.md) ``` $ sudo vi /etc/nginx/sites-available/default ``` **Ensure You Change APPNAME in NGINX to actual app** Restart NGINX ``` $ sudo service nginx restart # try: http://server_public_IP ``` ---- ## 🙀 8. Complete Make sure you have all passwords: [**Appendix A: Inside Password Manager**](A-INSIDE-PW-MANAGER.md) All System Operational. <img src="https://i.imgur.com/wIevyxb.jpg" height="300px"/> ## Appendix: ### A. Inside Password Manager: ``` Digital_Ocean: root_pass: deploy_pass: Postgres: appname: appname_password: Rails_Credentials RAILS_MASTER_KEY: AWS: access_key_id: secret_access_key: ``` ### B. [config/unicorn.rb](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04) ``` # Configures Unicorn with the location of your application, and the location of its socket, logs, and PIDs. # set path to application app_dir = File.expand_path("../..", __FILE__) shared_dir = "#{app_dir}/shared" working_directory app_dir # Set unicorn options worker_processes 2 preload_app true timeout 30 # Set up socket location listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64 # Logging stderr_path "#{shared_dir}/log/unicorn.stderr.log" stdout_path "#{shared_dir}/log/unicorn.stdout.log" # Set master PID location pid "#{shared_dir}/pids/unicorn.pid" ``` ### C. [Unicorn Init Script](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04) **Replace APPNAME** ``` #!/bin/sh ### BEGIN INIT INFO # Provides: unicorn # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts the unicorn app server # Description: starts unicorn using start-stop-daemon ### END INIT INFO set -e USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>" # app settings USER="deploy" APP_NAME="appname" APP_ROOT="/home/$USER/$APP_NAME" ENV="production" # environment settings PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH" CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D" PID="$APP_ROOT/shared/pids/unicorn.pid" OLD_PID="$PID.oldbin" # make sure the app exists cd $APP_ROOT || exit 1 sig () { test -s "$PID" && kill -$1 `cat $PID` } oldsig () { test -s $OLD_PID && kill -$1 `cat $OLD_PID` } case $1 in start) sig 0 && echo >&2 "Already running" && exit 0 echo "Starting $APP_NAME" su - $USER -c "$CMD" ;; stop) echo "Stopping $APP_NAME" sig QUIT && exit 0 echo >&2 "Not running" ;; force-stop) echo "Force stopping $APP_NAME" sig TERM && exit 0 echo >&2 "Not running" ;; restart|reload|upgrade) sig USR2 && echo "reloaded $APP_NAME" && exit 0 echo >&2 "Couldn't reload, starting '$CMD' instead" $CMD ;; rotate) sig USR1 && echo rotated logs OK && exit 0 echo >&2 "Couldn't rotate logs" && exit 1 ;; *) echo >&2 $USAGE exit 1 ;; esac ``` ### D. [NGINX Reverse Proxy](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-unicorn-and-nginx-on-ubuntu-14-04) **Replace APPNAME** ``` upstream app { # Path to Unicorn SOCK file, as defined previously server unix:/home/deploy/<APPNAME>/shared/sockets/unicorn.sock fail_timeout=0; } server { listen 80; server_name localhost; root /home/deploy/<APPNAME>/public; try_files $uri/index.html $uri @app; location @app { proxy_pass http://app; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } error_page 500 502 503 504 /500.html; client_max_body_size 4G; keepalive_timeout 10; } ```