またどこかでCTOっぽいことやってる人のブログ

フリーランスを経て、またどこかでCTOっぽいことをやってる人が書いてます。何か色々やってます。

ConoHaのLAMPイメージでサーバ構築してみた 〜PHP7にアップデート〜

一人でGitLabサーバ構築ができました。
これは、インフラもできるエンジニアとしての大きな一歩を踏み出したと言っても過言ではありません。
「インフラですか? まぁ多少は。フフ」ぐらい言ってもいいかもしれません。
絶対言いませんけども。


さて、次は社内システムとしてのWebアプリを作ることにしました。
スケジュール閲覧とか問い合わせ管理とかそういうのです。
Webアプリ自体はサラっとCakePHP3で作ったのですが、今度はこれをサーバに載せなければいけません。
またです。またサーバを構築です。

やりたいこと

URLを知っていればアクセスできる。
ログインするためのIDとパスワードが必要。
スマホでアクセスできる。
DBは同じサーバ上にあればOK。

LAMP環境ですね。
ConoHaさまにお伺いを立てたところ、LAMPイメージがありました。
またも大勝利が見えています。

とりあえずConoHaからLAMPイメージを構築

特筆すべきことはないです。
こちらも秘密鍵認証にしたので、またpemファイルが吐き出されたぐらいです。
ちゃんと保存しておきましょう。

出来上がったLAMPイメージを確認してみる

Apacheある!
PHPある!
mySQLある!

なんですが。
PHPのバージョンが5.6でした。
「あれ、LAMPイメージ作る時に設定いるのかな?」と思っていたのですが、そうではなさそうでした。
どうやらConoHaのLAMPイメージで出来たサーバは、PHP5.6のようです。


PHP7使いたいんだけどなーと不安になりながらググってみたら、どうやら自分でインストールする必要がありそうです。
自分にはそんなことはできません。何でConoHaさまはPHP5.6なんだよ!
と文句をつけても仕方がありませんので、腹をくくってPHP7を入れてみることにしました。
もうこの時点で不安です。

yumをアップデートする

「ヤム」とか読むらしいです。
Linuxのパッケージ管理ソフトです。流石にこれぐらいは知ってます。
まぁアップデートとか言われるとガタガタ震えてしまうのですが。

グーグル先生にお申し立てをして、以下の手順でyumをアップデートしました。

# yumのお掃除コマンドらしいです。
yum clean all

# yumのアップデート(-yのオプション入れてもOKです)
yum update

# 何か知りませんがやった方がいいらしいので
yum -y install yum-plugin-priorities


雑ですみません。
とりあえず上記手順でyumのアップデートが出来たようです。

デフォルトのPHPを削除

ConoHaのLAMPイメージにデフォルトでインストールされていたPHPを削除します。
要するに「PHPが稼働しないLAMP環境」になります。
ちょっとどころか相当不安だったのですが「ダメだったら作り直せばいいか!」的なノリで削除してやりました。
以下、削除手順です。

# 初期インストールされているPHPのファイルを確認(リスト表示されます)
rpm -qa | grep php

# PHP関連のファイルを削除
yum remove php5*

 
本当に削除されてしまいました。

PHP7をインストール

お利口なyumがインストールしてくれます。
何も考えずに以下のコマンドを実行しました。

yum --enablerepo=remi-php70 -y install php php-mbstring php-pear php-fpm php-pdo php-intl php-mysqlnd php-pecl-redis php-xml php-gd php-json


何かよく見ると「php-intl」とかCakePHP3インストールに必要なライブラリも入ってます。
多分大丈夫でしょう。

一応Apacheを再起動

LinuxはCentOS7にしてみたので、以下のコマンドで再起動しました。
別にいらないかもしれませんが、まぁ一応。

systemctl restart httpd

インストールできたはずのPHPバージョン確認

さて、多分ちゃんとPHP7がインストールされているはずです。
ドキドキしながらPHPのバージョン確認です。

php -v

PHP 7.0.21 (cli) (built: Jul  5 2017 14:33:41) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies


!!!

PHP7になっていました。
これは大勝利と言っていいでしょう。


というわけで、PHP7が無事にインストールできました。
怪しげなインフラエンジニアスキルが助長されていきます。

ConoHaのイメージを使って、GitLabサーバを構築してサブドメインを設定してみた。

