RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

PostgreSQL10についてまとめてみた

こんにちは。開発エンジニアのd_shr(id:d_shr)です。
前回はNode.jsのことを書いていましたが、今回はPostgreSQLのことを書きます。

前回投稿した記事 tech-blog.rakus.co.jp

はじめに

最近、PostgreSQLについて調査する機会がありました。
主にPostgreSQL9系やPostgreSQL10の変更点を調査しましたが、その中でも最新のPostgreSQL10について書きます。
PostgreSQL10はリリースから半年以上経っており今更ですが、新機能や変更点で気になったものをピックアップしてまとめようと思います。

PostgreSQL10 変更点

  • ロジカルレプリケーション
  • 宣言的テーブルパーティショニング
  • 改善された並列問い合わせ
  • その他

ロジカルレプリケーション

PostgreSQL10でPublish/Subscribeによる論理レプリケーションが実装されました。

PostgreSQL9.6までのレプリケーション

マスタからスタンバイにトランザクションログを転送し適用することでデータの複製を実現していました。
対象はデータベース全体。完全な複製でスタンバイには物理的な変更はできないものでした。

PostgreSQL10 ロジカルレプリケーション

レプリケーション先に対して変更したレプリケーション情報を送付できるようになります。
トランザクションログを「テーブルに〇〇を挿入しました」のように論理的な変更内容として転送することができます。
データベース全体をレプリケーションするのではなく、特定のテーブルの情報やinsertだけをレプリケーションすることが可能です。
レプリケーション情報のやりとりにPublish/Subscribe(出版/購読型)モデルのメッセージ送信を用いています。
複製元でPUBLICATIONを作成し、複製先でSUBSCRIPTIONを作成することでテーブルの同期とレプリケーションが行われます。
INSERT, DELETE, UPDATEには対応していますが、CREATE TABLEなどには対応してません。

所感

柔軟にレプリケーションできるようになったという印象を受けました。
学生の頃にPub/Subモデルのメッセージングを用いた開発をしていたので興味深い内容でした。

パーティショニング

パーティショニングとは、巨大な親テーブルを複数の子テーブルに分割することです。
今までパーティショニングの手順がめんどうだったのですが、CREATE TABLE文でパーティショニングが構築可能になりました。

これまでのパーティショニング

  1. 親テーブルを作成
  2. 親テーブルを継承する子テーブルを作成
  3. CHECK制約を作成
  4. 親テーブルにINSERTトリガを作成 ......

宣言的テーブルパーティショニング

CREATE TABLE文で構築可能 1. 親テーブル作成 PARTITION BY構文 2. 子テーブル作成 PARTITION OF構文

所感

PostgreSQL9.5でもUPSERTが追加されていましたが便利な構文が増えたということで使ってみようかなと思いました。

パラレルクエリの強化

パラレルクエリとは、PostgreSQL9.6で追加された大きなテーブルに対するクエリを並列問合せで実行することです。
パフォーマンスの向上が期待できます。
PostgreSQL9.6で追加されたパラレルクエリ(並列問い合せ)がPostgreSQL10で強化されています。

PostgreSQL9.6で対応していたもの

  • シーケンシャルスキャン
  • 結合(nested loop, hash join)
  • 集約

PostgreSQL10で追加されたもの

  • インデックススキャン(B-tree, index only scan, bitmap heap scan)
  • 結合(merge)
  • 非相関副問合せ

所感

パラレルクエリ自体、バージョンアップで既存のシステムに取り入れるのは難しいのかなという印象を持っています。
これからも並列化はどんどん強化されそうな流れなので、パフォーマンス向上に繋がるなら考慮するべきなのかなと思います。
正しく理解しておきたい機能だと思いました。

その他

PostgreSQL10.3の修正で
他ユーザからの search_path を使った「トロイの木馬」攻撃を防御する PostgreSQL とアプリケーションの設定方法がドキュメントに記載されました。
pg_dump や他のクライアントプログラムで安全でない search_path 設定の使用が回避されました。 *1

