- 投稿日:2021-01-17T22:12:20+09:00
AWS_WEB3層環境構築②
前回の記事
https://qiita.com/shinichi_yoshioka/items/7226b9ebaad06c569c80
前回の続きをやっていく。
APサーバとDBサーバはプライベートサブネットに構築する。
プライベートサブネット配置のEC2インスタンス作成にあたって、
"パブリックIP自動割り当てを無効"にしたが
TomcatやMySQLをインストールするのに一時的にインターネットに繋ぎたい。
そもそもプライベートサブネット配置のEC2インスタンスにssh接続できなくて詰んでいる。
対処法を調べたところ、3通りぐらい把握した。
①ElasticIP(EIP)を一時的に割り当て →これは実質パブリックサブネットと変わらない。
②前回構築したWEBサーバを踏み台としてアクセスする →SSH接続はできるが、TomcatやMySQLをインストールするのに面倒。
③NATゲートウェイをパブリックサブネットに配置する →これが一番良いやり方。ちなみにNATゲートウェイの料金は、東京リージョンで1hあたり0.062USDらしい。
https://aws.amazon.com/jp/vpc/pricing/
施行錯誤の環境構築で時間がかかると思ったので、今回はEIPを使い、一時的にパブリック化する方法を選んだ。
(2台目のDBサーバを構築する際は、NATゲートウェイを使おうと思う)
EIPはAWSアドレスプールから払い出される固定のパブリックIPのこと。
セキュリティグループも一時的に開けないとダメだし、ルートテーブルもインターネットゲートウェイへ向ける。
構築が落ち着いたら、封鎖するので許してほしい。◆EIPの作成とアタッチ
サービス[VPC]のElasticIPから[Elastic IPアドレスの割り当て]から、
AmazonのIPv4アドレスプールから割り当てを行う。
割り当てられたアドレスをクリックすると、EC2インスタンスに関連付けできる。
ちなみにEIPはEC2インスタンスにアタッチ中は課金されないが、
EIPの払い出しだけしていてEC2にアタッチされていないと課金されるらしい。
ここでは、APサーバとDBサーバそれぞれにEIPを割り当てる。
こんな感じ。
とりあえず、各EC2インスタンスにSSH接続できることは確認した。
AP/DBサーバの構築後処理は以下。
①EIPをデタッチし、EIPを解放
②ルートテーブルからインターネットゲートウェイを削除し、最低限に絞る
③セキュリティグループを必要なプロトコルのみに絞る◆Nginxのインストール
対象:WEBサーバ
sudo su -
yum update -y
yum install nginx -y
ここでエラーが。
どうやら、AmazonLinuxはインストール方法が違うらしい。
以下コマンドでインストールが開始されたことを確認した。
amazon-linux-extras install nginx1 -y
Nginxの自動起動を有効化にし、サービスを起動。
ステータスがactive(running)になっていることを確認した。
systemctl enable nginx.service
systemctl start nginx.service
systemctl status nginx.service
ブラウザに以下のように入力し、Nginxのテストページが表示されることを確認した。
http://WEBサーバのパブリックアドレス◆Tomcatのインストール
対象:APサーバ
sudo su -
yum update -y
yum install tomcat -y
systemctl enable tomcat.service
systemctl start tomcat.service
systemctl status tomcat.service
tomcatのサービスは正常に動いているが、Web App Containerとしての正常性確認のやり方が不明(調べ中)
過去に自宅VirtualBoxにTomcatを入れて正常性確認をしたが、これはApache Tomcat(WEBサーバ)であって
上記のWeb App Containerとは違う認識。
◆MySQLのインストール
対象:DBサーバ
sudo su -
yum update -y
yum install mysql -y
Mysqlをインストールしようとしたら、MariaDBが入ったのだが・・・。
他のEC2インスタンスを確認したところ、Amazon Linuxにはデフォルトでmariadb-libs-5.5.68-1.amzn2.x86_64が入っていて
MySQL互換のMariaDBをインストールしてしまった。
MySQLとMariaDBで競合をおこさないようにアンインストールしておく。
yum remove mariadb-libs -y
rpm -qa | grep -i maria
何も表示されないことを確認した。次にMySQLをyumでインストールするため、MySQL公式のリポジトリを追加した。
yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm -y
yum info mysql-community-server
にて、MySQLのyumリポジトリ追加を確認。
yum -y install mysql-community-server
mysqld --version
にてMySQLのインストールを確認。
他のサービスと同様にmysqld.serviceが正常に動いていることを確認した。
systemctl enable mysqld.service
systemctl start mysqld.service
systemctl status mysqld.service
MySQLのrootユーザの初期パスワードは、/var/log/mysqld.logに記載されている。
cat /var/log/mysqld.log | grep temporary
一時的なパスワードなので、rootユーザにログイン後に任意のパスワードに変える。
mysql -u root -p
白塗りの一時パスワードを入力し、rootユーザにログイン。
set password for root@localhost=password('ここに新しいパスワード');
Query OKと出れば変更完了だが、初期のパスワードポリシーが結構厳しめで
パスワードは大文字・小文字・数字・記号とかにしないとはじかれると思う。
パスワード変更後はいったんMySQLから抜けて、新パスワードでログインできることを確認した。
長くなってしまったので、第2回はここまで。
久々に有意義な休日を過ごせたと思う。(いつもはゲームして、YouTube見て、見てるうちに寝ちゃって1日終わる)
次回は、APサーバにMySQLドライバーを入れて、WEBサーバとAPサーバとDBサーバを連携したい。
イメージでは、WEBサーバのnginx.confにリバースプロキシの設定を入れて、
Tomcatのserver.xmlにDBサーバのアドレスを記載すれば
連携できるのではないかと思っている。
正直ここから先は何もわかっていないので、次回の記事は結構先になりそうだ。
- 投稿日:2021-01-17T21:29:12+09:00
Warning: Illegal string offset ' ' in... の解決方法
今回は、SQLから取得したデータをsmartyを使って、foreachでtable表示させようとした際に発生したエラーが解決した方法をご紹介します。
発生したエラー
Warning: Illegal string offset '出力変数の各カラム名' in...下記のサイトを参考に解決したのですが、全て英語で書かれた記事なので、正直正確なエラー発生の原因がわかっていません。
どなたか詳しい原因が分かる方いましたらコメントにて教えて頂けると幸いです。
私の場合は、どうやら出力変数のキーを文字列で指定していた為に発生したようです。エラーが発生したコードと修正コード
list2.php(データ取得)修正前
<?php require_once('../db_connect2/db_connect2.php'); require( dirname( __FILE__ , 3).'/libs/Smarty.class.php' ); $smarty = new Smarty(); $smarty->template_dir = dirname( __FILE__ , 3).'/templates'; $smarty->compile_dir = dirname( __FILE__ , 3).'/templates_c'; $smarty->config_dir = dirname( __FILE__ , 3).'/configs'; $smarty->cache_dir = dirname( __FILE__ , 3).'/cache'; $smarty->escape_html = true; try { $sql = 'SELECT stock_id,purchase_date,deadline,stock_name,price,number FROM stocks WHERE 1'; $stmt = connect()->prepare($sql); $stmt->execute(); $rec = $stmt->fetch(PDO::FETCH_ASSOC); //ここで、結果セットに返された際のカラム名で添字を付けた配列を返したことが原因。 $dbh = null; } catch(Exception $e) { echo "エラー発生:" . htmlspecialchars($e->getMessage(),ENT_QUOTES, 'UTF-8') . "<br>"; print'ただいま障害により大変ご迷惑をお掛けしております。'; exit(); } $smarty->assign('stock', $rec); $smarty->display('list.tpl'); ?>修正コード
try { $sql = 'SELECT stock_id,purchase_date,deadline,stock_name,price,number FROM stocks WHERE 1'; $stmt = connect()->prepare($sql); $stmt->execute(); $rec = $stmt->fetch(PDO::FETCH_ASSOC); //ここで、結果セットに返された際のカラム名で添字を付けた配列を返したことが原因。 $dbh = null; } ↓ try { $sql = 'SELECT stock_id,purchase_date,deadline,stock_name,price,number FROM stocks WHERE 1'; $stmt = connect()->prepare($sql); $stmt->execute(); $dbh = null; }list.tpl(出力)修正前
<table class = "sorttbl" id = "myTable" border = "2"> <tr> <th class = "radio-th"></th> <th class = "purchase_date-th">購入日</th> <th class = "stock_name-th">商品</th> <th class = "price-th">値段</th> <th class = "number-th">数量</th> <th class = "deadline-th" onclick = "w3.sortHTML('#myTable','.item', 'td:nth-child(6)')">消費期限 <i class = "fa fa-sort"></i></th> </tr> //出力変数のキーを文字列で指定しているのが原因 {foreach $stock as $s} <tr class = "item"> <td><input type = "radio" name = "stockid" value = "{$s.stock_id}"></td> <td>{$s.purchase_date|date_format:'%Y-%m-%d'}</td> <td>{$s.stock_name}</td> <td>¥{$s.price}</td> <td>{$s.number}</td> <td>{$s.deadline|date_format:'%Y-%m-%d'}</td> </tr> {/foreach} </table>修正コード
{foreach $stock as $s} <tr class = "item"> <td><input type = "radio" name = "stockid" value = "{$s.stock_id}"></td> <td>{$s.purchase_date|date_format:'%Y-%m-%d'}</td> <td>{$s.stock_name}</td> <td>¥{$s.price}</td> <td>{$s.number}</td> <td>{$s.deadline|date_format:'%Y-%m-%d'}</td> </tr> {/foreach} ↓ {foreach $stock as $s} <tr class = "item"> <td><input type = "radio" name = "stockid" value = "{$s[0]}"></td> <td>{$s[1]|date_format:'%Y-%m-%d'}</td> <td>{$s[3]}</td> <td>¥{$s[4]}</td> <td>{$s[5]}</td> <td>{$s[2]|date_format:'%Y-%m-%d'}</td> </tr> {/foreach}
- 投稿日:2021-01-17T19:33:54+09:00
Dockerでapache7.4+mysql8環境構築(初期データ入り)
今更ですが、Macで表題の環境を作らなくてはいけなくなったので、構築してみました。
備忘録として書いておきます。環境
マシン macOS Catalina 10.15.7
構成
ファイル、ディレクトリの構成はざっくりと以下のようにします。
任意のディレクトリ │ ├── docker-compose.yml │ ├── html/ │ └── index.html │ ├── mysql/ │ ├── Dockerfile │ ├── data/ │ ├── init/ │ │ └── init.sql │ └── my.cnf │ ├── php-apahce/ ├── Dockerfile └── php.iniこの構築の重要な部分
docker-compose.ymlとDockerfileがこの構築の重要な部分になります。
ファイル名 説明 docker-compose.yml コンテナの構成を定義するもの。コンテナ間通信の定義もできる。 Dockerfile dockerのイメージに対する定義。 docker-compose.ymlの要素
調べて自分が認識している限りだと以下の通り
名称 意味 build Dockerfileがある位置を指定 volumus ローカル内のマウントされる場所:コンテナ内のマウントする場所 ports ポートフォワード container_name コンテナの名前 docker container lsのname environment 環境変数?変数名で何を意味するかがなんとなくわかる Dockerfileの要素
調べて自分が認識している限りだと以下の通り
名称 意味 FROM 何をどのバージョンで EXPOSE どのポートを使用するか ADD ローカルファイルをコンテナ内ファイルに追記 CMD コンテナ起動時に実行されるやつ COPY ローカルファイルをコンテナ内ディレクトリにコピーする RUN イメージ作成時に呼ばれるやつ。なのでパッケージのインストール等を書く。 構築
本編はここからです。
確認
まずコンテナの状態確認
ksk@ksknoMacBook-Pro work % docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES何もいません
./docker-compose.yml
docker-compose.ymlとは、コンテナの構成を定義するファイル
docker-compose.ymlversion: '3' services: php-apache: build: ./php-apache/ volumes: - ./html:/var/www/html ports: - 8080:80 container_name: web mysql: build: ./mysql/ volumes: - "./mysql/data:/var/lib/mysql" - "./mysql/init:/docker-entrypoint-initdb.d" environment: - MYSQL_ROOT_PASSWORD=docker - MYSQL_DATABASE=mydb - MYSQL_USER=appuser - MYSQL_PASSWORD=appuser1 container_name: db ports: - 3306:3306ymlに書いている属性?で、自分が理解していることを以下の表に書いてみる
(間違っているところを指摘してくれる優しい人いたら教えてください)./html/index.php
動作確認するために使用。
とりあえず、DBのデータを表示できれば良しとする。
volumesの定義により、htmlがドキュメントルートとなる。index.php<?php try { $db = sprintf('mysql:host=%s:3306;dbname=%s', 'mysql', 'mydb'); $dbh = new PDO($db, 'appuser', 'appuser1'); foreach($dbh->query('select * from users') as $row) { echo $row['name'] . '<br>'; } $dbh = null; } catch (PDOException $e) { echo $e; die(); } $dbh = null;hostの指定で「'mysql'」としていますが、これはdocker-compose.ymlのservice名と理解しています。
docker-compose.ymlmysql: ←これ!!! build: ./mysql/ volumes:./mysql/Dockerfile
mysql側のDockerfile
DockerfileとはDockerイメージの定義を書くファイルです。FROM mysql:8.0 EXPOSE 3306 ADD ./my.cnf /etc/mysql/conf.d/my.cnf CMD ["mysqld"]./mysql/init/init.sql
適当なテーブルとデータを詰め込むような記述にしておく
use mydb; CREATE TABLE users ( id int(10) unsigned not null auto_increment, name varchar(255) not null, primary key (id) ); insert into users(name) values('hogeo'); insert into users(name) values('fugao');./mysql/my.cnf
my.cnf[mysqld] character-set-server=utf8 default_authentication_plugin=mysql_native_password [mysql] default-character-set=utf8 [client] default-character-set=utf8default_authentication_plugin=mysql_native_passwordについて
mysqlのデフォルト認証プラグインが変わったので、デフォルトの認証プラグインを変更しています。
mysqlの環境変数でユーザ(appuser)作っていますが、mysql_native_passwordという認証プラグインで設定されます。
デフォルトのままだと、phpがmysqlへのアクセスで失敗します。./php-apache/Dockerfile
色んなサイトを見て参考にさせてもらいました。
FROM php:7.4-apache COPY ./php.ini /usr/local/etc/php/ RUN apt-get update RUN apt-get install -y zip unzip vim libpng-dev libpq-dev RUN docker-php-ext-install pdo_mysql./php-apache/php.ini
色んなサイトを見て参考にさせてもらいました。
[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"docker-compose build
上記を作った後、docker-compose.ymlと同階層で以下のコマンド実行
ksk@ksknoMacBook-Pro work % docker-compose build 〜〜〜中略〜〜〜 Successfully built e5b1c15e825e Successfully tagged work_php-apache:latest Building mysql Step 1/4 : FROM mysql:8.0 ---> d4c3cafb11d5 Step 2/4 : EXPOSE 3306 ---> Using cache ---> e11d55e213ab Step 3/4 : ADD ./my.cnf /etc/mysql/conf.d/my.cnf ---> Using cache ---> 6dd70a6b7ecd Step 4/4 : CMD ["mysqld"] ---> Using cache ---> c22190479ddf Successfully built c22190479ddf Successfully tagged work_mysql:latestコンテナ作成&起動
ksk@ksknoMacBook-Pro work % docker-compose up -d Creating web ... done Creating db ... done確認
コンテナの状態確認
ksk@ksknoMacBook-Pro work % docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b416b97d3f7b work_mysql "docker-entrypoint.s…" 2 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp db 9985abb2eb90 work_php-apache "docker-php-entrypoi…" 2 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp webコンテナが確認できました
画面確認
http://localhost:8080
こちらへアクセス以上!
- 投稿日:2021-01-17T19:33:54+09:00
Dockerでapache7.4+mysql8環境構築(初期データ入り)(自分メモ)
今更ですが、Macで表題の環境を作らなくてはいけなくなったので、構築してみました。
備忘録として書いておきます。環境
マシン macOS Catalina 10.15.7
構成
ファイル、ディレクトリの構成はざっくりと以下のようにします。
任意のディレクトリ │ ├── docker-compose.yml │ ├── html/ │ └── index.html │ ├── mysql/ │ ├── Dockerfile │ ├── data/ │ ├── init/ │ │ └── init.sql │ └── my.cnf │ ├── php-apahce/ ├── Dockerfile └── php.iniこの構築の重要な部分
docker-compose.ymlとDockerfileがこの構築の重要な部分になります。
ファイル名 説明 docker-compose.yml コンテナの構成を定義するもの。コンテナ間通信の定義もできる。 Dockerfile dockerのイメージに対する定義。 docker-compose.ymlの要素
調べて自分が認識している限りだと以下の通り
名称 意味 build Dockerfileがある位置を指定 volumus ローカル内のマウントされる場所:コンテナ内のマウントする場所 ports ポートフォワード container_name コンテナの名前 docker container lsのname environment 環境変数?変数名で何を意味するかがなんとなくわかる Dockerfileの要素
調べて自分が認識している限りだと以下の通り
名称 意味 FROM 何をどのバージョンで EXPOSE どのポートを使用するか ADD ローカルファイルをコンテナ内ファイルに追記 CMD コンテナ起動時に実行されるやつ COPY ローカルファイルをコンテナ内ディレクトリにコピーする RUN イメージ作成時に呼ばれるやつ。なのでパッケージのインストール等を書く。 構築
本編はここからです。
確認
まずコンテナの状態確認
ksk@ksknoMacBook-Pro work % docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES何もいません
./docker-compose.yml
docker-compose.ymlとは、コンテナの構成を定義するファイル
docker-compose.ymlversion: '3' services: php-apache: build: ./php-apache/ volumes: - ./html:/var/www/html ports: - 8080:80 container_name: web mysql: build: ./mysql/ volumes: - "./mysql/data:/var/lib/mysql" - "./mysql/init:/docker-entrypoint-initdb.d" environment: - MYSQL_ROOT_PASSWORD=docker - MYSQL_DATABASE=mydb - MYSQL_USER=appuser - MYSQL_PASSWORD=appuser1 container_name: db ports: - 3306:3306ymlに書いている属性?で、自分が理解していることを以下の表に書いてみる
(間違っているところを指摘してくれる優しい人いたら教えてください)./html/index.php
動作確認するために使用。
とりあえず、DBのデータを表示できれば良しとする。
volumesの定義により、htmlがドキュメントルートとなる。index.php<?php try { $db = sprintf('mysql:host=%s:3306;dbname=%s', 'mysql', 'mydb'); $dbh = new PDO($db, 'appuser', 'appuser1'); foreach($dbh->query('select * from users') as $row) { echo $row['name'] . '<br>'; } $dbh = null; } catch (PDOException $e) { echo $e; die(); } $dbh = null;hostの指定で「'mysql'」としていますが、これはdocker-compose.ymlのservice名と理解しています。
docker-compose.ymlmysql: ←これ!!! build: ./mysql/ volumes:./mysql/Dockerfile
mysql側のDockerfile
DockerfileとはDockerイメージの定義を書くファイルです。FROM mysql:8.0 EXPOSE 3306 ADD ./my.cnf /etc/mysql/conf.d/my.cnf CMD ["mysqld"]./mysql/init/init.sql
適当なテーブルとデータを詰め込むような記述にしておく
use mydb; CREATE TABLE users ( id int(10) unsigned not null auto_increment, name varchar(255) not null, primary key (id) ); insert into users(name) values('hogeo'); insert into users(name) values('fugao');./mysql/my.cnf
my.cnf[mysqld] character-set-server=utf8 default_authentication_plugin=mysql_native_password [mysql] default-character-set=utf8 [client] default-character-set=utf8default_authentication_plugin=mysql_native_passwordについて
mysqlのデフォルト認証プラグインが変わったので、デフォルトの認証プラグインを変更しています。
mysqlの環境変数でユーザ(appuser)作っていますが、mysql_native_passwordという認証プラグインで設定されます。
デフォルトのままだと、phpがmysqlへのアクセスで失敗します。./php-apache/Dockerfile
色んなサイトを見て参考にさせてもらいました。
FROM php:7.4-apache COPY ./php.ini /usr/local/etc/php/ RUN apt-get update RUN apt-get install -y zip unzip vim libpng-dev libpq-dev RUN docker-php-ext-install pdo_mysql./php-apache/php.ini
色んなサイトを見て参考にさせてもらいました。
[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"docker-compose build
上記を作った後、docker-compose.ymlと同階層で以下のコマンド実行
ksk@ksknoMacBook-Pro work % docker-compose build 〜〜〜中略〜〜〜 Successfully built e5b1c15e825e Successfully tagged work_php-apache:latest Building mysql Step 1/4 : FROM mysql:8.0 ---> d4c3cafb11d5 Step 2/4 : EXPOSE 3306 ---> Using cache ---> e11d55e213ab Step 3/4 : ADD ./my.cnf /etc/mysql/conf.d/my.cnf ---> Using cache ---> 6dd70a6b7ecd Step 4/4 : CMD ["mysqld"] ---> Using cache ---> c22190479ddf Successfully built c22190479ddf Successfully tagged work_mysql:latestコンテナ作成&起動
ksk@ksknoMacBook-Pro work % docker-compose up -d Creating web ... done Creating db ... done確認
コンテナの状態確認
ksk@ksknoMacBook-Pro work % docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b416b97d3f7b work_mysql "docker-entrypoint.s…" 2 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp db 9985abb2eb90 work_php-apache "docker-php-entrypoi…" 2 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp webコンテナが確認できました
画面確認
http://localhost:8080
こちらへアクセス以上!
- 投稿日:2021-01-17T19:05:10+09:00
AWS Lambdaでコンテナデプロイする方法
はじめに
随分前になりますが、AWS Lambdaでコンテナデプロイがサポートされました。
AWS Lambda now supports container images as a packaging format今回は、AWS Lambdaにコンテナのイメージをデプロイする方法について紹介します!
対象
- AWS Lambdaの新機能について知りたい人
- コンテナデプロイの流れを知りたい人
YouTube動画
動画で確認したい方は、こちらを利用ください!
*撮影は1ヶ月以上前のものですが、大きく変わったところはありません。
【YouTube動画】実践! Lambdaでコンテナデプロイをする方法!!
コンテナのデプロイ条件
Lambdaに、コンテナデプロイがサポートされましたが、コンテナなら何でも良いという訳ではありません。
AWSが提供しているLambda用のRuntime APIに準拠している必要があり、以下のいずれかの方法でコンテナを作る必要があります。方法1: AWS提供のベースイメージを使う 方法2: Runtime APIが入っているイメージを使う以下のサイトから使いたいランタイムを選択して、利用できます。
Runtime support for Lambda container images具体例
今回はベースイメージを利用して、実際にLambdaにコンテナデプロイしてみます。
まず、簡単なNode.jsのサンプルを確認して、次に実践的なRubyのサンプルを見ていきます。Node.jsのサンプル
簡単なサンプルを書くとこのようになります。
# ベースイメージの取得 FROM public.ecr.aws/lambda/nodejs:12 # Lambda関数を定義しているapp.jsをLambda実行時のルートディレクトリに置く COPY app.js ${LAMBDA_TASK_ROOT} # app.jsのhandler関数を実行 CMD [ "app.handler" ]Rubyのサンプル
このサンプルはLambdaからMySQLに接続するためのLambda関数を作ります。
コンテナをサポートする前は、native extenstion関連で面倒な手順が必要でしたが、コンテナをサポートしたことで簡単に使えるようになりました。FROM amazon/aws-lambda-ruby:2.7 WORKDIR ${LAMBDA_TASK_ROOT} # MySQL関連で依存しているものをインストール RUN yum install -y mysql-devel gcc-c++ make COPY . ${LAMBDA_TASK_ROOT} RUN bundle config --global silence_root_warning 1 RUN bundle config set path 'vendor/bundle' RUN bundle install CMD ["app.App::Handler.process"]ローカルでLambdaを動かす
コンテナ化したことで、ローカルで実際に試すことができます。
9000番ポートを開放して試したい場合は次のようにします。
docker run -p 9000:8080 <image name>
そして、以下のようにPOSTすることで、実際に確認できます。
ここでの、/2015-03-31/functions/function/invocations"
は固定です。curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" \ -d '{"payload":"hello world!"}'デプロイ
まずはコンテナイメージをAmazon ECRにデプロイする必要があります。
今回は割愛します。以下が詳しいです。
Docker イメージをプッシュするLambdaの関数の作成方法を確認すると、コンテナイメージという項目ができているので、そちらを選択して使います。
まとめ
今回はAWS Lambdaにコンテナをデプロイする方法について解説しました。
この記事を通してざっくり理解していただくと、自分で設定する時にスムーズだと思います。また、AWS Lambdaでコンテナを使った場合は、最初の起動で2 ~ 5秒程度かかってしまいますが、それ以降はスムーズに起動します。
AWS Lambdaの利用の幅が広がる新機能なので、ぜひ遊んでみてください!
- 投稿日:2021-01-17T15:42:55+09:00
MYSQLコマンド
ポスグレとごっちゃになってしまっているので、まとめてみました。
テーブル作成
mysql> CREATE DATABASE `testtable`;テーブル確認
show databases();結果
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql_test | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec)このような表記が出る。
現在接続しているDBの確認
mysql> SELECT database();DB接続
mysql> use mysql_test; Database changedテーブル作成
mysql > CREATE TABLE テーブル名(カラム名 データ型, カラム名 データ型)テーブルの確認
mysql > show tables;テーブルにデータをロードする
INSERT INTO テーブル名 VALUES (カラム1, カラム2, カラム3)複数入れる場合
mysql > INSERT INTO pokemon VALUES (1, 'Andy', 35 , America, 'Ramen') ,(2, 'Betty', 26, Canada, 'Sushi') ,(3, 'Carol', 21, America, 'Sushi')データを削除
DELETE FROM テーブル名テーブルを削除
mysql > DROP FROM テーブル名;DBを消す
mysql > DROP DATABASE データベース名;テーブルのデータ検索
SELECT * FROM テーブル名;必要なカラムの値を検索
SELECT カラム名1, カラム名2 FROM テーブル名;条件を指定してデータを検索
SELECT * FROM テーブル名 WHERE 条件文;例
mysql> SELECT * FROM user WHERE food = 'Sushi'; +------+---------------+---------------------------+------------------------+ | id | name | country| Food | +------+---------------+---------------------------+------------------------+ | 1 | Betty | America| Sushi | | 7 | Yusuke | Japan | Sushi | | 21 | Zack | India | Sushi | +------+---------------+---------------------------+------------------------+ 3 rows in set (0.16 sec)
- 投稿日:2021-01-17T14:51:52+09:00
データベースとは?その役割や種類まとめ
データベースが一体どんなものであるのか?
初心者にも分かりやすく解説。データベースとは?
データベースとは、簡単にいえば「情報の集合体」。
必要な情報を取り出したり、平均値を算出してみたり、いろいろな活躍をしてくれる。例えば、以下のような情報は、データベースで活用されることが多い。
- 銀行の個人情報
- 顧客の名前や連絡先
- ゲームユーザーのIDやパスワード
など、幅広い情報が、データベースに登録されている。
データベースの種類
実はデータベースといっても、以下のようにいくつかの種類が存在する。
- 階層型データベース
- XMLデータベース
- リレーショナルデータベース
- NOSQLデータベース
- オブジェクト指向データベース
など。
それぞれ簡単な特徴を紹介します。階層型データベース
親データと子データの関係から成り立つデータベース。
例えば、会社などの組織図が当てはまる。XMLデータベース
情報をXML形式で管理するデータベース。
※XML形式=機械に情報を伝えるための言語。リレーショナルデータベース
リレーショナルデータベース(RDB)は、SQL言語を用いて扱う、現在主流のデータベース。
詳細は後述します。NOSQLデータベース
リレーショナルデータベースでは管理しにくいデータを扱うためのデータベース。
比較的、データの整合性に対してゆるいが、機能はそこまで多くない。大量のデータを、高速処理できるのが強み。
オブジェクト指向データベース
オブジェクト形式で扱うデーターベース。
関連性のあるデータや処理方法を、オブジェクト(箱)に格納する。主流のデータベース
先ほど紹介したように、主流のデータベースは、リレーショナルデータベース(RDB)になる。
Relationalという名前の通り、各データ間には何かしらの繋がりが存在する。表自体をテーブルと呼び、テーブル同士で関係を定めたり、複数のテーブルから新しい表を作ったりできる。
リレーショナルデータベースの操作
リレーショナルデータベースを扱うには、SQL文の知識が必要。
SQLの基本操作は、以下の通り。
- 検索
- 登録
- 更新
- 削除
もちろん他にも機能はあるが、基本操作は上記4つ。
データ検索をはじめ、新しく登録したり更新したり、削除することも可能!
データベース管理システム(DBMS)
リレーショナルデータベースを扱うには、SQL文だけでなく、管理システムを使う必要がある。
以下が、主な管理用のソフトウェア。
- oracle
- SQL server
- DB2
- postgreSQL
- MySQL
- FireBird
など。
まとめ
以上が、データベースに関する簡単なまとめ。
- 投稿日:2021-01-17T10:54:36+09:00
Cloud9でWordPress環境を構築 3
WordPressの学習&AWSに触れるのを目的として
AWS Cloud9でWordPress環境を構築するまでの備忘録。環境構築完了。ここまでやったこと
- Cloud9環境立ち上げ
- MySQLセットアップ
- Apache、MySQLサービス起動
- スナップショット作成
この記事の目次
- WordPressセットアップ
- 前準備
- インストール
基本これに従う。
https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/sample-wordpress.htmlWordPressセットアップ
前準備
WordPressをダウンロード&展開する。
wget http://wordpress.org/latest.tar.gz tar -xzvf latest.tar.gz
wp-config-sample.php
をwp-config.php
に名前変更して利用する。cd wordpress mv wp-config-sample.php wp-config.php
wp-config.php
内の3箇所をMySQLで作成したデータベースに合わせる。define( 'DB_NAME', 'データベース名' ); define( 'DB_USER', 'ユーザ名' ); define( 'DB_PASSWORD', 'パスワード' );Amazonのサイトに記載はないが、セキュリティ的な対応をしておく。
次の値をサイトでランダムに生成して書き換える。
https://api.wordpress.org/secret-key/1.1/salt/define('AUTH_KEY', 'XXXXX'); define('SECURE_AUTH_KEY', 'XXXXX'); define('LOGGED_IN_KEY', 'XXXX'); define('NONCE_KEY', 'XXXX'); define('AUTH_SALT', 'XXXX'); define('SECURE_AUTH_SALT', 'XXXX'); define('LOGGED_IN_SALT', 'XXXX'); define('NONCE_SALT', 'XXXX');インストール
index.php
をエディタで開いてメインメニューバーからRunを実行する。
メインメニューバーのPreview > Preview Running Application を実行する。
Not Foundのエラー画面が出る。これは正常。
ブラウザのパスに
/wordpress/
を追加する。
これでインストール画面が出るらしいが、ずっとぐるぐるして画面が表示されない。
追加するURLを
/wordpress/readme.html
に変更する。画面が表示される。
(ここが分からず、色々いじって何回かCloud9の環境を作成しなおした……)
install.php
へのリンクをクリックしてインストールを進める。
ようやくWordPressのインストールまで完了した。
AWSの用語が分からなかったり、プリインストールのMySQLが動かなかったりで
結構時間がかかってしまった……。今後はこの環境を使ってWordPressの学習を進める。
- 投稿日:2021-01-17T04:54:58+09:00
MySQLで取得したデータを、EJSでWebブラウザに出力する
はじめに
Node.js + Express で作る Webアプリケーション 実践講座を参考にしながら、
データベース(以下DB)内のデータを、Webブラウザに表示する方法を記事にしました。なお、ここではNode.jsのテンプレートエンジンであるEJSと、RDB(リレーショナルデータベース)であるMariaDB(MySQL)を利用します。
(上記講座ではMongoDBが利用されていますが、本記事ではMySQLに置き換えました。)
実行環境
- Node.js v12.16.3
- Express 4.16.1
- 10.4.11-MariaDB
対象者
- JavaScriptの文法自体は学んだけど、Web技術はまだほとんど学べていない人
- かんたんなCRUD操作に関するSQLを理解している人
本記事でわかること
- サーバーサイド言語Node.js & フレームワークExpressを使い、Hello Worldする方法
- ExpressとMariaDB(MySQL)の連携方法
- ExpressとMariaDB(MySQL)を使い、DB内のデータをWebブラウザ上に出力する方法
対象のUdemy講座で学んだこと
対象の講座で学んだことのうち、特に本記事へ反映する内容は以下となります。
- パッケージマネージャであるnpmを使い、ミドルウェアやフレームワークを導入する方法
- EJSの構文の使い方
- Expressでのルーティング方法(特に関数の引数に関して)
EJSとは
EJSは、テンプレートエンジンと呼ばれるもののひとつで、HTMLの中にプログラム言語を埋め込むことができます。
特にEJSにおいては、HTML文書の中に<% %>
,<%= %>
タグなどを埋め込み、この中にプログラムを記述します。これは、サーバーサイドで保持している変数の値を併用してHTMLを記述するときに、書きやすさ・読みやすさの点で非常に強力です。
例えばサーバーサイドのみでHTML文書を書く場合、次のようなソースコードになります。
app.jsconst express = require("express"); const app = express(); app.get("/", (req, res) => { const text = "Hello World"; let data = "<!DOCTYPE html>\r\n"; data += "<html>\r\n"; data += " <head>\r\n"; data += " <meta charset='UTF-8'>\r\n"; data += " <title>hoge</title>\r\n"; data += " </head>\r\n"; data += " <body>\r\n"; data += "<p>"; data += text data += "</p>\r\n"; data += " </body>\r\n"; data += "</html>"; res.send(data); }); app.listen(3000);一方で、テンプレートエンジンを併用した場合は、次のようになります。
クォーテーションや改行を意味する\r\n
などが消え、読み書きしやすくなっているのが分かります。app.jsconst express = require("express"); const app = express(); app.set("view engine", "ejs"); app.get("/", (req, res) => { const text = "Hello World"; res.render("index", {text}); }); app.listen(3000);index.ejs<!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <title>hoge</title> </head> <body> <p><%= text %></p> </body> </html>実行の準備
さて、まずは環境の構築を行います。
Node.js, MariaDB(MySQL)はインストールされているものとします。サーバーサイドの準備
以下のコマンドを順に実行して、フレームワークやミドルウェアを導入します。
$ npm init
$ npm install express --save
,$ npm install mysql
$ npm install ejs -- save
MariaDB(MySQL)の準備
以下のSQLを順に実行します。
この操作により、Webサイトの名前・URLに関するテーブルを作成し、データの追加も行います。
create database website
create table website(name varchar(255), url varchar(255));
insert into website(name, url) values ("google", "https://www.google.com/"), ("amazon", "https://www.amazon.co.jp/"), ("apple", "https://www.apple.com/"), ("facebook", "https://www.facebook.com/");
実装する
次のような順序で、簡単なことから実装していきます。
- EJSを使い、Webブラウザ上でHello Worldする
- DB接続を行ってデータを取り出し、ターミナル上にデータを出力する
- DB接続を行って、EJSファイルを利用してWebブラウザ上にデータを出力する(ここでは一度失敗してみる)
- DB接続を行って、EJSファイルを利用してWebブラウザ上にデータを出力する(再チャレンジし、成功する)
1. EJSでHello Worldしてみよう
まずはDBのことは一旦 忘れて、EJSを使ってHello Worldをしてみます。
下記ソースコードを保存後、ターミナル上で
$ node app.js
と入力し、
Webブラウザでhttp://localhost:3000/
にアクセスします。次の画像のように表示されたら成功です。
ちなみに、
app.js
のソースコード内のapp.get()
の第一引数はリクエストURL、
第二引数はリクエストが送られたときに実行されるコールバック関数を指します。この処理を口語的に説明するなら、
http://localhost:3000/
が呼ばれたら次のコールバック関数を実行してね!
そしてそのコールバック関数には、index.ejsを表示して!っていう命令も含まれてるよ!
といったところでしょうか。実行するソースコード
app.jsconst express = require("express"); const app = express(); app.set("view engine", "ejs"); app.get("/", (req, res)=>{ res.render("index.ejs"); // デフォルトでは /viewsからの相対パスで表すので注意 }) app.listen(3000);views/index.ejs<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>Hello World</h1> </body> </html>2. DBに接続してみよう
次に、DB内のデータをターミナル上で表示する実装を行います。
app.js
を次のように書き換えます。
なお、mysql.createConnection()
の各種ユーザ情報は、必要に応じて書きかえてください。実行するソースコード
app.jsconst express = require("express"); const app = express(); const mysql = require("mysql"); const connection = mysql.createConnection({ host: "localhost", user: "root", password: "1234", database: "website" }); app.set("view engine", "ejs"); app.get("/", (req, res)=>{ const sql = "select * from website"; connection.query(sql, (err, result, fields)=>{ if(err)throw err; console.log(result); }) res.render("index.ejs"); // デフォルトでは "/views"ディレクトリからの相対パスで表すので注意 }) app.listen(3000);ターミナル上で
$ node app.js
と入力し、Webブラウザでhttp://localhost:3000/
にアクセスします。
前回と同様にHello WorldがWebブラウザに表示されており、
更にターミナル上に、次のような表示があれば成功です。ここでは
console.log(result)
の実行による、ターミナルのデータ出力結果から、
変数result
にはDBから取り出したデータが入っていることが確認できます。$ node app.js [ RowDataPacket { name: 'google', url: 'https://www.google.com/' }, RowDataPacket { name: 'amazon', url: 'https://www.amazon.co.jp/' }, RowDataPacket { name: 'apple', url: 'https://www.apple.com/' }, RowDataPacket { name: 'facebook', url: 'https://www.facebook.com/' } ]3. DB内のデータをWebブラウザに表示してみる
『1.EJSでHello Worldしてみよう』, 『2.DBに接続してみよう』では、
res.render("index.ejs")
とレンダリング先を表記し、ルーティングを設定していました。今回はレンダリング先にデータを渡すために、
app.get()
内にレンダリング先だけではなく、DBから取得したデータも記述する必要があります。
そこでres.render()
の第二引数に、レンダリング先に送るデータを記述します。より具体的にはいえば、
『2. DBに接続してみよう』で、変数result
にDBのデータが格納されることが確認できていました。
このresultをres.render()
の第二引数に指定します。
従って、ここではres.render("index", { web: result})
と記述します。ところで
{ web: result}
という記述に、ややこしさを感じるかもしれません。
これはresultからwebへ名前を置換してから、データを送るという処理を含んでいます。EJSに対して、resultという変数名をそのままに渡してしまうと、
「result?結果?いや何の結果を表す変数なのか、なんのこっちゃわからん」と、
フロントエンドエンジニアが困惑することになってしまいます。(webという変数名ならば適切なのかという問題はさておき。)
実行するソースコード
DBに保存しているWebサイト名やURLをWebブラウザ上に出力するため、
app.js
とindex.ejs
を、それぞれ次のように書き換えます。app.jsconst express = require("express"); const app = express(); const mysql = require("mysql"); const connection = mysql.createConnection({ host: "localhost", user: "root", password: "1234", database: "website" }); app.set("view engine", "ejs"); app.get("/", (req, res)=>{ const sql = "select * from website"; connection.query(sql, (err, result, fields)=>{ if(err)throw err; console.log(result); res.render("index", { web: result}); }) }) app.listen(3000);/views/index.ejs<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>Hello World</h1> <%= web %> </body> </html>ターミナルに
node app.js
を入力し、Webブラウザでhttp://localhost:3000/
にアクセスします。
次の画像のような、Hello WorldとObjectという文字の羅列が確認できるでしょうか?
半分だけ成功です!本来であれば
Apple
といったWebサイト名や、
https://www.google.com/
のようなURLがほしかったところですが、
DBから何らかのデータを取り出すことには、ひとまず成功したのではないでしょうか。
[]
で囲まれたよくわからないものは4つで、DBに登録したレコードもちょうど4つでしたしね。次の項で、この問題を解決します。
4. DB内のデータをWebブラウザに表示してみる(再挑戦)
前項ではDBから、どうやら何らかのデータを取り出すことには成功しましたが、
Webサイトの名前やURLを取得することはできませんでした。この原因について考えます。
http://localhost:3000/
にアクセスしたとき、
console.log(result)
の実行によって、ターミナルに何か表示されたことは覚えているでしょうか?それは、次のような内容でした。
$ node app.js [ RowDataPacket { name: 'google', url: 'https://www.google.com/' }, RowDataPacket { name: 'amazon', url: 'https://www.amazon.co.jp/' }, RowDataPacket { name: 'apple', url: 'https://www.apple.com/' }, RowDataPacket { name: 'facebook', url: 'https://www.facebook.com/' } ]一見するとオブジェクトですが、
出力されたデータは[]
で囲まれているため、これはオブジェクトたちを格納している『配列』です。従って、例えば
web[0]["name"]
と記述します。実行するソースコード
例として、
https://www.google.com/
をWebブラウザ上に表示してみます。
次のようにindex.ejs
を書き換え、再度$ node app.js
で実行します。
下記画像のように、Webサイト名とURLが表示されたら、成功です。/views/index.ejs<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>Hello World</h1> <%= web[0]["name"] %> <br> <%= web[0]["url"] %> </body> </html>この他にも、
for文を利用するなどして、一度に複数のデータを出力すること、あるいはSQLを変更してデータの更新・追加・削除することも可能です。おわりに
プログラミングを本格的に始めて1年も満たない未熟者の言葉ではありますが、
プログラミング言語の文法を修めるだけでは、Webのシステム開発は正直 不可能です。私はJavaScriptの文法を学習した後、サーバーサイド言語としてのJavaScript(Node.js)に入門したのですが、
すぐにHTTPリクエスト、ルーティングなどといったWeb特有の専門用語に悩まされました。Webアプリケーションのサーバーサイドへ入門する前に、
『この一冊で全部わかるWeb技術の基本』, 『Webを支える技術』, 『Web技術速習テキスト』といったWeb周りの情報に触れておくことを、強くおすすめします。参考
- 投稿日:2021-01-17T02:06:34+09:00
Heroku MySQLにクライアントから接続したい
やりたいこと
HerokuのアプリにアタッチしているMySQLへ、MySQL Workbenchなどのクライアントから接続したい
方法
情報を取得する
アプリ名を取得
herokuにデプロイしているアプリケーションの名前を取得します。
この場合はhogehogeというアプリをデプロイしていることとします。
herokuのアプリ名は、ど忘れしてたり、被らないように特殊にしている場合があるのでcliで取得してコピーしましょう。$ heroku list hogehoge fugafuga
アプリの情報を取得
アプリケーションhogehogeの情報を取得します。
アプリケーションに設定されている環境変数が出力されます。
Heroku上にあるアプリケーションにMySQLをアタッチしている多くの場合において、DATABASE_URLは以下のようになっていると思います。$ heroku config -a hogehoge === hogehoge Config Vars CLEARDB_DATABASE_URL: mysql://fizz:buzz@foo.cleardb.com/heroku_barbarbar?reconnect=true DATABASE_URL: mysql://fizz:buzz@foo.cleardb.com/heroku_barbarbar?reconnect=true 以下略MySQLの接続情報を抜粋する
環境変数の値から接続情報のすべてを読み取ることができます。
// 元が以下だとしたら mysql://fizz:buzz@foo.cleardb.com/heroku_barbarbar?reconnect=true // このように読み替える mysql://username:password@host/schema?reconnect=true // つまり以下のようになる MySQLホスト => foo.cleardb.com DB Schema => heroku_barbarbar Username => fizz Password => buzz以上になります。
あとは使っているクライアントに情報を入れて接続してあげるだけです。最後に
HerokuってデフォルトのデータベースがPostgreSQLなんですが、
MySQLに変えることもできます。
僕の場合には仕事、プライベート、開発環境、本番環境問わず、MySQLを使うことが多いため、PostgresからMySQLへ変えてみました。変え方については検索すればいくらでもヒットするのでそちらを。
ちなみにクライアントからアクセスして使ってみた感じだと速度が遅めです。まぁ無料なのでそこは仕方ないですね。