LoginSignup
21
9

More than 5 years have passed since last update.

VaporのプロジェクトをFlockを使ってEC2にデプロイする

Last updated at Posted at 2019-09-18

はじめに

Server Side Swift の開発をより実践的にできればと思い、CapistranoライクなServer Side Swiftフレームワークのデプロイツールである Flock を使ってみました。
今回の投稿では Vapor で作ったプロジェクトのEC2サーバーへのデプロイを行います。

- Flock

  • Capistoranoライクな Server Side Swift のフレームワークデプロイツール
  • Vapor, Kitura, Zewo, Perfect に対応しているよう

- Vapor

  • Server Side Swift の Webフレームワーク

手順概要

  1. Vaporプロジェクトの作成
  2. EC2でUbuntuサーバー(デプロイ先サーバー)の作成
  3. デプロイ先サーバーでのNginxの設定
  4. デプロイ先サーバーでのsupervisorの設定
  5. デプロイ先サーバーでのその他デプロイに必要な設定
  6. ローカルmacでFlockの設定
  7. いざ、デプロイ

環境

  • 開発機
    • macOS Sierra 10.12.1
    • Swift 3.0.1
    • Vapor 1.1.13
    • Flock 0.1.1
  • デプロイ先サーバー
    • Ubuntu 16.04
    • Swift 3.0.1

1. Vaporプロジェクトの作成

▶︎ ローカルmacにプロジェクト作成

まずは開発用のローカルmacにVaporプロジェクトを作成します。
今回は、デプロイ部分を中心に見ていくので、VaporのインストールやVapor自体の説明は割愛します。
(詳しくはVaporのDocumentをご覧ください。)

$ vapor new vaporDeploySample

vaporDeploySample部分はプロジェクト名になるので、適宜変更してください。

▶︎ GithubへPush

今回は特にプロジェクトはいじらずにそのままデプロイ設定の手順に進むので、一旦GithubにPushしておきます。

GithubのリポジトリのURLを後述のデプロイ設定の際に使用します。

2. EC2でUbuntuサーバー(デプロイ先サーバー)の作成

EC2でなくても大丈夫なのですが、VagrantでUbuntu14.04で試した時に何かと面倒があったので、EC2でUbuntu16.04を立てて行いました。

▶︎ EC2の作成

AMIの選択

Ubuntu Server 16.04 ...のものを選択して作成を進めていきます。

スクリーンショット 2016-12-11 14.14.09.png

キーペア

キーペアを新しく作成する場合は、

  • 作成したキーをダウンロード
  • 手元のmacの~/.sshの下に配置
  • chmod 600 ~/.ssh/your-key-pair.pem

としておきます。

セキュリティグループの設定

セキュリティ設定では、今回の作業ではSSHとHTTPが開いていれば十分です。
下の画像では送信元が「任意の場所」になっていますが、手元で試すだけなら「マイIP」を選択して自分のIPからのみアクセスできる状態にしておいた方が安心です。

スクリーンショット 2016-12-11 14.17.59.png

3. デプロイ先サーバーでのNginxの設定

▶︎ サーバーへ接続

先ほど作成したサーバーへ接続して、作業を行います。

$ ssh -i ~/.ssh/your-key-pair.pem ubuntu@publicdns

publicdns部分は作成したインスタンスのパブリックDNSが入ります。

▶︎ Nginxインストール

サーバーへログインできたら、Nginxをインストールします。

$ sudo apt-get update
$ sudo apt-get install nginx

▶︎ Nginxの設定

/etc/nginx/sites-enabled/defaultファイルに以下のような設定を書きます。

/etc/nginx/sites-enabled/default
server {
    server_name localhost;
    listen 80;

    try_files $uri @proxy;

    location @proxy {
        proxy_pass http://127.0.0.1:8080;
        proxy_pass_header Server;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_header Server;
        proxy_connect_timeout 3s;
        proxy_read_timeout 10s;
    }
}
$ sudo service nginx restart

これで、localhostの80番ポートへのアクセスをVaporのプロジェクトがデフォルトでバインドする8080番へ流してくれます。

4. デプロイ先サーバーでのsupervisorの設定

続いて、プロセス監視のため、supervisorをインストールします。

$ sudo apt-get update
$ sudo apt-get install supervisor

こちらの設定は後述のFlockを使って行うので、まずはインストールまででokです。

(※このタイミングでインストールしていなくても、後述のflock toolsタスクの中でインストールされそうですが、試行錯誤していたので確認できていません。もし良ければお試しください。)

5. デプロイ先サーバーでのその他デプロイに必要な設定

