TIS ENGINEER NOTE

ITエンジニアのためのキャリア向上ノウハウブログ

プログラミング

sinatraでミニマムなWebサービスを公開してみるよ【sinatra + nginx + puma + Capistrano】

更新日:

sinatraとはRubuで作成されたWebフレームワークです。かなりシンプルな構成ですので、Ruby自体の勉強用としてはRailsより向いているかも知れません。

今回はRailsを使うまでもない小規模なWebサイトを作成する機会がありましたので、sinatra + Puma + nginxの構成で公開し、Capistranoでデプロイできるようになるまでを作業をまとめてみました。

Rubyのインストール・公開サーバーの準備等は完了している前提で進めていきます。

作業PCでの作業

まずは開発用のローカル環境下での作業から。

今回はポートフォリオサイトを作るので、アプリケーション名はportfolioです。

まずはディレクトリを作成し、そのディレクトリに移動。その後bundle initでGemfileを生成します。

mkdir portfolio
cd portfolio/
bundle init

そして作成されるGemfileの最後にsinatraを追加します。

gem 'sinatra'

保存したら、以下のコマンドでvendor/bundle配下にgemをインストールします。ローカル環境は極力汚さない。

bundle install --path vendor/bundle

これでローカル開発環境自体は完成となります。

動作確認のために、Rubyファイルを作成し、修正します。

touch main.rb
require 'sinatra'

get '/' do
    "<h1>This is Portfolio<h1>"
end

ひとまずはRubyファイルから直接表示します。最終的にはviewファイルを読み込むように修正します。

そしてsinatraを起動。

bundle exec ruby main.rb

起動されたらブラウザからhttp://localhost:4567/にアクセスしてみましょう。

上記のようにmain.rbに記載した内容が表示されていればOKです。

Gitの初期設定

なにはともあれソースを書いたらバージョン管理。Gitの初期設定を行います。

以降のコマンドは基本的にアプリケーションディレクトリ(今回であればportfolio)配下で実行します。

使用しているPCで初めてGitを使用する場合

git config --global user.name "Your Name"
git config --global user.email your.email@example.com

git init

アプリケーションディレクトリでgit initします。これでportfolio配下がGitによってバージョン管理される対象となります。

git init

gitignoreを設定

git上にアップしたくないファイルを設定します。今回はvendor/bundle配下とbundlerのconfigはアップしないようにします。

touch .gitignore
# Ignore bundler config.
/.bundle

# Ignore bundler gems.
vendor/bundle