PostgreSQLのpublicスキーマの仕様によるもので、悪意あるユーザがpublicスキーマに不正な挙動を行うユーザー関数を仕込んでおくことができます。
他のユーザがその不正なユーザ関数を一般のユーザ関数として実行させることで攻撃(漏えい、改ざんなど)ができてしまう問題がありました。
pg_dump」「pg_upgrade」「vacuumdb」などの管理者ユーザで実行されるアプリケーション関してはsearch_pathからpublicスキーマが取り除かれました。

PostgreSQLの仕様が原因になっていることなのでpublicスキーマの設定を見直す必要もあり 既存のシステムで問題に直面しそうな場合は、運用面のことを考えるのなかなか辛いなという印象を受けました。

まとめ

PostgreSQL10についてまとめました。
個人的に興味深い技術が使われていたものや、構文が追加され便利になったものなどありました。
また、パフォーマンスの向上に繋がることや脆弱性に関連した修正もあり、正しく理解しておかないといけないこともあるなと思いました。

参考

Android Studioで天気情報を表示するアプリを作ってみた

はじめに

kuwa_38です。以前Android Studioを使ってみたので、その続きとして天気情報を表示するアプリを実装してみました。簡単に実装できるかと思いきや、AndroidではAPI接続に非同期処理(AsyncTask)を用いる必要があるらしく苦戦しました。この記事では今回苦戦した非同期処理も含め、天気情報を表示するアプリについて、実装に必要なこと、実装したコードを記載します。

前回実装した処理

今回は下記の実装に付け加える形で実装したため記載しておきます。

Android Studioを使ってHello Worldをやってみた

  • 初期画面の表示
  • ボタンを押すとテキストが変わる

今回実装した処理

  • ボタンを押すとその日の大阪の天気が表示される

利用したAPI

Weather Hacksを利用させて頂きました。GETでエンドポイントにアクセスすることで、パラメータcityで設定した都市の天気をJSONで返してくれます(因みに270000は大阪です)。

補足:jqを活用してAPIレスポンス等から欲しい情報だけを抽出する【初級編】

$ curl -s http://weather.livedoor.com/forecast/webservice/json/v1\?city\=270000 | jq -r

