WebサーバーのPATHを通すとは.

PATHが通っていないからErrorになった。という話を聞いたことありますでしょうか。これは、どういう意味でしょうか。

理解し易くするために、サーバーは様々な処理を実行してくれるコマンド群とイメージして下さい。

1. コマンドの在りか

サーバーには様々なディレクトリが存在しています。
コマンドは役割に応じて、複数のディレクトリ配下に待機しています。

例えば、下記のようなディレクトリです。

  • usr/bin
  • usr/sbin
  • local/bin

コマンドがOSでリクエストされるのを待機しております。

2. PATHとは何か。

サーバー上で、下記コマンドを実行して下さい。

env

下記のような環境変数が出力されると思います。 ※一部抜粋

 EB_ENV_NAME=ZZZZZZZZZZZZZZZZ
 MAIL=/var/spool/mail/ec2-user
 PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin
 PWD=/home/ec2-user
 LANG=ja_JP.UTF-8
 HISTCONTROL=ignoredups
 SHLVL=1
 HOME=/home/ec2-user
 LOGNAME=ec2-user
 SSH_CONNECTION=ZZZZZZZZZZZZZZZZ

その中に、 PATH=XXXX の部分が存在するかと思います。
これが、PATHを通す。の、PATHの正体です。

3. 結局、PATHとは何か。

結局のところ、PATHとは何でしょうか。 

OSにコマンドリクエストされた際に、PATHで指定された配下のコマンドを探すよ。

ということです。
つまり、このPATHに指定されていないディレクトリ配下にはコマンドを確認しにいきません。

4. PATHを通す必要がある機会

では、どんな場合にPATHを通す必要がるのでしょうか。

例えば、サーバーにnode.jsをインストールして起動するときなどに必要です。(node.jsのインストール方法によっても異なります。PATHが元々通った状態でインストールされている場合もあります。)

再度、envのPATHを確認してみます。

PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin

下記のディレクトリにはPATHが通っています。

  • /usr/local/bin
  • /usr/bin
  • /usr/local/sbin
  • /usr/sbin
  • /home/ec2-user/.local/bin
  • /home/ec2-user/bin

つまり、コマンドをリクエストされた際にPATHディレクトリ配下に確認して、コマンドが存在していれば、そのコマンドを実行してくれます。

私の環境では、この状態ではnode.jsのPATHが通っておりません。nodeはインストールされているが、コマンドがこのディレクトリに存在していないのです。

nvm use v14.19.0 

した後に、再度 envのPATHを確認します。

PATH=/home/ec2-user/.nvm/versions/node/v14.19.0/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin 

/home/ec2-user/.nvm/versions/node/v14.19.0/bin

が追加されております。このディレクトリ配下にnodeのコマンドが存在しております。そして、このPATH追加によってコマンドを受け入れられる状態になりました。すなわち、PATHが通った状態になりました。

如何でしたでしょうか。PATHを通すとは何かについてイメージを深めて頂けましたでしょうか。

SQSのメッセージをトリガーにLambdaを起動

以前、Laravelを利用してSQSメッセージを送信する方法を解説しました。こちらの続きです。

SQSメッセージを送信するだけで機能完了することはほぼ無いことだと思います。メッセージを送信した先で、何らかの処理を実行するために用います。
そこでよく使われるのが、Lambdaです。

SQSメッセージをトリガーにして、Lambdaを起動させるまでを簡潔に解説していきます。

0. GOAL

今回のGOALは、SQSのメッセージ送信をトリガーにして、Lambdaを起動させる。そして、起動したことをCloudWatchで確認。

1. Lambdaを作成

1-1. Lambda関数を新規作成

特別な設定は不要です。 今回、Python3.7 で作成していきます。

1-2. Roleを設定

Roleを設定していきます。 SQSをポーリングして、メッセージを受信できるRoleを設定します。

AWSLambdaSQSQueueExecutionRoleを追加します。

1-3. 関数のコードを設定

import json
def lambda_handler(event, context):
    for record in event['Records']:
       payload=record["body"]
       print(str(payload))

CloudWatchへ、SQSのメッセージを送信するだけなので、record["body"]  をprintする。だけの単純な処理です。