前回契約したConoHaサーバですが、色々なアプリケーションサーバのイメージが最初から準備されているようです。
インフラ知識皆無な自分にとっては優しい仕様です。どこかの偉い人、ありがとうございます。


さて、とりあえず色々と作りたいものはあるのですが、まずはソース管理が最初かなと思いました。
ので、前職でも採用していた「GitLab」を使うことにしました。
見てみるとGitLabのイメージもあります。これは大勝利の予感がします。

ConoHaのコントロールパネルからGitLabサーバを作ってみる

注意点は特になかったです。
秘密鍵は必須かなと思ってましたので、途中で作成した秘密鍵のpemファイルを必ず保存しておくぐらいでしょうか。
あ、pemファイルが何かぐらいは知っています。
アレですよね。接続する時に使う大事な鍵ですよね。知ってます。
※本当にこのぐらいのインフラ知識しかありません。

ブラウザでアクセスしてみる

サーバを作成するとIPアドレスが勝手に吐き出されるので、そのIPアドレス目掛けてブラウザでアクセスしてみると、無事にGitLabのログイン画面が表示されます。これだけで感動です。
初回アクセス時はrootユーザでのアクセスになるようです。
rootユーザのパスワード変更しやがれっぽい画面が出てくるので、パスワード設定してみました。
設定したパスワードはちゃんと保存しておきましょう。

GitLabにSSHでアクセスしてみる

サーバ作成時に保存したはずのpemファイルでアクセスします。
自分の場合は「どこに何があるかわからなくなる」のがイヤなので、この手のファイルは一箇所にまとめてしまいます。
開発はMacでやっていますので、お好きな場所に保存するといいかと思います。
参考までに自分の場合はこの辺に置いてみました。

  /Users/ユーザ/develop/key/gitlab.pem


※developディレクトリとkeyディレクトリは新規作成です


MacからのSSH接続はコンソールから実行できます。
以下のような感じです。

  cd /Users/ユーザ/develop/key
  ssh -i "gitlab.pem" root@999.999.99.99

999〜と記載している部分は構築したGitLabサーバのIPアドレスになります。
ConoHaのコントロールパネルを見れば書いてあります。

Administratorユーザの名称を変更する

これは別に変更しなくてもいいと思います。
自分がやりたかったことは、GitLabの各プロジェクトをAdministratorユーザで作成してマージやデプロイ自体は別ユーザでやりたかっただけなので。
プロジェクト作成用のユーザを作ればよくね? と後から思ったのですがもういいです。

ユーザ名の変更はGitLab画面上から実行できます。
右上のアイコンから「Setting」を開いて、その画面から「Account」を選択すれば設定画面が出てきます。
自分はここでAdministratorユーザの名前を「gitlab」に変更しました。
「Change username」部分です。
名前を変更すると次回ブラウザからアクセスする時のユーザ名も変わります。

作成したGitLabサーバにドメインを割り当てる

IPアドレス直接でログインするのもアレなので、ドメインを設定することにしました。
何か昔やったことがあるのですが、今となっては設定方法がよくわかりません。
よくわからないのに「サブドメインがいいな」と自分でハードルを上げてしまいました。

この作業をやっている時、Macに表示されているコンソール画面をチラ見されて「すっごーい」と某フレンズ的な賞賛をされたのですが、自分でもよくわかっていないので某フレンズのようにはなれないのです。


話を戻します。
ConoHaを使っているので、とりあえずドメインはお名前.comで借りました。
サブドメインじゃなければ、きっと作成したGitLabサーバのIPアドレスを割り当てればいいんだと思います。
が、「サブドメインがいいよね、フフ」なんて思ってしまったばかりに、サブドメイン設定をしなければいけません。

とは言え、きっとお名前.com先生がそんなの簡単に設定できるようにしてくれているだろうと信じてコントロールパネルをごにょごにょ触ってみました。
結果、「多分、DNS設定のナントカ部分だな。何か聞いたことあるし」的なノリで実施してみることに。


お名前.comのドメインNAVIからログイン。
契約しているドメイン一覧が表示されますので、対象のドメインを選択しました。
選択後、画面上部にタブが出てくると思いますので、「ドメイン設定」をポチっと。
何か設定画面ぽいのが出てきましたので、そこから「DNS関連機能の設定」を選択。
内部ドメイン一覧が表示されました。またかよ。