# 結果
{
  "pinpointLocations": [
    {
      "link": "http://weather.livedoor.com/area/forecast/2710000",
      "name": "大阪市"
    },
# ...(中略)
 "link": "http://weather.livedoor.com/area/forecast/270000",
  "forecasts": [
    {
      "dateLabel": "今日",
      "telop": "晴れ",
      "date": "2018-05-27",
      "temperature": {
        "min": null,
        "max": {
          "celsius": "29",
          "fahrenheit": "84.2"
        }
      },

Androidのバージョンに伴う注意点

それでは実装、といきたいところですが、先に私がハマった注意点について述べておきます。

実装概要

コードなどは次の節に記述します。この節では実装すべきことについて大まかに述べます。

※ 今回は実機デバックを対象とします(エミュレータを使用する場合は、エミュレータwifi設定などが必要です)。

ネット接続を許可する

  • AndroidManifest.xmlに下記を追記
<!-- ネット接続を許可する -->
<uses-permission android:name="android.permission.INTERNET" />

ボタンを押すと特定の処理を実行する

  • 前回の記事を参照ください

APIサーバに接続する

  • 注意で述べたようにメインスレッドでは接続できませんので、実行用のクラスを作成してあげます

    • 参考:AsyncTaskを使った非同期処理のきほん

      1. AsyncTaskを継承するクラス(今回はAsyncHttpRequestというクラス名にしました)を作成する
      2. 作成したクラス内にdoInBackground(非同期で行いたい処理を記述する)メソッドを実装する
      3. メインスレッド(MainActivity.java)で1のクラスをインスタンス化し、executeメソッドを呼び出す
        doInBackgroundが呼び出される

受け取ったJSONを加工する

  • 受け取った文字列をJSONObjectでパースし、天気情報を取り出します

天気情報を表示する

  • AsyncTaskを継承するクラスでonPostExecute(非同期処理が終わった後に実行される)メソッドを実装し、メインスレッドのラベルを変更する

実装例

下記にMainActivity.javaAsyncHttpRequest.java(AsyncTaskを継承するクラス)を載せますので、実装してみたい方は参考にして下さい。

AndroidManifest.xmlは1行追記したのみですので載せていません

MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * トップ画面を制御するActivityクラス.
 */
public class MainActivity extends AppCompatActivity {

    /**
     * 画面を表示する.
     *  note:デフォルトで実装されている
     * @param savedInstanceState savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    }

    /**
     * テキストラベルを変更する.
     * @param view view
     */
    public void changeTextView(View view) {
        // 非同期処理(AsyncHttpRequest#doInBackground())を呼び出す
        try {
            new AsyncHttpRequest(this).execute(new URL("http://weather.livedoor.com/forecast/webservice/json/v1?city=270000"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

AsyncHttpRequest

import android.app.Activity;
import android.os.AsyncTask;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 非同期処理を行うクラス.
 */
public final class AsyncHttpRequest extends AsyncTask<URL, Void, String> {
    private int TODAY_FORCAST_INDEX = 0;
    private Activity mainActivity;

    public AsyncHttpRequest(Activity activity) {
        // 呼び出し元のアクティビティ
        this.mainActivity = activity;
    }

    /**
     * 非同期処理で天気情報を取得する.
     * @param urls 接続先のURL
     * @return 取得した天気情報
     */
    @Override
    protected String doInBackground(URL... urls) {

        final URL url = urls[0];
        HttpURLConnection con = null;

        try {
            con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            // リダイレクトを自動で許可しない設定
            con.setInstanceFollowRedirects(false);
            con.connect();

            final int statusCode = con.getResponseCode();
            if (statusCode != HttpURLConnection.HTTP_OK) {
                System.err.println("正常に接続できていません。statusCode:" + statusCode);
                return null;
            }

            // レスポンス(JSON文字列)を読み込む準備
            final InputStream in = con.getInputStream();
            String encoding = con.getContentEncoding();
            if(null == encoding){
                encoding = "UTF-8";
            }
            final InputStreamReader inReader = new InputStreamReader(in, encoding);
            final BufferedReader bufReader = new BufferedReader(inReader);
            StringBuilder response = new StringBuilder();
            String line = null;
            // 1行ずつ読み込む
            while((line = bufReader.readLine()) != null) {
                response.append(line);
            }
            bufReader.close();
            inReader.close();
            in.close();

            // 受け取ったJSON文字列をパース
            JSONObject jsonObject = new JSONObject(response.toString());
            JSONObject todayForcasts = jsonObject.getJSONArray("forecasts").getJSONObject(TODAY_FORCAST_INDEX);

            return todayForcasts.getString("dateLabel") + "の天気は " + todayForcasts.getString("telop");
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
    }

    /**
     * 非同期処理が終わった後の処理.
     * @param result 非同期処理の結果得られる文字列
     */
    @Override
    protected void onPostExecute(String result) {
        TextView tv = mainActivity.findViewById(R.id.messageTextView);
        tv.setText(result);
    }
}

おわりに

本記事ではAndroid Studioを使い、天気情報を表示するAndroidアプリの実装方法を紹介しました。まだまだ実用には遠いクオリティですが、非同期処理やjqコマンドなど知らなかったことを学ぶいい機会になりました。自分の学習目的で始めた部分が大きいですが、Androidアプリ開発の初心者や非同期処理の実装で困っている方の手助けになれば幸いです。


◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

メンバー同士でお互いの価値観を可視化するムービングモチベーターズを新チーム結成時に使ってみよう

id:radiocat です。今年度はビアバッシュ推進委員から一歩身を引いてアドバイザー役になりました。

このブログでも何度か紹介している ビアバッシュ ですが、このたび新しい運営メンバーが選抜されて、先日キックオフを行いました。同じ会社の社員とはいえ価値観は人によって違うため、ビアバッシュをどのように推進していきたいか、思い描くイメージはそれぞれ違っているものです。はじめはお互いに手探り状態で意見をすり合わせながらやりたいことをまとめていくことになりますが、そんな時に役に立つ価値観を可視化する手法が「ムービングモチベーターズ」です。

ムービングモチベーターズとは

チームのメンバー同士でお互いの価値観を共有するためのワークショップです。手法の成り立ちや考案者については後述します。

10種類のカード

モチベーションの源泉となるキーワードが書かれた10種類のカードがあります。このカードを自分が価値を感じる順番に並べ替えて共有します。

f:id:radiocat:20180523000145p:plain:w500

やってみよう

テーマの認識合わせ

まずは何に対しての価値観について考えるのか全員でしっかり認識合わせをします。今回は「開発部のビアバッシュを推進していくうえで価値が高いと感じるキーワード」としました。

実践タイム

5分~10分程度で時間を決めて並び替えます。あまり深く考えず直感的に並び替えましょう。

f:id:radiocat:20180523000251p:plain:w500

共有タイム

1人ずつ結果をチームに共有します。なぜそのキーワードを選んだのか理由も説明して価値観の理解を深めましょう。

f:id:radiocat:20180523005955p:plain:w500

今回はメンバーそれぞれが選んだトップ3を発表しました。このチームは「関係性」と「受容」を選んだメンバーが多いとか「名誉」や「権力」は誰も選ばなかったといったコミュニケーションを取って価値観を共有しました。

まとめ

ビアバッシュのような社内イベントの運営ではルールや手順が細かく決まっているわけではなく、むしろ集まったメンバーの個性や考え方に委ねられている面もあるので、このように手軽に価値観を共有できる手法はとても有効です。

また、私の所属する開発チームでは毎月1回全員でこれを行って前月からのメンバーの価値観の変化も追いかけています。「最近新しい技術に取り組んでいるので好奇心を選んだ人が増えた」とか、「難しい課題に取り組んでいるのでゴールの重要性を感じている」といった、チームの状況の変化に応じたメンバー同士の価値観の変化にも気づけます。

最後に、実践しするうえでのポイントを3つ紹介します。

気軽に並べる

結局どれも大事な言葉なのです。時間をかけずにその瞬間の価値観をさらけ出しましょう。もちろん隣の人のカードを見てはいけません。

言葉の捉え方も共有する

やってみると言葉の捉え方が人によって違うことにも気づきます。元々英語で作られたカードなので、「受容」や「熟達」など、日本語だと少しイメージしにくい言葉もあります。しかし気にする必要はありません。「自分はこう思ってこれを選んだ」という考えを共有することが大事です。どうしても気になる場合はみんながどういう意味で捉えているか聞いてみましょう。

楽しむ

お互いに価値観を共有しあうので、堅苦しい雰囲気だと発言しづらくなります。無言でカードを並べるのではなく、楽しくワイガヤしましょう。

参考:Management 3.0

ムービングモチベーターズはManagement 3.0のプラクティスの1つです。

management30.com

Management 3.0は 公式サイト で以下のように説明されています。

オランダ出身のヨーガン アペロ(Jurgen Appelo)の世界80ヶ国で展開している新しいイノベーションとリーダーシップそしてマネジメント運動です。

近年マネジメントの領域で注目されている自己組織化や心理的安全性などについても言及されており、アジャイル開発の現場でも手法が使われているようです。

ARKit + Unityでアプリ開発

こんにちはsts-250rrです。

今回も前回の記事に引き続きAR技術の紹介になります。

tech-blog.rakus.co.jp

前回は簡単にARを体験する。まででしたので今回はSoftware DesignのコラムにあったARアプリARKittenを作ってみました。

gihyo.jp

ちなみにGithubリポジトリでサンプルを公開してくださっていますので、こちらでまず試してみるのも良いかもですね。

では、やっていきましょう。

猫、ARに立つ

前回はARの世界で平面を検出し、キューブを設置するところまででしたが、それではあまりに味気ないので猫を配置することにします。 ※AssetStoreからARKitをインポートする部分は割愛します。

UnityのAssetStoreでは、3Dのモデルデータを購入することもできます。
ここから猫のモデルを取得していきたいところですが、残念なことにARKittenで使用する猫のモデルは作成者の諸事情により、AssetStoreからダウンロードできなくなってしまいました。
現在は上記のGithubからモデルデータを取得してくるしかないようです。
Kittenディレクトリをプロジェクト名/Assets配下に格納しておきましょう。

単純に猫を平面に追加するだけでは、拡張現実らしくなりません。
それはなぜか、ズバリ影がないからです。

そこで今回作成するアプリではUnityARShadowsというサンプルを元に作成していきます。
このサンプルであれば平面を検出した部分に3Dモデルの影を落とすことができます。

UnityARShadowsにはCubeの代わりにHitPlayerが存在しています。
f:id:sts-250rr:20180519210601p:plain これをAssets/Kitten/Prefabs/KittenNPCに置き換えます。 f:id:sts-250rr:20180519210723p:plain

これだけではiOSの画面をタップしても猫が平面に配置できないのでスクリプトを組み込んでいきます。

KittenNPCを選択しインスペクターウィンドウ(右側に表示されている設定窓)の設定を以下のようにします。 f:id:sts-250rr:20180519211418p:plain

ここで一度ビルドして、画面をタップして見て猫を配置してみます。
猫に影がついていたり、アニメーションが定義されているので、まるで猫がそこにいるようです。 f:id:sts-250rr:20180520172607p:plain

カメラを向かぬ猫

f:id:sts-250rr:20180520172401p:plain

単純に猫を配置するだけでは、場所によってはそっぽを向かれてしまいます。
猫を配置した時にいつもこちら側(カメラ)を向いてくれるようにしつけスクリプトを追加していきます。
ここでは猫がカメラを向いてくれる時の処理の流れを解説します。

  1. 猫位置の取得
    タップで配置した猫の位置を取得します。
    このままでは猫は初期の向きを向いてしまいます。
    3Dグラフィックスの世界では向き(回転)という情報はクオータニオンと呼ばれるもので保持されています。

  2. カメラ位置の取得
    猫とカメラの位置(座標)を比較することで、猫がどの方向を向けば良いのかがわかるようになります。

  3. カメラの方に向かせる 猫とカメラの位置の差から、猫がどれだけ回転すれば良いのかを計算します。
    この計算は3Dを扱うライブラリであれば、大抵3次元ベクトルを与えてやれば計算してくれる関数があります。
    ARKitであれば、QuaternionクラスのLookRotationクラスがその一つに該当します。
    スクリプトの内容はサンプルコードを眺めてみてください。

スクリプトが完成したら再びビルドしましょう。
そこには従順にこちらを向いている猫が佇んでいるはずです。

f:id:sts-250rr:20180520172311p:plain

まとめ

今回は前回ご紹介したARKitのサンプルプログラムを作ってみました。 猫が配置され、それを眺めるまでしかできませんが、本来そこにいないはずの猫が画面を通して存在している感覚はまさしく拡張現実です。

次回も引き続きARKitネタをお送りしたいと思います。
お楽しみに、

実録ビルドできない事件簿

iPhoneiOSをアップデートしたばかりにビルドできなくなってしまった・・・・ f:id:sts-250rr:20180520140348p:plain

エラー内容を見てみると、 「iOS11.3のデバイスサポートファイルがない」ということだそうです。

みなさん結構起きてしまっているようで、解決策を調べてみたらすぐに出てきました。 今回は以下の記事を参考にさせていただきました。

iOSをアップデートしたために実機でビルドができない - Qiita

メールディーラーバージョン12.2をリリースしました!

ラクスのメールディーラーの開発を行っている@nerobluebrosです。
5月9日にメールディーラーのバージョン12.2をリリースしました。

今回はそのメールディーラーバージョン12.2とリリースについての紹介をします。

バージョン12.2では33の機能と修正をリリース

12.2では大小合わせて33の機能と修正をリリースすることが出来ました。
主な機能と修正は以下のとおりです。

1.添付ファイルセキュリティオプション機能
 ・添付ファイルの拡張子と実際のファイルの内容をチェックします
 ・ユーザ単位で添付ファイルのダウンロード可否をコントロールできます
 ・期限付きのURLから添付ファイルのダウンロードができます
 ・添付ファイルのみを対象に自動削除できます
2.アドレス入力欄のUI変更などUI改善
3.ミドルウェアPostfixにすることでSTARTTLSに対応します
4.メール本文をRFCに準拠しました
5.不具合修正

リリースは複数回に分割して実施

以降はリリースについて説明します。リリースは複数回(複数日)に分割して行います。
理由は以下のとおりです。

・メールディーラーのサーバは複数台あり1日では終了しない
・メールディーラー内部のミドルウェアの変更があり、より慎重におこなう必要があった

リリース作業は深夜に実施します。
それはリリース中にメールディーラーのサービスが停止するからです。

「サービス停止が発生する=お客様がメールディーラーを利用できない」ということを意味します。
ですので、お客様の日常業務に影響しないように、夜間バッチが開始される朝の4時までにリリース作業を終了しなければなりません。

そのため、リリース作業によるサービス停止時間を極力短くするために、準備作業などは事前に実施しておきます。
リリース作業は「できるだけ遅い時間に開始」し「できるだけ早く終了」する時間との戦いになるので大変な作業です。

リリースについてはまた別の記事で詳しくご紹介します。

なお2回目は5月30日の深夜を予定しています。

以上でメールディーラーの12.2の機能とリリースについての説明を終わりにします。

おまけ

現在ラクスでは新卒採用と中途採用を行っています。
サービス開発に少しでも興味がある方は下記採用サイトをご覧になり、応募をおねがいします。

ラクス採用サイト
http://fresh-recruit.rakus.co.jp/

コマンド不要で超簡単!HerokuでWebアプリ開発を30分で始める【php+postgres】

こんにちは。エンジニアのmickey-STRANGEです。
前回はめんどくさがりによるめんどくさがりのためのスマホアプリ開発についてお話したいと思います。なんて言いながら、全てをJSでごりっと無理やり解決する方法をご紹介しました。 tech-blog.rakus.co.jp はい、タイトル詐欺です、すみません。冷静に考えて、この作りのWebページが世の中にない現状、これよりも簡単な方法が必ずあるはずなんですよね(当時サンプル書きながらコレめんどくさいな、なんて思ってないです)

今回はタイトル詐欺ではなく、Herokuというサービスを用いてWebアプリ開発の環境構築が本当に簡単に出来てしまう方法をご紹介いたします。

Heroku(へろく)とは

Herokuとは、PaaS(Platform as a Service)の1種で、アプリケーションの底にあるプラットフォームそのものを、Webを通じて提供してくれるサービスです。
今回の記事では、Heroku上でphp+postgresをプラットフォームとするWebアプリの構築、が目的となります。

Herokuで環境構築

Herokuを用いて、ということなのでHerokuのアカウント登録は完了している前提で説明を始めます。使用するのは以下の2サービスですので、アカウント登録まだだよ、という方はご準備ください。

  • Heroku

jp.heroku.com

github.co.jp

php+postgresアプリの作成

まず最初に、Heroku上にアプリケーションを作成します。ログインして右上NewからCreate New App、もしくはアプリケーションが1つもない場合は画面真ん中にあるCreate New Appをクリックします。

アプリ名を入力し、Create appをクリックします。これでアプリケーションが作成できました。
といっても、名前と枠組みだけの状態なので、これからphp+postgresで動くアプリケーションだという設定をします。

アプリケーションのページからSettingsAdd buildpackの順にクリックします。

立ち上がったポップアップの中でphpを選び、Save changesをクリックします。

これで作成したアプリケーションはphpで動きますよ、という設定が出来ました。

続いてpostgresを設定します。
ResourcesFind more add-onsからHeroku Postgresを探してクリックし、Install Heroku Postgresをクリックします。

Heroku Postgresはアドオンですので、料金プランの選択があります。というと身構えてしまうかもしれませんが、Hobby Devという無料プランがありますので、これを選択します。そしてpostgresを追加するアプリケーションを選択し、Provision add-onをクリックします。

以上で作成したアプリケーションをphp+postgresのアプリケーションであるという設定が完了しました。あとはソースをデプロイすればWebアプリケーションとして稼働する状態です。

デプロイソースの指定

続いて、ソースのデプロイ元の設定をご説明します。
ソースのデプロイ元として使用するのがGitHubになります。GitHubにデプロイ用リポジトリを作成し、直下にindex.phpをpushします。

今回作成したファイルは以下のものです。php+postgresが稼働していること、phpからpostgresに接続できていることの確認が目的なので簡単なものです。

今回もGitHubへのpushはGitHub Desktopを使用しました。直感でぽちぽちできるデスクトップアプリはやはり強いですね。
GitHub Desktop | Simple collaboration from your desktop

とはいえ、これでGitHub側の操作は終わりです。Herokuの画面に戻ります。
DeployGitHubSearchとクリックし、上記index.phpをpushしたリポジトリの隣にあるConnectをクリックします。

これでGitHubリポジトリからデプロイする設定が完了しました。HerokuからGitHubへの接続が初めての場合は、連携をするかどうかの確認が出ますので、表示されるとおりに進めていけばOKです。

最後に、Enable Automatic deploysDeploy Branchをクリックしましょう。
Enable Automatic deploysは自動デプロイの設定です。ブランチを指定して自動デプロイを有効にすることで、そのブランチにpushされるたびに自動でアプリケーションを最新のソースに置き換えてくれます。
Deploy Branchは手動デプロイのボタンです。アプリケーションの設定とデプロイ元の指定をしただけで、まだデプロイはされていません。自動デプロイを有効にしたとしても、初回だけは手動で行います。

ブラウザからアクセス!

これまでの手順で全ての準備が完了しました。実際に作成したアプリケーションにアクセスしてみましょう。
アプリケーションのページの右上にOpen appというボタンがあるのでクリックしてみましょう。

作成したindex.phpの通りに表示されました!
postgresのバージョンもphpから取得出来ているのでgetAttributeの代わりにSQLを発行して動きをつけていけば立派なWebアプリケーションになりますね。

個人的な感想として、postgresが10.3と最新に対してphp5.6がツッコミどころに思えて仕方がなかったのですが、phpのバージョンを指定する方法がちゃんと用意されています。画面から作っただけではデフォルト設定で作られる、といった感じでしょうか。composer.jsonに改めて指定することでphpのバージョン変更が可能です。
Heroku PHP Support | Heroku Dev Center

【補足】phpからpostgresの接続

ここまでアプリケーション稼働までの手順をご説明いたしましたが、1つだけ補足があります。

最初、phpからpostgresに接続するにあたって、接続情報の取り方に詰まりました。Herokuの画面上から確認は出来るのです。ですが、これだけ環境構築が簡単なのに接続情報はまったく関係ないサービスであるGitHub上のソースにべた書きで持つ、というところが引っかかりました。GitHub上のソースを見れば他の人のアプリのDBにアクセス出来てしまいます。
調べたところ、postgresをアプリケーションに追加したときに、環境変数に追加されているようで、そこから取得する方法が、上記のindex.phpの記述になります。
Heroku Postgres | Heroku Dev Center

終わりに

今回はタイトル詐欺ではなく、めんどくさがりでもすぐにWebアプリ開発が出来る手順の記事になっていると思います。

Herokuを初めて使ったのですが、とても簡単で驚きました。調べるにも公式ドキュメントが多いので、詰まってどうしようもなくなるということはありませんでした。
タイトルの30分というのも嘘ではなく、「よし、やるか」と思い立ってHerokuのアカウントを作成してから、特に調べるでもなく直感でぽちぽち画面を操作して、phpinfo()を画面に出すまでの時間がそれぐらいでした。本当に簡単です。
コマンド要らずの設定の簡単さも素晴らしいのですが、特にpushからの自動デプロイがめんどくさがりの心にかなり響きました。

気を付けないといけないところは、前回の記事で作成したアプリはアクセス者本人の画面にのみデータが表示されるのに対し、Herokuは通常のWebアプリになりますので、脆弱性のあるサービスを公開してしまうと攻撃の踏み台として使われてしまう可能性があります。アプリの作成、公開は気を付けて行いましょう。

さて、これにて今回の記事は終わりとしますが、前回のタイトル詐欺の汚名を返上できたでしょうか。 最後までお読みいただきありがとうございました。


  • エンジニア中途採用サイト
    ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
    ご興味ありましたら是非ご確認をお願いします。
    20210916153018
    https://career-recruit.rakus.co.jp/career_engineer/

  • カジュアル面談お申込みフォーム
    どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
    以下フォームよりお申込みください。
    forms.gle

  • イベント情報
    会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.