2. SQSメッセージ送信をトリガーに設定する

トリガーをLmabdaに設定します。

  • SQSを選択
  • キューを指定

キューを設定することで、キューにメッセージが受信することをトリガーにLambdaが起動されます。

CloudWatchにSQSメッセージがprintされています。確認してみて下さい。

Q. LambdaはSQSメッセージをどのように判定しているのか.

今回、SQSはメッセージを送信していません。その上で、LambdaではトリガーにSQSのキューを指定しただけです。

結論から言うと、LambdaはSQSのメッセージを定期的に確認しにいってます。これをポーリングと言います。

下記ブログで詳しく書いてありましたので、参照してみて下さい。

実は月額30円の定額課金?SQS⇒lambdaの罠

LaravelでAWS/SQSクライアントを作成し、メッセージを送信

AWSのキューイングサービスであるSQSを利用する方法を解説します。

0. AWSアカウントを作成し、SQSでキューを作成

AWSアカウントの作成方法は省略します。

SQSのキュー作成で、1点だけ注意点です。
キュータイプ標準 で作成して下さい。

1. LaravelにAWS-SDKをインストール

AWS-SDKとは、AWSとのAPI通信を簡素かしたパッケージです。LaravelでAWSを利用する際には、aws-sdk-php-laravel を利用する機会が多いかと思います。

すごい簡単にいうと、AWSとの面倒な認証やあれこれをやってくれる処理郡です。

1-1. composer.json へ aws-sdk-php-laravel を追記

composer.json

{
    "require": {
        //省略
        "aws/aws-sdk-php-laravel": "~3.0"
        //省略
    }
}

1-2. aws-sdk-php-laravel をインストール

composer update を実行する。

composer update

実行が完了すると
/vendor/aws 配下にAWS-SDKがインストールされています。

2. Laravel で SQS クライアントを作成し、メッセージを送信する。

Controllerで、SQSキューにメッセージを送信していきます。まずは、SQSのクライアントを作成します。

2-1. SqsClientを作成する

WebApiControllerのsendSqsメソッドの中で、処理を書いてきます。

<?php

namespace App\Http\Controllers;
use Aws\Sqs\SqsClient;

class WebApiController extends Controller
{
    public function sendSqs()
    {
        $config = [
            'credentials' => [
                'key' => env('AWS_SECRET_ACCESS_KEY'),
                'secret' => env('AWS_ACCESS_KEY_ID'),
            ],
            'region' => 'ap-northeast-1', // ご利用のリージョン
            'version' => 'latest',
        ];
        //SQS Clientを作成
        $sqs = SqsClient::factory($config);
    }
}

SqsClientaws-sdk-php-laravel をインストールした際に一緒に含まれています。

$sqs でSQSのClientを作成出来ました。次に $sqs を利用してメッセージを送信していきます。

2-2. SQSにメッセージを送信

上記で作成したクライアントを利用してメッセージを送信します。

<?php

namespace App\Http\Controllers;
use Aws\Sqs\SqsClient;

class WebApiController extends Controller
{
    public function sendSqs()
    {
        $config = [
            'credentials' => [
                'key' => env('AWS_SECRET_ACCESS_KEY'),
                'secret' => env('AWS_ACCESS_KEY_ID'),
            ],
            'region' => 'ap-northeast-1', // ご利用のリージョン
            'version' => 'latest',
        ];
        //SQS Clientを作成
        $sqs = SqsClient::factory($config);

        // SQSのメッセージ
        $value = "piyo";

        // 送りたいSQSのURLを指定
        $sqs_url = env('AWS_SQS_URL');

        $params = [
            'DelaySeconds' => 0,
            'MessageBody' => $value,
            'QueueUrl' => $sqs_url,
        ];

        $result = $sqs->sendMessage($params);
    }
}

上記で、SQSのキューにメッセージを送信出来ます。

Q. SQSのURLはどこにある?

$sqs_url = env('AWS_SQS_URL');

こちらに SQSのURLを設定する必要があります。

それは、キューの画面へいくと確認出来ます。

以上です。

Sequel Aceでcopy with column nameが操作出来ない問題