文句を言っても仕方がないので、対象のドメインを選択して次へ。
また何か色々メニューが出てきました。この辺で「え、これ合ってるの…?」と不安になっていました。
が、メニューを見ていたら「DNSレコード設定を利用する」とかいうものが書いてあります。
説明文には「AレコードやMXレコードの設定が必要な場合にご利用ください」との記述。

こ れ だ

勘を働かせて設定ボタンを押したところ、出てきました。
前にAWSの方で見たことのあるような感じの画面です。ここで設定すればいいはずです、多分。


サブドメインはAレコードに設定すればよさそうなので、とりあえず設定するサブドメインを入力してIPアドレスを設定しました。
お名前.comのコントロールパネル上だと以下のような感じです。


・sample-site.infoというドメインを契約済み
・gitlab.sample-site.infoというサブドメインを設定する場合
 ホスト名:gitlabと入力
 VALUE:作成したGitLabのIPアドレス


で、保存しました。
きっとこれでできているはずです。

GitLabサーバの方に作成したサブドメイン設定を記述する

調べてみたところ、コンフィグファイルに設定が必要らしいです。
へーそうなのねと深く考えずに設定することにします。

rootユーザでSSHにログインして、以下のファイルを開きます。
どうでもいいですが、自分はvim派です。

  vim /etc/gitlab/gitlab.rb

開くと設定が何か色々書いてありますが、修正箇所は1箇所だけです。

  external_url 'http://gitlab.sample-site.info/'


設定が終わったらファイルを保存して、GitLabのコンフィグファイルの再読み込みを実行します。

  gitlab-ctl reconfigure


そう言えば、GitLabはApacheではなく「nginx」で稼働しているらしいです。
エンジンエックスと読むことを知らず、ずっと「ンギックス」と読んでいました。
まぁどうでもいいですね。

設定したサブドメインにブラウザからアクセスしてみる

今回の場合だと http://gitlab.sample-site.info/ になります。
アクセスできなかった場合は慌てず騒がず、時間を置いてからアクセスしてみてください。
ドメインの書き換えが終わったら多分接続できると思います。きっとできます。


というわけで、運任せとか勘任せなどもありましたがインフラ知識皆無な自分にもGitLabサーバの構築ができました。
嬉しかったので、前職の部下に「一人でできたよ!」とLINEをブチ込んでおきました。


ネタではなく、本当にインフラできないのです。
前途多難ですが、しばらくConoHaサーバとの戦いが続きます。

インフラできないけどConoHaを契約してみた。

2017年7月になりました。
以前書いたように、新しい会社にジョインしました。
まだ初週が終わったばかりなのですが、なかなか楽しそうな会社です。


が、早速問題勃発です。
新しい会社にはエンジニアがいないので、自分が全てをやる必要があります。
社員の方々はインフラエンジニアとかフロントエンジニアとかサーバエンジニアとかそういう区分けも知りません。
「エンジニアは魔法使いであり唯一神」ぐらいの勢いです。


元々、Wordpressでサイトを構築してごにょごにょやっていたと聞いていたのでサーバはあると思っていました。
案の定、サーバはありました。エックスサーバを借りているようです。
そこにこれから作るものを構築しようと思ったのですが、せっかくなので別サーバを借りてみようかと。
且つ、今まで必要に駆られない限り極力避けてきたインフラにトライしてみようと。
これ、自分の中では相当なレベルのイベントです。


前職ではAWSを採用していたのですが、AWSって高いと思うのです。
ましてやスタートアップの会社にAWSがそもそも必要なのか。便利なのはわかるのですがコストがちょっと。
コストを極力抑えて、やりたいことを実現できるサーバがいいなぁと。
というわけで色々調べた結果、GMOさまが提供しているサーバのConoHaを契約してみました。

www.conoha.jp


特徴は公式サイトにお任せするとして、簡単に書くと「クラウドっぽく使えるVPS」だそうです。
アプリケーションイメージも予め準備されているようなので、インフラ知識皆無な自分でもできるかもしれません。
いや、やらなきゃいけないのは重々承知していますが。


サーバの契約自体はすんなり終わりました。
コントロールパネルもわかりやすいです。
よし、これならきっとできると根拠のない自信も生まれました。


というわけで、弊サイトに「ConoHa」というカテゴリーを追加し、色々やってみようと思います。