▶︎ /var/www ディレクトリの作成

Flockでは /var/www ディレクトリにデプロイされるので、もしない場合は作っておきます。
(EC2ではデフォルトであるようなので、この工程は不要です。)
また、後述の設定でデプロイ先のディレクトリの変更も可能です。

$ sudo mkdir /var/www
# ↑本来はwwwユーザーとか作ってそのユーザーのみにwww以下を触らせるのが良さそうですが、一旦そのまま動かします

▶︎ rootでのログイン

あまり気が進まないですが、Flockを使っていてrootでのログインができないと困ることが多々でてきたので、rootでのログイン設定をします。
(適切なパーミッションを持ったユーザーを使ったり、Flock自体の改善でrootでのログインは回避できるかもしれませんが、一旦簡単のためにそうします。)

$ mv /root/.ssh/authorized_keys /root/.ssh/authorized_keys_bak
$ cp -f /home/ubuntu/.ssh/authorized_keys /root/.ssh/authorized_keys

authorized_keysをコピーすることで、手元のmacからキーペアを使ってrootユーザーでログインすることができます。

6. ローカルmacでFlockの設定

それでは、いよいよデプロイをする準備をしていきます。

▶︎ Flockのインストール

$ brew install jakeheis/repo/flock

▶︎ プロジェクト直下でFlockの初期化

$ cd /path/to/your/project
$ flock --init
Creating Flock files...
Creating .flock
Creating config/deploy
Writing .flock/Package.swift
Writing config/deploy/FlockDependencies.json
Writing Flockfile
Linking Flockfile to .flock/main.swift
Creating environment `always`
Writing config/deploy/Always.swift
Linking config/deploy/Always.swift to .flock/Always.swift
Creating environment `production`
Writing config/deploy/Production.swift
Linking config/deploy/Production.swift to .flock/Production.swift
Creating environment `staging`
Writing config/deploy/Staging.swift
Linking config/deploy/Staging.swift to .flock/Staging.swift
Successfully created Flock files
Downloading and building dependencies...
Successfully downloaded dependencies
Adding Flock files to .gitignore...
Successfully added Flock files to .gitignore
Successfully initialized Flock!

IN ORDER FOR FLOCK TO WORK CORRECTLY
Follow these steps:
1. Update the required fields in config/deploy/Always.swift
2. Add your production and staging servers to config/deploy/Production.swift and config/deploy/Staging.swift respectively

To add Flock dependencies:
1. Add the url and version of the dependency to config/deploy/FlockDependencies.json
2. in your Flockfile, at the top of the file import your dependency and below add `Flock.use(Dependency)`

これによって、FlockfileというファイルとConfig/下にdeployというディレクトリが作られ、deployに必要な設定を行うことができるようになります。

▶︎ Config/deploy/FlockDependencies.json の編集

Vaporデプロイ用にVaporFlockを使うので、追記します。

以下のファイルが編集後のものです。
https://github.com/jakeheis/VaporFlockのブロックを追加しています。

Config/deploy/FlockDependencies.json
{
   "dependencies" : [ 
       {   
           "url" : "https://github.com/jakeheis/Flock",
           "version": "0.1.1"
       },  
       {   
           "url" : "https://github.com/jakeheis/VaporFlock",
           "version": "0.0.4"
       }   
   ]   
}

ここでの依存関係のバージョンが食い違うとエラーが起こるので、注意が必要です。

例えば、VaporFlockのversionを0.0.3とすると、VaporFlock v0.0.3 はソース上(Package.swift)では Flock v0.0.x に依存しているため、このファイルの記述と食い違いが起こります。

▶︎ Flockfile の編集

以下が編集後のFlockfile

Flockfile
import Flock
import VaporFlock

Flock.use(Flock.Tools)
Flock.use(Flock.Deploy)
Flock.use(Flock.Vapor)

Flock.configure(.always, with: Always()) // Located at config/deploy/Always.swift
Flock.configure(.env("production"), with: Production()) // Located at config/deploy/Production.swift
Flock.configure(.env("staging"), with: Staging()) // Located at config/deploy/Staging.swift

Flock.run()

▶︎ Config/deploy/Always.swift の編集

環境に依らない、共通の設定をこのファイルに書きます。

  • Config.projectName
  • Config.executableName
  • Config.repoURL
  • Config.swiftVersion

の値をプロジェクトに応じて変更します。

Config/deploy/Always.swift
import Flock