SQLクライアントサービスは何を使っていますでしょうか。
Macであれば、Sequel Ace が非常に使い勝手が良いかと思います。

SQL書き出しした後に、データと一緒にカラム名も一緒にコピーしたいことがあるかと思います。 デフォルト機能でカラムと一緒にコピーが可能です。

しかし、グレースケールしており、選択出来ない状態となっていました。

そこで、解決方法としては、ショートカットを利用するとコピー出来ましたので紹介します。

下記にてCopy selected row(s) with column namesの機能が使えます。

⌥ ⌘ C

SequelAceショートカットはこちらに様々ありましたので、ご確認頂けたらと思います。

SQLのインデックス確認方法 / インデックス対象のカラム

SQLのパフォーマンスを向上させたい場合に、重要な変数であるインデックス。インデックスを作成してパフォーマンス向上していく場合もあるかと思います。

それらを確認する方法を解説します。

show index from テーブル名;

非常にシンプルです。

Q デフォルトで存在するインデックス

出力されたデータを確認頂けると注目して頂きたいのは、Key_nameです。

まず、必ずインデックスがついているのが、PRIMARY KEYです。
デフォルトだと、Tableのidに該当します。

また、PRIMARY KEYでなくても、インデックスが存在している場合があります。
それは、他のTableのPRIMARY KEYに紐付いている外部キー カラムです。

下記2カラムは、
インデックスを作成しなくても、デフォルトでインデックスとなっています。

  • PRIMARY KEY
  • PRIMARY KEYに紐付いている外部キー カラム

git was not found in your PATH, skipping source download / Failed to download laravel/laravel from dist: The zip extension and unzip/7z commands are both missing, skipping

標題にerror文を貼り付けました。ターミナル上でのerror表記は下記です。

■error発生の状況

DockerFileコンテナを起動した後に、Laravelをインストールした際に発生。
Laravel InstallはComposerを利用. 下記。

composer create-project laravel/laravel:^8.0 app

■error原因

・unzip ライブラリが存在せず、Laravelをdownloadして来れなかった。
・gitを経由してLaravelをダウンロードしようとしたが、git ご存在していなかった。

■解決策

1:unzip をinstall

Run apt-get install -y unzip

2:git をinstall

Run apt-get install -y git

どちらを片方で問題ありません。
1を選択すれば、直接ダウンロード。2を選択すれば、git経由でダウンロード。
gitをコンテナの中に入れる必要も無いと思うので、個人的には1がオススメです。

Docker環境構築 / Vue.jsをさくっと起動させるまで.

ディレクトリ構成

/Vue-Test
 L Dockerfile
 L docker-compose.yml

①:Dockerfile/docker-compose ファイルを準備

①-1:Dockerfile
FROM node:17-alpine3.14

WORKDIR /work

RUN apk update && \
    npm install -g npm && \
    npm install -g @vue/cli

EXPOSE 8080
ENV HOST 0.0.0.0
①-2:docker-compose.yml
version: '3'
services:
  vue:
    container_name: vue
    build: 
      context: .    
      dockerfile: ./Dockerfile
    ports:
      - "8080:8080"
    volumes:
      - ./server:/work:delegated      
    tty: true

②:docker コンテナの起動

②-1:ディレクトリに移動

cd Vue-Test

②-2:コンテナ起動

docker-compose up -d

③:コンテナに入り、Vueプロジェクトを作成

③-1:コンテナへ移動

docker-compose vue exec vue sh

③-2:Vueプロジェクトを作成

first-app 名称でプロジェクトを作成

vue create first-app

③-3:Vueのバージョンを選択

Default ([Vue 3] babel, eslint) 
❯ Default ([Vue 2] babel, eslint) 

③-4:package manageを選択

Use Yarn 
❯ Use NPM

これでインストールが開始します。

④:プロジェクトの起動

④-1:プロジェクトへ移動

cd first-app

④-2:serve

npm run serve

⑤:ブラウザで確認

下記へアクセスして、確認して下さい。

http://localhost:8080/

ACM,ALB,Route53を活用してSSL化する.httpsのリダイレクトも.| AWS