CakePHP3でどこでも使えるグローバル配列を作ってみた。

グローバル配列という音の響きが何だかアレなんですが、あまり気にしないことにします。
CakePHP3を使っていれば大抵「フォームヘルパー」を使うんじゃないかなと思います。
テキストもあればラジオボタンもありますが、自分が多用するのはセレクトボックスです。

何度も書いている通りUIセンスが絶望的なので、Bootstrapばかり使っているのですがセレクトボックスはここ半年ぐらいは「SelectPicker」を使っています。

silviomoreto.github.io


以前書いたselect2もいいのですが、使ってるうちに何かどうも都合よくないことが多く乗り換えました。
使い方はまたそのうち書いてみます。


やりたかったこと

セレクトボックスにいれるリストを使い回したかったのです。
ViewにセットするだけであればControllerにprivateで配列作ってセットすればいいのですが、取得したデータの結果に合致するKeyからValueを取得してdatatablesを読み込んだテーブルに表示したかったのです。
要するにViewにセットする時にEntityで処理をする時に使い回したいなと。

Entityの中でif文で切り分ければできてしまうのですが、リストの中身が増減した時に面倒ですしそもそもあまり美しくない。
というわけでグローバル配列を作ってみました。

やったこと

確かCakePHP2の頃もあったと思うのですが、こういう時はbootstrap.phpにfunctionを作ります。
作成したfunctionの返り値を配列にして、それを使います。
しかし何でbootstrapって名前なんですかね。まぁいいです。

<?php
 // bootstrapの記述

 /**
  * 配列を取得するfunction
 */
 function getSampleList() {

    $sampleList = [
      0 => 'サンプル1',
      1 => 'サンプル2',
      2 => 'サンプル3',
      9 => 'その他'
    ];

    return $sampleList;
  }


雑なfunctionです。
functionにpublicは不要です。
とりあえずこれをグローバル配列とします。


取得したデータは上記functionのキーにあたる、何らかの数値が入っているものと仮定します。
DB定義だと何ですかね。個人的なアレだとtinyint(4)です。
Viewにセットする時はこんな感じになると思います、多分。

<?php
 // Viewにセット
 $this->set('sampleList', getSampleList());


View側は結構端折りますが、こんな感じです。

<?php
 <!-- SelectPickerを使ったセレクトボックスです -->
 <?php echo $this->Form->input('Sample.sample_val', [
        'class' => 'form-control selectpicker',
           'data-live-search' => true,
           'data-width' => '100%',
           'type' => 'select',
           'div' => true,
           'label' => 'サンプルリスト',
           'options' => $sampleList, // ここにセット
           'default' => 0
   ]); ?>


これでセット完了です。
Entityの方は以下のように書いてみました。

<?php
 /**
  * リストの値取得用フィールド
 */
 protected function _getSampleListValue() {
    
    // サンプルリストを取得
    $sampleList = getSampleList();
    
    if (array_key_exists($this->_properties['sample_val'], $sampleList)) {
        // データが存在する場合は配列に対してキーとしてセット
        return $sampleList[$this->_properties['sample_val']];
    } else {
        return '不正データ';
    }
  }


まず、bootstrap.phpに作成したfunctionからリストを取得。
次に「sample_val」という何かのテーブルにあるカラムのデータ($this->_properties['sample_val']部分)が、リストにあるかチェック。
存在していた場合はリストのキーとして「sample_val」のデータを指定して、合致するValueを取得して返しています。


とりあえずこれでやりたいことができました。
リストが増減した時はbootstrap.phpに作ったfunctionを修正すればOKなはずです。

前に書いた定数は配列を指定できません(はず)
いや、指定はできますが使えません。確か。
ですので、今回のような方法を取っています。

Configファイルに書いても同じようなことができると思いますが、あまりConfigファイルに書いていくとワケがわからなくなるのでこういう感じに仕上げました。

とは言え、bootstrap.phpにゴチャゴチャ書きたくないという方ももちろんいらっしゃると思うのでそこは好みということで。

Bootstrap3のパネルヘッダーの右端にボタンを配置してみた。

UIセンスが皆無な自分はBootstrapを多用します。
管理画面を作るのが好きなのですが、迷わずBootstrapを組み込みます。
最近は他の色々なCSSフレームワークがあるようですが、CSS大嫌いなので自分の中ではどれも大差ありません。