/log/*
/tmp/*

add & commit

git add -A
git commit -m "Initialize repository"

リモート設定

Gitリポジトリサービスの登録は済ませておいてください。

Bitbucket,GitHubなりお好みのサービスをどうぞ。

登録しているサービスでリポジトリを作成するとリモート設定のコマンドが表示されますので、そちらを実行しましょう。基本的には以下のような形です。

git remote add origin https://github.com/stobita/portfolio.git
git push -u origin master

以上でバージョン管理の設定は完了です。長丁場ですね。コーヒーでも飲んで一休みしましょう。

サーバーへの配布準備

サーバーに公開するだけなら、作成したファイルをサーバーにコピーしてWebサーバーの準備をするだけですが、それだけだと変更を加えた時に、いちいちコピーし直さなければなりません。それって結構手間になります。

プログラマーは怠惰であれの言葉に則り、Capistranoというツールを使って、自動デプロイを実現しておきます。

Gitリポジトリにpushしたソースを公開サーバーにコピーするという処理をCapistranoにやってもらう流れです。

Webサービスの構築などについては下記サイトを参考に進めました。Railsでの例ではありますが、ディレクトリの設定などは同様に進めることが可能です。Rails、DBの設定の部分などは今回スキップしてしまって構いません。

http://qiita.com/eiei19/items/7c08d358c82cb538def0

まずはGemfileに下記を追加し、bundle installしましょう。

# puma
gem 'puma'

# for deploy
group :development do
  gem 'capistrano',         require: false
  gem 'capistrano-bundler', require: false
  gem 'capistrano3-puma',   require: false
  gem 'capistrano-rbenv',   require: false
end

インストールが完了したら、下記コマンドでCapistranoの初期設定を行いましょう。

bundle exec cap install

コマンドを実行して生成されたCapfileに以下のコマンドを追加しましょう。

require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/puma'

install_plugin Capistrano::Puma

更にconfig/deployファイルも生成されているので、こちらに配布用のコードを書いていきます。

# config valid only for current version of Capistrano
lock "3.9.0"

server '[IPアドレス]', roles: [:app, :web, :db], primary: true
set :repo_url,        'git@github.com:stobita/XXX.git'
set :application,     'portfolio'
set :user,            'deploy_user'
set :ssh_options,     {
  forward_agent: true,
  user: fetch(:user),
  keys: %w(~/.ssh/id_rsa)
}
set :puma_threads,    [4, 16]
set :puma_workers,    0
set :pty,             true
set :use_sudo,        false
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/var/www/#{fetch(:application)}"
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log,  "#{release_path}/log/puma.access.log"
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true
set :rbenv_type, :user
set :rbenv_ruby, '2.4.1'
set :linked_dirs, fetch(:linked_dirs, []).push(
  'log',
  'tmp/pids',
  'tmp/cache',
  'tmp/sockets',
  'vendor/bundle',
  'public/system',
  'public/uploads'
)
namespace :puma do
  desc 'Create Directories for Puma Pids and Socket'
  task :make_dirs do
    on roles(:app) do
      execute "mkdir #{shared_path}/tmp/sockets -p"
      execute "mkdir #{shared_path}/tmp/pids -p"
    end
  end
  before :start, :make_dirs
end

namespace :deploy do
  desc "Make sure local git is in sync with remote."
  task :check_revision do
    on roles(:app) do
      unless `git rev-parse HEAD` == `git rev-parse origin/master`
        puts "WARNING: HEAD is not the same as origin/master"
        puts "Run `git push` to sync changes."
        exit
      end
    end
  end

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      before 'deploy:restart', 'puma:start'
      invoke 'deploy'
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end

  before :starting,     :check_revision
  after  :finishing,    :cleanup
end

あとは今回アプリケーションをPumaで動かすので、config.ruをアプリケーションディレクトリに作成しておきます。

touch config.ru
require './main'
run Sinatra::Application

ここまで完了したら下記コマンドで配布実行。

bundle exec cap production deploy:initial

権限によってはwww配下にディレクトリが作れないよ!と怒られることもあるので、その場合はサーバーにアクセスし、直接作成しておきましょう。

エラーが発生したり、修正を行った時はリポジトリへのpushを忘れないようにしましょう。特にGemfileを修正した時などは、pushしてから再リトライしないと反映されないので要注意!

正常に終了したら、デプロイは完了です。

nginxの設定

これでアプリケーションが動く仕組みはできましたが、実際にインターネットからアクセスされた時にアプリケーションに繋げる仕組みができていませんので、nginxの設定を行います。nginxのインストールや基本的な設定は上で紹介した記事を参考にしてみてください。

今回は設定ファイルの例だけ書いておきます。

pstream portfolio {
    server unix:/var/www/portfolio/shared/tmp/sockets/portfolio-puma.sock fail_timeout=0;
}

server {
    listen 80;
    server_name xxxxx.com
    root /var/www/portfolio/current/public;

    location / {
        proxy_pass http://portfolio;
        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;
}

設定を記述し終わったら、nginxを起動、または再起動します。

sudo systemctl start nginx
sudo systemctl restart nginx

これで実際にサーバーのドメインまたはIPにアクセスすれば作成したsinatraアプリケーションが表示されます。

これからモリモリカスタマイズしていこうと思います。

閲覧いただき、ありがとうございました。

よく読まれている記事

エンジニア入門

2018/8/19

本気でRubyを学びたい人のためのエンジニアスクール『ポテパンキャンプ』

こんにちは、フリーエンジニアのてぃすです。 エンジニアといえば今や最も少ない投資で高収入を望め、更には週3勤務やリモートワークなどの柔軟な働き方も目指せる夢のある職業です。 ここ最近は営業職や事務職から、将来性を考えてエンジニアに転身するといういう人もかなり増えてきています。 特にRubyプログラマーは日本における絶大な需要とリモート案件の豊富さから、特に人気のあるポジションとなっています。エンジニアとして働いているが、職場環境に不満を抱いていたり、今扱っている技術が今後通用するか不安に感じ、Ruby・W ...

続きを読む

エンジニア独立

2019/5/29

エンジニアが会社員のままでいるのはヤバいなと感じた理由

現在会社員エンジニアからフリーランスエンジニアへの転身を目論んで活動中のてぃすです。 今回は僕が感じた会社に雇われた状態でエンジニアを続けることのデメリットについて語っていきます。 エンジニアは多くの現場で幅広い技術を習得するべきである 会社員としてエンジニアを続けることの最大のマイナスポイント。 それはキャリアのコントロールしにくいという点です。 エンジニアが携わるITの世界というのは、技術の流行り廃りが他の業界に比べて断トツで早いんですよね。 そうなるとその技術で生計を立てていくエンジニアという存在は ...

続きを読む

エンジニア入門

2019/5/19

RubyでWebエンジニアを目指せるプログラミングスクール厳選4校

どうもフリーランスエンジニアのてぃすです。 エンジニアを目指すにあたり、もっとも確実性の高い手段がプログラミングスクールを活用するというもの。 そんなプログラミングスクールの中でJavaを扱っているプログラミングスクールが特に多いです。 しかしJavaを使ってエンジニアとしてのキャリアを開始する場合、SES企業などのスキルアップの保証のない企業に入ることになる確率が結構高い。 また官公庁や大企業での採用が多いことからスーツ勤務などといったエンジニア軽視の風潮が強い現場も多かったりします。 そうなるとカジュ ...

続きを読む

エンジニア独立

2019/4/28

収入を上げたいWebエンジニアが学習するべき技術

どうも、フリーランスエンジニアのてぃすです。 エンジニアの収入は技術に比例して上がるわけではない。というのはこのブログでよく言っていることです。 しかし技術と収入の因果関係はもちろん0ではありません。 そこで今回はITエンジニアとして働いていく上で収入アップに繋がる可能性の高い技術をピックアップして紹介していきます。 今やっている仕事で収入に限界を感じている 新しい技術を学びたいけど何を学ぶのが効率がいいのか知りたい というエンジニアは要チェックです。 技術によって収入が上がる要因 まず収入が上がる技術と ...

続きを読む

エンジニア独立

2018/8/12

ITエンジニアがスーツ勤務を強要する現場を避けるべき理由

こんにちは、フリーエンジニアのてぃすです。 プラグラマやインフラ担当などと言ったITエンジニアとしての一般的な働き方として、客先に常駐して業務を行うというものがあります。 そんなとき、現場を選ぶ判断基準の一つとして服装が自由か否かというものが上げられます。 僕は決まって私服勤務可能な現場を選ぶようにしています。それはなぜか。エンジニアをスーツ勤務させる客先にロクなところがないから。 これまでスーツ勤務・私服勤務の現場を経験した上で、エンジニアがスーツを勤務を強要する現場を避けるべき理由を書いて行こうと思い ...

続きを読む

-プログラミング
-,

Copyright© TIS ENGINEER NOTE , 2023 All Rights Reserved Powered by AFFINGER5.