標題の通りです。ご自身で取得したドメインをSSL化したい場合の一連の流れと作業を解説していきます。ちなみに、自分はお名前ドットコムでドメイン取得をしております。

■前提

・httpによるアクセスが出来ている環境であること.
・AWSを利用して、サーバー構築していること.

0:ACM,ALB,Route53各サービスの役割

初めに、各サービスの相互役割を解説して、全体の流れを解説していきたいと思います。

Route53の役割:

・ドメインのDNSレコードの作成
・ルーティング先をALBへ指定(ドメインアクセス後にALBへ)

ACMの役割:

・SSL化に必要な証明証の発行

ALBの役割:

・httpsアクセスに対して、ACMで発行した証明証を基にSSL化
・Target(今回はEC2インスタンス)へ、転送
・httpアクセスに対して、httpsへリダイレクト

①:ドメインの取得

ご自身でドメイン取得をして下さい。自分はお名前ドットコムでドメイン取得しております。

②:ACMで証明証発行

AWS Certificate Manager > 証明書 @ リクエスト

・「パブリック証明証をリクエスト」を選択
・完全修飾ドメイン名 (FQDN): {{ご自身で取得したドメインを指定}}

これで、証明証を発行します。

③:Route53レコードの設定

③-1:ホストゾーンの作成

Route 53 > ホストゾーン @ ホストゾーンの作成

・ドメイン名: {{ご自身で取得したドメインを指定}}
・パブリックホストゾーンを選択

これで、ホストゾーンを作成します。

③-2:NSレコードを、ドメイン購入サイトに反映

下記サイトなどで手順を参考に。

https://dev.classmethod.jp/articles/route53-domain-onamae/
https://blog.i-tale.jp/2020/04/13_02/

③-3:CNAMEレコードを、ACMからから作成

③-3-1:CNAMEレコードとは.

CNAMEは、ドメイン名と別ドメイン名をつけることができる。
つまり違うドメイン名で、同じ動きをしてくれます。

③-3-2:ACMから、Route53のCNAMEを作成

AWS Certificate Manager > 証明書 > ②で作成した証明証へ

Route53でレコード作成

③で作成している、Route53を選択して下さい。

④:ALBでSSL化 / ターゲットグループへの転送(EC2) / httpからのリダイレクト

④-1:ロードバランサーの作成

EC2 > ロードバランサー @ ロードバランサーの作成

Create Application Load Balancer

Basic configuration

名前を自由を設定にして、basic 情報を設定。

VPCを選択します。

今回のターゲットグループとなる、EC2インスタンスが設置してあるVPCを選択します。
※少なくとも2つ以上のアベイラビリティゾーンを追加して下さいとのことです。

リスナーを設定

・HTTPSプロトコル、443ポートで受けます。
・Forward to にターゲットグループを設定します。今回の場合は、EC2インスタンスを含まれるターゲットグループを指定
・secure listenerを From ACMで「②で作成したACMを指定」

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

今回作成するセキュリティグループは、ALBへのセキュリティグループです。HTTPS・HTTPどちらもインバウンドを許可します。
※HTTPに対するリダイレクト処理は下記で紹介。

④-2:httpからのアクセスをhttpsへリダイレクト

設定方法を下記記事にて解説しています。

⑤:Route53で、Aレコードの設定

④で作成したALBを、Route53でAレコードをしていきます。

⑤-1:Aレコードとは.

ドメインをIPアドレスへ変換します。
ドメインへのリクエストが合った際のルート先を指定することができます。
今回はリクエストが合った際に、ALBを指定することで、SSL化を実行しています。

⑤-2:設定

・レコードタイプ:A
・エイリアス:オン
・ルーティング先:ALB >> ap-northeast-1(ご自身のリージョン)>>{{④で作成した、ALBを指定}}

[AWS|ALB]http→httpsへリダイレクトの設定

SSL化した後に、httpでのアクセスが可能 OR httpではアクセスが不可の状態が発生することで、httpへのアクセスを全てhttpsへリダイレクトしたい機会があると思います。 AWSのALBを利用して、設定していきます。

■前提

AWSのALBにて、ロードバランサー経由でWebサーバーへ接続をしている場合に限る。