class Always: Configuration {
    func configure() {
        // UPDATE THESE VALUES BEFORE USING FLOCK:
        Config.projectName = "vaporDeploySample"
        Config.executableName = "App" // Same as Config.projectName unless your project is divided into modules
        Config.repoURL = "https://github.com/taji-taji/vaporDeploySample"

        // Optional config:
        // Config.deployDirectory = "/var/www"
        Config.swiftVersion = "https://swift.org/builds/swift-3.0.1-release/ubuntu1510/swift-3.0.1-RELEASE/swift-3.0.1-RELEASE-ubuntu15.10.tar.gz"
    }   
}

Config.executableNameは、プロジェクトがビルドされて生成される実行ファイルの名前を指すようで、コメントには Same as Config.projectName unless your project is divided into modules と書いていますが、私が行った際には実行ファイルはAppになっていたので、そのようにしました。
フレームワークによって違うのかもしれません。
(これが分からなくてしばらくハマりました、、)

▶︎ Ubuntuサーバーに接続するsshキーを環境変数に設定

Flockのコード内からUbuntuサーバー作成時に作成したキーペアを環境変数を通して読み込むので、環境変数への設定を行います。

$ export FLOCK_KEY=$HOME/.ssh/your-key-pair.pem

Config/deploy/Production.swift の編集

ここで、デプロイ先のIPやそこに接続するためのsshキー(先ほど設定したもの)の設定を行います。

Config/deploy/Production.swift
import Flock
import Foundation

class Production: Configuration {
    func configure() {
        if let key = ProcessInfo.processInfo.environment["FLOCK_KEY"] {
            Config.SSHAuthMethod = .key(key)
        }   
        // using vagrant private network ip
        Servers.add(ip: "ec2-ip", user: "root", roles: [.app, .db, .web])
    }   
}

"ec2-ip"部分にはEC2のパブリックIPを設定します。
ProcessInfo.processInfo.environment["FLOCK_KEY"]の部分で先ほど環境変数に設定したキーペアの場所が読まれています。

注意点

デフォルトでFoundationフレームワークがimportされていなかったため、ProcessInfoの使用で怒られました。
環境変数を読むときはimport Foundationを追記しましょう。

デプロイ

▶︎ flock tools コマンド

初回はflock toolsコマンドでデプロイ先のサーバーにSwiftと依存するライブラリをインストールします。

$ flock tools

このflock toolsコマンドでは、

  1. デプロイ先サーバーにデプロイに必要な依存ライブラリをインストール
  2. デプロイ先サーバーにswiftenvのインストールおよびswiftenvによるSwiftをインストール

という2つのフェーズに分かれており、それぞれ、

flock tools:dependencies
flock tools:swift

というコマンドで別々に実行することが可能です。

▶︎ flock deployコマンド

いよいよデプロイです。

$ flock deploy

こちらも

  1. gitからソースコードをcloneする
  2. コードをbuildする
  3. デプロイした最新のコードがあるディレクトリにリンクを貼る

というフェーズに分かれており、それぞれ下のコマンドで別々に実行できます。

flock deploy:git
flock deploy:build
flock deploy:link

補足:デプロイ先ディレクトリについて

/var/www/vaporDeploySample/
├── current -> /var/www/vaporDeploySample/releases/20161211181262
└── releases
    ├── 20161211181234
    └── 20161211181262

Capistranoを使っている方には馴染みがあるかと思いますが、デプロイ先のディレクトリ構成には currentreleases というディレクトリがあります。
デプロイしたコードをreleasesに貯めていき、最新のものをcurrentにリンクするようにしています。
もしデプロイしたものに異常があってもリンクを差し替えるだけでデプロイ前の状態に戻すことが可能です。


以上でデプロイの手順は完了となります。
お疲れ様でした。

一度上記の設定を行えば、以降はflock deployコマンドのみでデプロイができます。

今回作成したサンプルアプリケーション

今回作成したサンプルアプリケーションです。
Vaporプロジェクトはデフォルトのテンプレートのまま、「Flockfile」および「Config/deploy」以下のdeploy用の設定ファイルが追加された形になります。

感想

普段、Capistranoを使っている方にとっては学習コストも低く、とても便利に使えるツールだと思います。
一方で、Server Side Swift そのものがそうであるように、このような付随するツールもまだ安定していないものが多かったりします。
なので、こういったツールへの貢献ができるようにというのが今後の自分の課題です。

Server Side でも Swift を楽しめるといいですね!:grinning:

最後に

とりあえず、今回は「デプロイをする」ことのみに絞ってみましたが、これから、もう少し機能的にどんなことができるかなどを深掘りしてみたいと思います。

21
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
9