そんなことはさておき。
Bootstrapのパネルとアラートがとても好きです。
もの凄く多用します。
今回はパネルのお話しです。

Bootstrapのパネルの普通の構造

 <div class="row">
   <div class="col-xs-12">
     <div class="panel">
        <div class="panel-heading">
           パネルの見出し
        </div>
        <div class="panel-body">
           <div class="row">
              <div class="col-xs-12">
                 パネルの内容
              </div>
           </div>
        </div>
     </div>
   </div>
 </div>


ネルフッターとかもありますが、自分はあまり使わないので置いておきます。
やりたかったのは「panel-heading」の右側にボタンを配置することです。
「panel-body」の中にdatatables辺りでデータ一覧を表示して、新規作成ボタンを配置したいみたいなよくあるやつです。
こういう時は「panel-heading」部分をちょっと修正すると上手くできます。

こんな風に修正してみる

 <div class="row">
   <div class="col-xs-12">
     <div class="panel">
        <div class="panel-heading">
           <!-- この辺から修正 -->
           <span class="panel-title pull-left"> <!-- pull-leftで見出しを左側にセット -->
              パネルの見出し
           </span>
           <span class="pull-right"> <!-- pull-rightでボタンを右側にセット -->
              <a 
                 href="<?php echo $this->Url->build(['controller' => 'users', 'action' => 'edit']); ?>" 
                 class="btn btn-block btn-xs btn-primary">
                   新規ユーザ作成
              </a>  
           </span>
           <div class="clearfix"></div>
           <!-- この辺まで修正 -->
        </div>
        <div class="panel-body">
           <div class="row">
              <div class="col-xs-12">
                 パネルの内容
              </div>
           </div>
        </div>
     </div>
   </div>
 </div>


レスポンシブにしてもボタンがズレたりしません。
Bootstrapばっかり使う割に解説できないのがアレで申し訳ないです。

CakePHP3のtmpディレクトリ配下のキャッシュをコンソールから全部消してみた。

小ネタです。

CakePHP3でプロジェクトを作成中、テーブル定義が変わった場合tmpディレクトリ配下のキャッシュを消さないといきなりエラーが出てきます。
すっかり忘れててドキドキすることもあります。
そんな時のコマンドです。


とりあえず、プロジェクトがあるディレクトリに移動します。
自分の場合はMAMPに構築しているので、この辺です。

cd /Application/MAMP/htdocs/sample-project

ここに移動するとbinディレクトリがありますので、以下のコマンドを叩きます。

bin/cake cache clear_all


するとキレイに消えます。
便利。

公式で紹介されてました。
こちらもご覧くださいませ。

Cache Shell

CakePHP3でドキュメントの有効期限切れに対応してみた。

CakePHP3に限った話ではないのですが。
例えばブラウザバックした際に「ドキュメントの有効期限切れ」とかいうエラーが出て、頭がイーッとすることがあります。
これの対応です。


発生する理由はPHPの初期設定だと、headerに「no-cashe」を送っているからです。
ですので、そこをごにょごにょすると対応完了できます。
今回はCakePHP3のプロジェクトから、その設定をする方法になります。


上で書いていますがheaderに送ってあげればそれで終わる話です。
あとは送るタイミングの話。
CakePHP3だとbeforeRender辺りで実行するといいと思います。
AppController.phpを開いて、該当箇所に埋め込みます。

<?php
 public function beforeRender(Event $event) {
  // バージョンによりますが、ここは最初から記載があると思います
  if (!array_key_exists('_serialize', $this->viewVars) &&
   in_array($this->response->type(), ['application/json', 'application/xml'])) {
    $this->set('_serialize', true);
   }
  }

  // 2017/06/22 パクり元のエンジニアから訂正が入ったのでここから修正
  // ドキュメントの有効期限切れ対応として、以下を追加します
  header("Cache-Control: no-cache, no-store, must-revalidate");
  header("Pragma: no-cache");
  // ここまで修正しました
 }

もし、ControllerやAction毎に切り分けたくなったら、AppControllerにprotectedでbool型の変数でも作成して上記の箇所にtrueの場合のみ実行するように修正。
あとはControllerなどで作成した変数をfalseに変えればいいかと思います。


今回は弊社エンジニアが作ってた処理をそのまま記事にしてみました。
すいません。今日もパクリです。