ロードバランサーの設定

EC2 >> ロードバランサー >> リスナー

「リスナーの追加」をします。

すると下記の、追加設定画面が出てきますので。
・httpを80ポートで受けて
・リダイレクトをfull URLで設定

これで、htttp → https化へリダイレクトします。

dockerコンテナ内で生成したファイルを、ホスト(PC)へDL(連携)する方法

dockerコンテナ内でpythonのライブラリをinstallし、そのライブラリをzip化。 そして、そのzipファイルをホスト環境(ローカルPC)へ連携することを実現します。

①:phpのライブラリをinstallするdockerコンテナ環境を構築

ファイル構成

/ 
 L Dockerfile
 L entrypoint.sh
Dockerfile
FROM python:3.7

RUN apt-get update && apt-get install -y zip unzip

#pipでinstallしたいディレクトリ$$パッケージを指定&&インストール
RUN pip install --target ./python google-api-python-client google-auth requests-oauthlib

ADD entrypoint.sh /
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

・imageのベースはphp 3.7をpullしてきています。
・pip install で installしたいライブラリを。※今回zipファイルで連携したいライブラリ郡です。
・entrypoint.shをコンテナ上に追加・コンテナでの操作権限を付与して、コンテナで上で、コンテナ上でコマンド実行可能な状態を作る。(コマンドの具体は、entrypoint.shに記載)
・ENTRYPOINTに /entrypoint.shを指定して、コンテナ起動後の実行を指定

②:ライブラリをZip化 / entrypoint.shにてコードで実行

entrypoint.sh
!/bin/bash -eu
 SRC=/python
 DIST=/dist/layer.zip
 zip -q -r ${DIST} ${SRC}
 /bin/bash

・コンテナ上の/python ディレクトリをzip化して、 DISTで指定したディレクトリ位置へ
・コンテナ内を確認するために、 /bin/bash を起動させる。

・DIST=/dist/layer.zip というdistディレクトリが突然現れました。これは、後に、run する際にバインドマウントする際に連携するディレクトリです。※詳細は下記

③:バインドマウントをして、dockerコンテナとホストを連携

docker build でimageを作成

docker build . -t {imageのnameを指定}

docker run で コンテナ起動 &&

docker run --rm -v $(pwd):/dist -it {imageのname}

rm:終了後、コンテナ削除

今回の処理の一番重要な部分は、

-v $(pwd):/dist 

ここです。

ここのバインドマウントの処理によって、
$(pwd):ホストの現在のディレクトリ

/dist :コンテナ上の distディレクトリ
を連携しています。
※FROM python:3.7にはdistは存在しないので、このタイミングで自動生成される。

この後、
>>②:ライブラリをZip化 / entrypoint.shにてコードで実行

>> zip -q -r ${DIST} ${SRC} の処理によって
dist へLayer.zipが生成されています。

④:ホスト環境 / dockerコンテナ環境で確認

④-1:ホスト環境を確認

ファイル構成

/ 
 L Dockerfile
 L entrypoint.sh
 L Layer.zip

上記のようになってると思います。

④-2:dockerコンテナ環境を確認

/bin/bashでコンテナを起動していると思いますので、コンテナの中身を確認していきましょう。

distディレクトリに移動して、その中で空のディレクトリを生成してみて下さい。

cd dist && mkdir gogo

そうすると、コンテナ上の/dist/gogoディレクトリが生成されます。

それと同時に、ホスト環境でも下記のようになっていると思います。

/ 
 L Dockerfile
 L entrypoint.sh
 L Layer.zip
 L gogo

⑤:バインドマウント

https://matsuand.github.io/docs.docker.jp.onthefly/storage/

バインドマウントを利用する際の副作用として、これが良いことか悪いことかはわかりませんが、コンテナー 内に動作するプロセスを通じて ホスト のファイルシステムに変更がかけられるということです。 たとえばシステムにとって重要なファイル、ディレクトリを生成、編集、削除ができてしまいます。 セキュリティに影響を及ぼしかねない強力な能力がここにあって、ホストシステム上の Docker 以外のプロセスへも影響します。