- 投稿日:2020-07-27T23:39:40+09:00
Node.jsとMySQLをDockerComposeで組んでみた
初めてのDockerネットワーク
これから先僕が環境構築する際、思い出せるようにするための、です。事前準備
まずDockerHubから二つのイメージをpullするところから
それぞれ12系と5.7系を使うのでバージョン指定
$ docker run -it node:12
$ docker run -it mysql:5.7
runはpull,create,startを一気に行ってくれる
control+p+qでコンテナから出る
その後
$ docker ps -a
で一度止めて、
コンテナが作成されているかを確認する(Upなら一度stopしてExitedにしておく)
これからは$docker start [コンテナID]
で起動できる
$ docker rename [古いコンテナ名] [新しいコンテナ名]
しておいた方がわかりやすい正しいバージョンのものが入っているかの確認は起動後
$ docker exec -it [コンテナ名] bash
attachと違うのはコンテナを起動したまま抜けることができるのかできないのかが違うexecは起動したまま抜けることができる
でコンテナに入り、バージョン確認...MySQLが起動しない...
先人様がいらっしゃいました。ありがとうございます。↓
https://qiita.com/takepan/items/0cbf13af3a0bb2c243abよしこれで確認できた
...でどうやってつなげるん??
Docker Composeとは
複数のコンテナを組み合わせてシステムを構成するための仕組みに用いるのがDocker Composeと呼ばれるもので、予めコンテナの起動方法やボリューム、ネットワークの構成などが書かれている
こんなものがあるのか、今まで一つのコンテナを独立させて動かしていたので、全く知りませんでした...
事前知識でDockerネットワークやマウントのことを知らなければならないとのことで書籍を借りて軽く頭に入れておきました。
全然知らないままDockerを使っていたのだなと反省そしてこれを書いていく...
docker-compose.yml
を作ってバージョン決めて、サービスの中身にnode.jsとmysql使いますよってこととかそれぞれの設定など、先人のymlファイルを参考にゴリゴリ書いていく...書き方を丁寧に載せてる先人様の記事はこちらです。ありがとうございます。↓
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaaかけたら、
docker-compose up
で起動
しばし待つ...しばし待つ
終わらねえ
db | Version: '5.7.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)ここで止まって一向に動かない...
仕方ないので、control+cで一度抜けました
docker-compose ps
で確認すると動いといて欲しいdb(mysql)が動いてない...一か八かで
docker start db
を試すと...stateがExitからUpに
一件落着ていうかこのやり方だと最初にコンテナは立ち上げなくても、なんならimageもpullしてこなくて急にdocker compose書いてあげた方がよかったのね...
じゃあ他のコンテナもたてます
今回はフロント、バック、dbの三つのコンテナを用意します。
docker-compose start
- 投稿日:2020-07-27T23:39:40+09:00
Node.jsとMySQLをDockerComposeで組みつつ、React,Express,MySQLの環境構築を躓きながらやっていく
初めてのDockerネットワーク
これから先僕が環境構築する際、思い出せるようにするための、です。事前準備
まずDockerHubから二つのイメージをpullするところから
それぞれ12系と5.7系を使うのでバージョン指定
$ docker run -it node:12
$ docker run -it mysql:5.7
runはpull,create,startを一気に行ってくれる
control+p+qでコンテナから出る
その後
$ docker ps -a
で一度止めて、
コンテナが作成されているかを確認する(Upなら一度stopしてExitedにしておく)
これからは$docker start [コンテナID]
で起動できる
$ docker rename [古いコンテナ名] [新しいコンテナ名]
しておいた方がわかりやすい正しいバージョンのものが入っているかの確認は起動後
$ docker exec -it [コンテナ名] bash
attachと違うのはコンテナを起動したまま抜けることができるのかできないのかが違うexecは起動したまま抜けることができる
でコンテナに入り、バージョン確認...MySQLが起動しない...
先人様がいらっしゃいました。ありがとうございます。↓
https://qiita.com/takepan/items/0cbf13af3a0bb2c243abよしこれで確認できた
...でどうやってつなげるん??
Docker Composeとは
複数のコンテナを組み合わせてシステムを構成するための仕組みに用いるのがDocker Composeと呼ばれるもので、予めコンテナの起動方法やボリューム、ネットワークの構成などが書かれている
こんなものがあるのか、今まで一つのコンテナを独立させて動かしていたので、全く知りませんでした...
事前知識でDockerネットワークやマウントのことを知らなければならないとのことで書籍を借りて軽く頭に入れておきました。
全然知らないままDockerを使っていたのだなと反省そしてこれを書いていく...
docker-compose.yml
を作ってバージョン決めて、サービスの中身にnode.jsとmysql使いますよってこととかそれぞれの設定など、先人のymlファイルを参考にゴリゴリ書いていく...書き方を丁寧に載せてる先人様の記事はこちらです。ありがとうございます。↓
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaaかけたら、
docker-compose up
で起動
しばし待つ...しばし待つ
終わらねえ
db | Version: '5.7.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)ここで止まって一向に動かない...
仕方ないので、control+cで一度抜けました
docker-compose ps
で確認すると動いといて欲しいdb(mysql)が動いてない...一か八かで
docker start db
を試すと...stateがExitからUpに
一件落着ていうかこのやり方だと最初にコンテナは立ち上げなくても、なんならimageもpullしてこなくて急にdocker compose書いてあげた方がよかったのね...
じゃあ他のコンテナもたてます
今回はフロント、バック、dbの三つのコンテナを用意します。
docker-compose start
動かない...
それもそのはず、docker-composeに必要なコマンドを書いてなかったからなんですね
いやymlファイルに書くコマンド全然わからん...ってなった僕はとりあえずdocker-compose run [コンテナ名] bash
で中に潜り込んで、reactの環境を作ることに...
node -v
,npm -v
でバージョンを確認
npm install -g create-react-app
でcreate-react-appをインストール
create-react-app [プロジェクトを入れるディレクトリ名]
しばしまつ...
Happy hacking!
これで完了(docker-compose run [コンテナ名] bashで中に潜り込んで作ったせいで、docker-compose upでローカルに作られたディレクトリの中に[プロジェクトを入れるディレクトリ名]のディレクトリができてしまったので削除しておく)
では改めて...
docker-compose start
ンンンン?
stateがExitから変わらない...
全部docker-composeに書いてるはずなんだけどな...ダメそうなので、docker-composeでdockerfileを参照することにする
docker-composeでimageを直接引っ張ってきてた部分をbuildで参照し、コマンドを書いたり〜、作業するディレクトリを書いたり〜よしこれで、わかりやすくなった気がする
docker-compose start
はい、ダメー
どうすればいいのだ...と助けを求めると、
docker-compose up
で立たない?
って言われハッとしたそういえば...
かけたら、
docker-compose up
で起動
しばし待つ
...しばし待つ
終わらねえ
db | Version: '5.7.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
ここで止まって一向に動かない...
仕方ないので、control+cで一度抜けましたこれが原因じゃないの
ってことでもう一度
docker-compose up
...
Compiled successfully!
動いた!!!!
ということで無事コンテナが起動し、localhost:3000にアクセスすると、reactがくるくるしとる!
stopしてからのstartでも起動できることが確認できた
よかったよかったこれでフロント(react)とdb(mysql)が動いた。次はバック(express)のコンテナを立てるぞ
- 投稿日:2020-07-27T23:39:40+09:00
Node.jsとMySQLをDockerComposeで組みつつ、React(TS),Express,MySQLの環境構築を躓きながらやっていく
初めてのDockerネットワーク
これから先僕が環境構築する際、思い出せるようにするための、です。事前準備
まずDockerHubから二つのイメージをpullするところから
それぞれ12系と5.7系を使うのでバージョン指定
$ docker run -it node:12
$ docker run -it mysql:5.7
runはpull,create,startを一気に行ってくれる
control+p+qでコンテナから出る
その後
$ docker ps -a
で一度止めて、
コンテナが作成されているかを確認する(Upなら一度stopしてExitedにしておく)
これからは$docker start [コンテナID]
で起動できる
$ docker rename [古いコンテナ名] [新しいコンテナ名]
しておいた方がわかりやすい正しいバージョンのものが入っているかの確認は起動後
$ docker exec -it [コンテナ名] bash
attachと違うのはコンテナを起動したまま抜けることができるのかできないのかが違うexecは起動したまま抜けることができる
でコンテナに入り、バージョン確認...MySQLが起動しない...
先人様がいらっしゃいました。ありがとうございます。↓
https://qiita.com/takepan/items/0cbf13af3a0bb2c243abよしこれで確認できた
...でどうやってつなげるん??
Docker Composeとは
複数のコンテナを組み合わせてシステムを構成するための仕組みに用いるのがDocker Composeと呼ばれるもので、予めコンテナの起動方法やボリューム、ネットワークの構成などが書かれている
こんなものがあるのか、今まで一つのコンテナを独立させて動かしていたので、全く知りませんでした...
事前知識でDockerネットワークやマウントのことを知らなければならないとのことで書籍を借りて軽く頭に入れておきました。
全然知らないままDockerを使っていたのだなと反省そしてこれを書いていく...
docker-compose.yml
を作ってバージョン決めて、サービスの中身にnode.jsとmysql使いますよってこととかそれぞれの設定など、先人のymlファイルを参考にゴリゴリ書いていく...書き方を丁寧に載せてる先人様の記事はこちらです。ありがとうございます。↓
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaaかけたら、
docker-compose up
で起動
しばし待つ...しばし待つ
終わらねえ
db | Version: '5.7.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)ここで止まって一向に動かない...
仕方ないので、control+cで一度抜けました
docker-compose ps
で確認すると動いといて欲しいdb(mysql)が動いてない...一か八かで
docker start db
を試すと...stateがExitからUpに
一件落着ていうかこのやり方だと最初にコンテナは立ち上げなくても、なんならimageもpullしてこなくて急にdocker compose書いてあげた方がよかったのね...
じゃあ他のコンテナもたてます
今回はフロント、バック、dbの三つのコンテナを用意します。
docker-compose start
動かない...
それもそのはず、docker-composeに必要なコマンドを書いてなかったからなんですね
いやymlファイルに書くコマンド全然わからん...ってなった僕はとりあえずdocker-compose run [コンテナ名] bash
で中に潜り込んで、reactの環境を作ることに...
node -v
,npm -v
でバージョンを確認
npm install -g create-react-app
でcreate-react-appをインストール
create-react-app [プロジェクトを入れるディレクトリ名]
しばしまつ...
Happy hacking!
これで完了(docker-compose run [コンテナ名] bashで中に潜り込んで作ったせいで、docker-compose upでローカルに作られたディレクトリの中に[プロジェクトを入れるディレクトリ名]のディレクトリができてしまったので削除しておく)
では改めて...
docker-compose start
ンンンン?
stateがExitから変わらない...
全部docker-composeに書いてるはずなんだけどな...ダメそうなので、docker-composeでdockerfileを参照することにする
docker-composeでimageを直接引っ張ってきてた部分をbuildで参照し、コマンドを書いたり〜、作業するディレクトリを書いたり〜よしこれで、わかりやすくなった気がする
docker-compose start
はい、ダメー
どうすればいいのだ...と助けを求めると、
docker-compose up
で立たない?
って言われハッとしたそういえば...
かけたら、
docker-compose up
で起動
しばし待つ
...しばし待つ
終わらねえ
db | Version: '5.7.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
ここで止まって一向に動かない...
仕方ないので、control+cで一度抜けましたこれが原因じゃないの
ってことでもう一度
docker-compose up
...
Compiled successfully!
動いた!!!!
ということで無事コンテナが起動し、localhost:3000にアクセスすると、reactがくるくるしとる!
stopしてからのstartでも起動できることが確認できた
よかったよかったこれでフロント(react)とdb(mysql)が動いた。次はバック(express)のコンテナを立てるぞ
- 投稿日:2020-07-27T23:05:05+09:00
yps並走備忘録 Task2 MySQL(5.7)~nginx(v1.18)~PHP(7.3)~Laravelインストール
yps Task 2 アプリを動かす準備
今回の流れ
1. MySQLインストール
2. Nginxインストール
3. PHPインストール
4. Laravelインストール
5. VS CodeでSSH接続してサーバーにあるファイルを編集-----用意するもの-----
VS Code
折れない心(笑)MySQL5.7のインストール&設定
アプリでデータベース管理を司るMySQLをインストール、設定していきます。
まずはインストール
sudo yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
sudo yum install -y mysql-community-server -y
動作確認
mysqld --version
(正常に完了していればMySQLの情報が表示される)
sudo systemctl enable mysqld
(MySQLを自動で起動する設定)
sudo systemctl start mysqld
(MySQLを起動)
sudo systemctl status mysqld
(MySQLの状態を確認、起動できていれば「active(Running)」という緑の文字が出てくるはず)
sudo systemctl stop mysqld
(一旦MySQLを停止)MySQLへログイン・パスワード変更・文字コードを設定
sudo cat /var/log/mysqld.log | grep -i root
(仮で設定されたパスワードを表示、root@localhost: xxxxxxと表示されるはず)
sudo systemctl start mysqld
mysql -u root -p
と打つとPassword:という表示になる、ここで上記の仮パスワードを入力するのですが、Linuxの仕様で入力しても何も表示されないので注意!
ミスタイプがないように打って、Enterを押すと、正しい場合はMySQLに入れ、表示がmysql>
となるはず。パスワード変更
SET PASSWORD = PASSWORD('パスワードをここに入力')
-------------注意事項-------------
- 8文字以上、英字の大文字・小文字・数字・記号を全て混ぜないといけない
- #はエラーに基になるので使用しない変更できたら
exit
と打つとサーバーのターミナルへ戻れる日本語を扱えるように文字コードを変更
sudo vi /etc/my.cnf
最終行に
character-set-server=utf8mb4
を追記
sudo systemctl restart mysqld
(MySQLを再起動して設定を反映)
mysql -u root -p
(MySQLにログイン)
Password:設定したパスワード
mysql> show variables like "chara%";
(文字コードの設定が反映されているか確認)MySQLのインストールここまで
Nginxのインストール&設定
補足:nginxとは? 参考url:
インストール
1. インストール用のyumレポジトリ作成
sudo vi /etc/yum.repos.d/nginx.repo
開いたファイルに以下を記述
[nginx]
name=nginx repo
baseurl=https://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=12. 以下のコマンドを打ってインストール
sudo yum install nginx -y
完了したらバージョンを確認
nginx -v
nginxを自動で起動できるように設定
sudo systemctl enable nginx
3. AWSマネジメントコンソールからインバウンドルールにhttp、httpsポートを追加
http = 80
https = 443nginxを再起動して設定を反映
sudo systemctl nginx
ブラウザにEC2インスタンスのIPを入れてWelcome to Nginxが表示されればインストール完了
4. nginxのrootディレクトリ変更
sudo mkdir /var/www
wwwディレクトリを作成
sudo mkdir /var/www/html
wwwディレクトリの中にhtmlディレクトリを作成
sudo chown -R centos:nginx /var/www
/var/www以下の権限をcentosからnginxに移譲5. nginxの設定変更
sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.org
元々の設定をorgファイルでバックアップ保存
sudo vi /etc/nginx/conf.d/default.conf
設定ファイルを編集--------編集する場所----------
rootのパスを変更
#root /usr/share/nginx/html;
⇒root /var/www/html;
Nginx構文チェック
sudo nginx -t
何も表示されなければOK!Nginxを再起動
sudo systemctl restart nginx
ブラウザで再度EC2のIPアドレスを開いて(or更新して)403エラーになっていればOK
nginxのインストール&設定ここまで
PHP 7.3のインストール&設定
お次はいよいよPHPを動かせるように必要なものをインストールしていきます
1. yum レポジトリのインストール&アップデート
EC2にインストールするためのプログラムが古いのでアップデートします。
sudo yum install epel-release -y
sudo yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm -y
sudo yum update -y
2. PHPのインストール
sudo yum -y install --enablerepo=epel,remi,remi-php73 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt php-fpm php-mysql php-mysqlnd zip unzip
バージョンの確認
php -v
で以下が表示されればOKPHP 7.3.20 (cli) (built: Jul 7 2020 07:53:49) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.20, Copyright (c) 1998-2018 Zend Technologies3. PHPとNginxを連携させます
php-fpmの設定
sudo cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.org
恒例、元のファイルバックアップ
sudo vi /etc/php-fpm.d/www.conf
設定ファイル編集変更する場所
user = nginx
group = nginx
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660php-fpmの設定ここまで
Nginxの設定
sudo vi /etc/nginx/conf.d/default.conf
まずは10行目くらいにあるindexのところに追記します
index index.php(←追記) index.html index.htm;
そのすぐ下に下記も追記
try_files $uri $uri/ /index.php?$query_string;
さらにlocation / 以下に下記を追記します
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}上記連携が終わったら…
配下のディレクトリもnginxへ所有者変更(使えるようにする)
sudo chown -R centos:nginx /var/www/
/var/www/php-fpmの自動起動
sudo systemctl enable php-fpm
nginx再起動
sudo systemctl restart nginx
php-fpm起動
sudo systemctl start php-fpm
ここまでできればあとちょっと!
テスト表示用のindex.phpファイルを作成
vi /var/www/html/index.phpファイルに以下を記述
<?php echo phpinfo();?>:wqで保存したらnginxとphp-fpmを再起動
sudo systemctl restart nginx
sudo systemctl restart php-fpm
ブラウザを更新してPHPのバージョン情報が見られれば完了です
Laravelのインストール&設定
一時フォルダに移動
cd/tmp
Laravelのインストールに必要なComposerをインストール
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
Composerがどこでも使えるようにします
sudo mv composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer
Laravelを構築します
cd /var/www/html
composer create-project --prefer-dist laravel/laravel yps
※ypsの部分はもちろん任意の名前でOK※phpをインストールした時にzip unzipがちゃんとインストールされていないとここで躓く可能性があります
無事Laravelの構築が終わったら設定をしましょう
cd yps
Laravelのフォルダへ移動
php artisan key:generate
composerでlaravelアプリ用の暗号化キーの生成
cp -p .env.example .env
.envファイルの下記の部分を変更します
APP_URL= EC2のIPアドレス
DB_PASSWORD= MySQLのパスワードnode.jsとnpm(パッケージ管理システム)をインストール
多分後日フロント周りをいじるとき用…かな?
sudo yum install npm node -y
composer install
npm install
下記のコマンドを打てば設定は一段落
sudo chorn-R centos:nginx /var/www/
sudo chmod -R 777 storage/ bootstrap/cache/
laravelのWelcome画面表示
vi /etc/nginx/conf.d/default.conf
/var/www/html;
となっているところを
/var/www/html/yps/public;
に変更して…nginxとphp-fpmを再起動
sudo systemctl restart nginx
sudo systemctl restart php-fpm最後にEC2インスタンスのIPアドレスをブラウザに入力すればLaravelのWelcome画面が見られるはずです。
さらにここからVS Codeで編集できるようにします
- VS Codeを起動して、拡張機能のRemote-SSHをインストール
- 左の「リモートエクスプローラーアイコンをクリック」
- SSH TARGETSと書いてあるところにカーソルを合わせると出てくる歯車アイコンをクリック
- 画面中央上部にSelect SSH configuration file to updateと出るのでC:\users\ユーザー名.ssh\configをクリック
- Host: 表示名、後ほどコマンドプロンプトからSSH接続をするのにも利用できる
- Port: AWSで作成したPort番号
- User: centos
- HostName: EC2のIPアドレス
- IdentifyFile: .ssh/xxxx.pem(秘密鍵ファイル)
- 入力後に右下の緑色の「リモートウインドウを開く」をクリック
- Remote-SSH Connect to Host...をクリック
- 上記で作成した表示名をクリック
- 画面中央上部にLinux, Windowsとか選択肢が3つくらい出てくるのでLinuxを選択
- しばらくするとVS Code Serverが立ち上がる
- 完了すると右下にHost名が出る
- エクスプローラを開いてresources ⇒ views ⇒ welcome.blade.phpを開く
- 84行目にあるウェルカムメッセージを変更して保存
- ブラウザをリロードするとウェルカムメッセージが更新されている(ハズ)
以上でTask2完了です。
- 投稿日:2020-07-27T22:45:34+09:00
PHPにおけるページネーションの方法
初投稿です。
PHPのページネーションに関して、以前実装したものの知識が抜けていたので、アウトプットがてら復習したいと思います。何かのお役に立てれば幸いです。要件
・各ページで5つずつ表示する
・ページの前後には「前へ」「次へ」を表示。複数ページある場合はリンクになり、それぞれのボタンを押すと前後のページへジャンプする
・ページ番号は5つまで表示。基本的に現在表示されているページの前後2つを表示させる
・ページ数が表示されてる部分にあわせて「○件中○〜○件目の商品」と記載するなお、今回はLaravelなどのフレームワークは使わずに、生のPHPで実装します。
イメージとしてはこんな感じです。
DB関連
function get_db_connect(){ $dsn = 'mysql:dbname='. DB_NAME .';host='. DB_HOST .';charset='.DB_CHARSET; try { $dbh = new PDO($dsn, DB_USER, DB_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4')); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } catch (PDOException $e) { exit('接続できませんでした。'); } return $dbh; } function fetch_all_query($db, $sql, $params = array()){ try{ $statement = $db->prepare($sql); $statement->execute($params); return $statement->fetchAll(); }catch(PDOException $e){ set_message('データ取得に失敗しました。'); } return false; }①modelで必要な要素をselectで抽出する
$db = get_db_connect();
function get_items_list($db, $limit = 5, $offset = 0){ $sql = ' SELECT --selectする要素を記載 limit ? offset ?'; return fetch_all_query($db, $sql, array($limit, $offset)); }このとき、$limit=5で表示させる件数を予め限定させておく。
また、全体の件数も知っておきたいので、countを使って実装。
function get_items_count($db) { $sql = ' SELECT count(*) FROM テーブル名' $result = fetch_all_query($db, $sql); return $result[0]['count(*)']; }②view画面の実装
<?php foreach($items as $value) { --ここにget_items_list関数から表示させたいアイテムを表示 } echo $items_count. '件中'.$page_ini. "〜" .$page_fin. "件目の商品"; // リンクをつけるかの判定 if($now > 1){ print '<a href=\'../html/〜.php?page_id='.($now - 1).'\')>前へ</a>'. ' '; } else { print '前へ'. ' '; } for($i = 1; $i <= $max_page; $i++){ if($i >= $now - $range && $i <= $now + $range) { if ($i == $now) { print '<a class="current_page" href=\'〜.php?page_id='.$now.'\')>'. $now. '</a>'. ' '; } else { print '<a href=\'../html/〜.php?page_id='.$i. '\')>'. $i. '</a>'. ' '; } } } // リンクをつけるかの判定 if($now < $max_page){ print '<a href=\'../html/〜.php?page_id='.($now + 1).'\')>次へ</a>'. ' '; } else { print '次へ'; } ?>まず、〜件中○〜○件目の商品の部分から。
$items_countに関しては、modelで記述したget_items_count関数を使って表示させます。
page_iniとpage_fin(つまり、表示させる商品ページの最初と最後の部分)に関しては、getで取得するページidによって、offsetの値が定義され、それにより表示されるページが変わるといった感じ。
「前へ」「次へ」に関しては、クリックするとgetしたページid+1がgetで渡される。
表示されるページの数に関しては、for文にて表示。
$rangeに関しては、ページidが1、もしくは最後のページのときは4、id=2、最後のページから1つ前のときは3、それ以外は2となるように設定しています。
//ページネーションの表示数 if((int)$now === 1 || (int)$now === (int)$max_page) { $range = 4; } else if((int)$now === 2 || (int)$now === ((int)$max_page -1)) { $range = 3; } else { $range = 2; }③controllerの記載
viewで指定した変数をそれぞれ定義する。
if(get_get('page_id')) { $now = $_GET['page_id']; } else { $now = 1; } $offset = ($now - 1) * 5; $items = get_items_list($db, $limit = 5, $offset); $items_count = get_items_count(); $max_page = ceil($items_count / 5); $page_ini = ($offset + 1); if(count($items) === 5) { $page_fin = ($offset + 5); } else { $page_fin = $items_count; } if((int)$now === 1 || (int)$now === (int)$max_page) { $range = 4; } else if((int)$now === 2 || (int)$now === ((int)$max_page -1)) { $range = 3; } else { $range = 2; }まずGETで受け取ったページidを定義する(get_getはユーザー定義関数)
//viewからのidをgetしたとき if(get_get('page_id')) { $now = $_GET['page_id']; } else { //設定されてない場合は1ページ目にする $now = 1; }定義したら、その変数($now)を使ってoffsetを定義する
//ここでoffsetの定義 $offset = ($now - 1) * 5;modelで実装したselect文もここで定義しておく。
$items = get_items_list($db, $limit = 5, $offset); $items_count = get_items_count();ceil関数を使って、小数点になる場合は繰り上げを行う。
$max_page = ceil($items_count / 5);前述の通り、page_iniとpage_fin(つまり、表示させる商品ページの最初と最後の部分)に関しては、offsetの値により表示されるページが変わる。
//最初 $page_ini = ($offset + 1); //最後(1ページに表示されるアイテム数が5つの場合とそうでない場合で条件分岐) if(count($items) === 5) { $page_fin = ($offset + 5); } else { $page_fin = $items_count; }あとはLaravelでもページネーションを実装してみたいな。
- 投稿日:2020-07-27T21:21:48+09:00
Mysql2::Error::ConnectionErrorが出た場合
localhost:3000で出たエラーを解決させました
自作アプリの開発中に起きたエラーを紹介します。
環境
・macOS
・Rails 5.2.4.3
・Ruby 2.5.1今日(投稿日)はエンゼルスの大谷投手が693日ぶりに登板と言う事で、めちゃくちゃテレビを見たい気持ちを抑えて、いつも通りの朝活を行う事に。。。
へ?
何だこれは??
一瞬頭が真っ白になってしまいました。
なかなか自作アプリ開発が思う様に進まない中で、もはや自分でアプリを見ることすら出来ないのかと愕然。
5分くらい絶望した後に、取り敢えずエラーの解析から始めました。
Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)って何??
エラーの内容を調べていると結構同じ様なエラーに遭遇されている方が多かったので、その記事を見ていくと、
クライアント(自分のPC) → /var/lib/mysql/mysql.sock にデータを見に行こうとしたら、そんな場所ないじゃん。って感じのエラーなんだと理解。
socketとは
プログラムとネットワークを結ぶ接続口。仲介役。仲介業者。仲人。合コンで言う幹事。
って事で正しい出入り口(ソケット)を探す旅に
socketってどこにあんの??
他の記事を読み漁り、socketの存在を調べました
特に参考にさせてもらった記事
Can't connect to local MySQL server through socket '/tmp/mysql.sock'記事を読み比べる中で
'/tmp/mysql.sock' '/var/lib/mysql/mysql.sock'と言う2つのソケットを見比べて、
「自分のエラーの場合は'/var/lib/mysql/mysql.sock'に行こうとしたが、そんな場所はないと言われているので、そこを見つけて修正すれば良いのか!!」と推測。
で、どこに書いてあんの?
解決法
この記事を読んで私も解決しました
【Rails】ローカル環境におけるmysql接続エラー対処法【Can't connect to local MySQL server through socket】database.yml#修正前 development: <<: *default database: データベース名_development username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /var/lib/mysql/mysql.sock #修正後 development: <<: *default database: データベース名_development username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /tmp/mysql.sock /var/lib/mysql/mysql.sock → /tmp/mysql.sock に変更してますコードの修正を行ったので、再起動させます。
rails sこれでソケット名が正しくなったので、無事に閲覧が出来ました!!
原因
database.ymlですが、特に自分で何かを記述した訳ではなくて、何かしらの教材や記事を
コピペしてしまう事で、起きやすい事象なのかと思いました。
その分、最初はすごく焦りましたが、今まで気にしなかった所を考えたり、エラー文を調べていく中で、同じ様なエラーに遭遇されている方が多かった事も、自分の中では収穫でした。ymlを一度見てもらうのも良いかも知れません。最後にsocketの
'/tmp/mysql.sock' '/var/lib/mysql/mysql.sock'の箇所ですが、使われている方によっては、
/tmp/mysql.sock → /var/lib/mysql/mysql.sockが正解のパターンも多くあると思いますので、まずは自身のsocketの所在を確認してみてください!!
- 投稿日:2020-07-27T17:25:16+09:00
Equalumがやって来た!(余談編・・)
唐突ですが、今回はリアルタイム・ストリーミングで流れ作業の匿名化処理を検証してみます!
お陰様で個人的に幾つかEqualumに関する質問等を頂けるようになり、その中でデータの一部のカラム情報に関して、全自動で匿名化処理(アスタリスク列等に置き換える)は出来る??・・・という内容がありました。
今回の検証では、極めてシンプルで単純な方法ですが、リアルタイムで連続挿入されてくるデータの「特定のカラム情報を全て自動的に」アスタリスク10個の文字列に置き換える作業を行ってみたいと思います。
イメージとしては、Equalumのエージェントが遠隔で稼働中のデータソースに加えられた操作を検出し、CDC+kafka/Spark連携を駆使したリアルタイム・ストリーミング処理でそのメッセージをターゲット側に伝える際に、そのメッセージの一部(今回の匿名処理対象)を自動的に特定の情報(10個のアスタリスク)に置き換えて送る・・という感じになります。
ポイントは、纏めてドン!のバッチ系で処理をするのではなく、オリジナルに対象データが挿入されたタイミングで高速変換を自動的に実施し、ターゲット側のデータベースにリアルタイムで反映させる・・・という作業を、Equalum得意のプログラム無しで実現してみるという点になるかと思います。
では、一気に匿名化処理の検証を実施します!!
最初の作業は、今まで実施してきた検証と同じく上流側のデータソースに対して、ストリーミング処理を定義する事から始めます。ここでEqualum内部でのkafka/Spark処理連結が「プログラム無し」で行われ、以降の各種データ処理に対してCDCを最大活用したリアルタイム・ストリーミング処理を提供する事が出来るようになります。kafkaとの連携を実施する為に、ユニークな名称を設定するだけでOKです。
まず始めに、データが挿入される上流側のデータソースを設定します。先ほどの手続きで準備済みのデータソース(トピック)を選択します。
匿名化の設定は非常に簡単で、上流側のデータベースに入ってきたデータの「特定のカラム」を全てアスタリスク10個で置き換えるようにトランスフォームを設定するだけです。今回の検証では、識別しやすいように変換後のカラム名に対して「AN_」を頭に付ける事にしました。またその際の処理はシンプルにダブルクォーテーションで囲ったアスタリスク列でOKです。
今回の匿名化作業に必要な置き換え用のカラム情報の設定が完了しました。(表の下側に纏めておきました)
メニューからターゲット側のデータソースを選択して、着地側の必要情報を設定します。
以前の検証で行った様に、最終のターゲットテーブルに対する必要な設定を行います。今回の匿名化検証では最後の「マッピング」設定が肝になりますので、以下はその部分にフォーカスして手順を紹介します。
最後にターゲット側のテーブルに対する、流し込み対象のカラム情報のマッピングを行います。1:1の様なケースでは、何も確認せずにそのまま「OK」ボタンを選択すれば良いのですが、今回の匿名化処理では事前に定義した幾つかの項目に対しての、最終テーブル上の各カラムに向けたマッピング変更を行わなければなりません。
まずは、カード番号の情報を先ほど設定したカラムに置き換えます。
全てのマッピングを適切に匿名化側の情報に向けて設定変更します。この辻褄が合えばEqualum的にはリアルタイム・ストリーミング処理で匿名化を実行しながら、最終段に設定されているターゲットのデータベース上の所定のテーブルに、リアルタイムで順次着地させていきます。このマッピング作業は、Equalumを活用するうえで重要なチェック項目になりますので、他のケースも含めて確実に実施する必要があります。
今回設定したEqualumのFLOWはこのような感じになります。(間に匿名化の為のTransformを1段挟んだだけの、非常に簡潔明瞭な形です)
今回検証に使用したスクリプトが、上流側のMySQLに挿入した結果がこちら側になります。形式的には今までの検証で使用している内容になりますので、個人情報(実際はFakerが作りだしている内容になりますが・・・)がそのまま各カラムに入ってきています。
こちらがEqualumでストリーミング処理を行いながら匿名化を実施した結果になります。綺麗にアスタリスクに置き換わっている事が確認できます。
Equalumのリアルタイム・ストリーミング処理により、ターゲットデータベース上のテーブルは自動的に必要情報がアスタリスク列に置き換わり、実質的に上流部のオリジナル情報(こちら側はエビデンス側として保全対象)の処理とほぼ同時に、下流側のターゲットデータベース上に対して、必要な情報項目の匿名化が実施済みの形で処理されるようになります。
今回のまとめ
昨今の情報利活用や広域情報共有等の際には、この種の情報匿名化作業が必要になるケースが出てくると思います。Equalumを活用する事で、データを流しながら必要処理を完了させて、ターゲット側に着地させたと同時に利活用や、その後に必要な処理(この場合は複数のテーブル(サイロ化されたデータベースから引き抜かれてくる情報)を跨いだケースが多くなるので、その処理の高速化の為に「インメモリ&スケールアウト型のデータベース」を使う事が増えてきています。これは、Equalumで高速化しても、その後の処理が遅いと投資対効果が極端に悪化するとか、IoT系の仕組みが既存系のデータ待ち状態になって、同じ様に投資対効果を下げる事を避ける意味での採用事例になります。
利活用系のターゲットデータは、今後の活用形態や規模の変化が読みにくいケースが多いので、前述のスケールアウトが可能な物や、クラウド提供されるサービスを活用するケースが増えてくると思います。
既存の現業系データシステムに無用のトランザクション・ロードを追加せずに、Equalumとその着地側のデータソースの柔軟な組み合わせで、「同じ時間帯」で、「同じデータ」に対して「創造的なアプローチを気兼ねなく行える」環境を構築できるのが、Equalumの強みの一つなのではないかと感じました。
謝辞
本検証は、Equalum社の特別の許可を得て実施しています。この貴重な機会を設定して頂いたEqualum社に対して感謝の意を表すると共に、本内容とEqualum社の公式ホームページで公開されている内容等が異なる場合は、Equalum社の情報が優先する事をご了解ください。
- 投稿日:2020-07-27T16:34:15+09:00
Node.js+Express+MySQLでWebAPIを作成してみる①
はじめに
NodeでReactを用いてフロントの作業をしていて、せっかくならバックエンドもNodeつかってJavaScriptで作ってみようということでWebApiサーバーを作ってみました。
実行環境
- CentOS7
- Node.js 8.17.0
Expressの動作確認
npm install express
でインストール以下のサンプルソースを任意のフォルダに保存
index.jsvar exp = require("express"); var app = exp(); app.get("/",function(req,res){ res.send("Hello,World"); }) app.listen(3000,function(){ console.log("成功") })保存したフォルダに移動し、
node index.js
で実行した後http://localhost:3000/
にアクセス。
サーバーが起動し、GETリクエストのレスポンスが返ってきました。MySQLの設定
まずはMySQLにログイン。その後
create database ApiTest;
use ApiTest;
create table api_tbl(id int(5),name varchar(10));
insert into api_tbl values(2,'test');
上記のコマンドで、データベースとテーブルを作成、レコードを追加。データの取得
作成したテーブルデータをGETリクエストで実際に取得してみます。
index.jsvar exp = require("express"); var app = exp(); var mysql = require("mysql"); var connection = mysql.createConnection({ host: "localhost", user: "root", password: "****", database: "ApiTest" }); app.get("/", function (req, res) { connection.query('select * from api_tbl', function (error, results, fields) { if (error) throw error; res.send(results); }); }); //任意のポート番号 app.listen(****, function () { console.log("成功"); })上記のソースを保存し、
node index.js
を実行。Postmanを使用してレスポンスを確認します。
先ほど登録したデータがちゃんと返ってきたので成功です。
感想
Expressを使うことでとても簡単にWebApiが作成できて感動しました!
今回は初めてということでGETリクエストのみの実装でしたが、今後CRUDすべてのAPIを実装し、フロント側もReactなどで開発することで1つのWebアプリケーションを作ろうと考えております。
- 投稿日:2020-07-27T15:06:23+09:00
Spring Bootで書籍管理Webアプリを作ろう part1
はじめに
どうも、プログラミング勉強中の大学生、@Ikuto19です。今回は勉強がてらにJavaのSpring Bootを使った簡易的な書籍管理webアプリを作ろうと思います。
以前、JavaではなくPythonで作成したんですが個人的に納得のいかない点があったので、作り直そうを思いました。その納得がいかない点というのは下記のようなものです。
- Pythonはサーバーサイド言語として不向き
- 無料で自作アプリを公開したい
サーバーサイドのプログラミング言語として使われているのはRuby、Java、PHPの三つが多い気がします。ネットで調べてもこの三つどれかが使われているのが大半みたいです。(個人調べ)
Pythonはサーバーサイドではなく、AIやディープラーニングといったものやデータサイエンスが得意なプログラミング言語です。なのにwebアプリのサーバーサイド言語として使っても、あまり使わないのであれば勉強にならないと思ったので、今回はJavaで作り直すという考えに至ったわけです。あと無料で自作アプリを公開できないかな?と調べた結果、Herokuというサービスがあることを知ったのも理由の一つです。
もし、載せている情報が間違っていたり、説明不足があれば、気にせず指摘してくださって構いません。この記事は自分の勉強のためであり、僕と同じように躓いている人に向けたものです。ですので、よろしくお願い致します。
前提条件
- macOS Catalina(バージョン10.15.5)
- Eclipse Version: 2020-03
- サーバーサイド言語: Java
- フロントエンド言語: HTML、CSS、Javascript(jQuery)
- データベース: MySQL(HerokuではclearDBというアドオンからMySQLを使用)
- Webアプリケーションフレームワーク: Spring FrameworkのSpring boot
- ビルドツール: maven
- 書籍管理API: openBD
- webアプリの公開サービス: heroku
各ツールやプロジェクトについて
Spring Frameworkについて
公式サイト → https://spring.io/
Spring FrameworkはJavaによる開発をスピーディーに安全に開発するためのフレームワークで、Springというふうに読んだりもするみたいです。このSpringは「DI:依存性注入」と「AOP:アスペクト指向プログラミング」を特徴にもっています。mavenについて
公式サイト → https://maven.apache.org/
mavenは複数あるビルドツールうちの一つです。他にはGradleやAntがありますが、今回はHerokuに完成したアプリをデプロイするのでmavenを選びました。pom.xmlに依存関係を記述することで、いろんなパッケージを扱えるようになります。openBDについて
公式サイト → https://openbd.jp/
このopenBDは書誌情報や表紙を誰でもアクセスできる無料のAPIです。
今回はjavascriptのjQueryでこのAPIを使って書籍情報にアクセスします。herokuについて
公式サイト → https://jp.heroku.com/about
コンテナベースのクラウド型PaaSで、多数のプログラミング言語から選んでき、自作アプリをデプロイ・管理することができるサービス。ツールの導入
インストール済みのeclipseへSpring プロジェクトをインストール
- eclipse起動後、ヘルプ > eclipse マーケットプレースからSpring Tools 4(aka Spring Tool Suite 4) 4.7.0.RELEASEをインストール
- 全てのチェックボックスにチェックしたまま、確認
- 「使用条件の条項に同意します」にチェックを入れて完了
- 「再起動しますか?」と聞かれるのでそのまま再起動する。
もし、セキュリティ警告で「信頼性または有効性を確立できない署名されていないソフトウェアをインストールします。インストールを続行しますか?」と表示されたら、インストールボタンをクリック。
Herokuへの登録およびクレカの登録
Herokuでアカウント作成
サインアップ → https://signup.heroku.com/login
1. 上記で必要項目を入力し、アカウント作成
2. 確認メールが来るので、クリックしてパスワードを設定ここまでできていると、ダッシュボード画面になっていると思います。
MySQL利用のためにクレジットカードの登録
HerokuではデフォルトのデータベースがPostgreSQLなので、MySQLにする際はclearDBという無料のアドオンを追加する必要があります。ですが、そのためにはクレジットカードの登録をする必要があるので、登録します。
- ダッシュボード画面から右上端のアイコンからAccount settingsをクリック
- BillingタブからBilling Informationの「Add credit card」をクリック
- 必要項目を入力して、Save Detailsをクリック
テストアプリの作成・実行とherokuでの公開
テストアプリの作成
一応、作成手順を載せておきますが、GitHubにプロジェクトをあげているので、以下のコマンドダウンロードしてくださっても構いません。
terminal$ git clone https://github.com/ikuto19/test-webapp.git作成手順
- eclipse起動後、パッケージ・エクスプローラーで右クリック
- 新規 > プロジェクトをクリック
- Spring BootのSpring スターター・プロジェクトを選択し、「次へ」をクリック
- 名前を「webapp-test」、グループとパッケージを「com.app」にして、「次へ」をクリック
- 依存関係のテンプレート・エンジンからThymeleafとwebからSpring Webにチェックして、「完了」をクリック
プロジェクトの中身を確認すると、以下の画像のような構成になっていると思います。もし、templatesフォルダがなければ追加で作っておいてください。
次に以下の構成で新規のファイルを作成または既存のファイルを削除します。
各ファイルの中身は以下のように記述します。
App.javapackage com.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }IndexController.javapackage com.app.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { @GetMapping("/") public String getIndexPage(Model model) { String message = "Hello, World!!"; model.addAttribute("message",message); return "index"; } }index.html<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <meta charset="UTF-8"> <head> <title>テストアプリ</title> </head> <body> <p th:text="${message}"></p> </body> </html>Procfileweb: java $JAVA_OPTS -jar target/*.jar --server.port=$PORT実行確認
パッケージ・エクスプローラーのApp.javaを選択したまま右クリックで、実行 > Spring Bootアプリケーションをクリックして、実行。
webブラウザで http://localhost:8080/ にアクセスすると、下記のような画像が表示される。
Herokuへデプロイ
以下のコマンドを順に実行
「heroku login」を実行後に何かキーを押すと、webブラウザにとばされるので、「Log IN」ボタンをクリックterminal$ brew tap heroku/brew && brew install heroku $ heroku logincreateコマンドで「Name test-webapp is already taken」のようなエラーが出る場合、アプリ名を変えてください。他の人に使われている見たいなので。僕はアプリ名を「test-webapp01」としました。
terminal$ cd (eclipseのワークペースがあるパス)/webapp-test $ git init $ heroku create test-webapp01 $ git add . $ git commit -m "first upload" $ git push heroku master (もしくは git push -f heroku master)
このようにBUILD SUCCESSと出ていると、成功していると思います。
以下コマンドで開いて確認してください。今回はここまでにします。terminal$ heroku open終わりに
今回は書籍管理アプリを作るための準備とテストアプリの作成・公開しました。
コードの詳しい説明などは次回以降にやっていく予定で、いよいよ書籍管理アプリを作っていこうと思います。次回へ続く > Spring Bootで書籍管理Webアプリを作ろう part2
参考サイト
EclipseでSpring Frameworkを利用してみる
- 投稿日:2020-07-27T15:06:23+09:00
Spring Bootで書籍管理Webアプリを作ろうpart1
はじめに
どうも、プログラミング勉強中の大学生、ikuto19です。今回は勉強がてらにJavaのSpring Bootを使った簡易的な書籍管理webアプリを作ろうと思います。
以前、JavaではなくPythonで作成したんですが個人的に納得のいかない点があったので、作り直そうを思いました。その納得がいかない点というのは下記のようなものです。
- Pythonはサーバーサイド言語として不向き
- 無料で自作アプリを公開したい
サーバーサイドのプログラミング言語として使われているのはRuby、Java、PHPの三つが多い気がします。ネットで調べてもこの三つどれかが使われているのが大半みたいです。(個人調べ)
Pythonはサーバーサイドではなく、AIやディープラーニングといったものやデータサイエンスが得意なプログラミング言語です。なのにwebアプリのサーバーサイド言語として使っても、あまり使わないのであれば勉強にならないと思ったので、今回はJavaで作り直すという考えに至ったわけです。あと無料で自作アプリを公開できないかな?と調べた結果、Herokuというサービスがあることを知ったのも理由の一つです。
もし、載せている情報が間違っていたり、説明不足があれば、気にせず指摘してくださって構いません。この記事は自分の勉強のためであり、僕と同じように躓いている人に向けたものです。ですので、よろしくお願い致します。
前提条件
- macOS Catalina(バージョン10.15.5)
- Eclipse Version: 2020-03
- サーバーサイド言語: Java
- フロントエンド言語: HTML、CSS、Javascript(jQuery)
- データベース: MySQL(HerokuではclearDBというアドオンからMySQLを使用)
- Webアプリケーションフレームワーク: Spring FrameworkのSpring boot
- ビルドツール: maven
- 書籍管理API: openBD
- webアプリの公開サービス: heroku
各ツールやプロジェクトについて
Spring Frameworkについて
公式サイト → https://spring.io/
Spring FrameworkはJavaによる開発をスピーディーに安全に開発するためのフレームワークで、Springというふうに読んだりもするみたいです。このSpringは「DI:依存性注入」と「AOP:アスペクト指向プログラミング」を特徴にもっています。mavenについて
公式サイト → https://maven.apache.org/
mavenは複数あるビルドツールうちの一つです。他にはGradleやAntがありますが、今回はHerokuに完成したアプリをデプロイするのでmavenを選びました。pom.xmlに依存関係を記述することで、いろんなパッケージを扱えるようになります。openBDについて
公式サイト → https://openbd.jp/
このopenBDは書誌情報や表紙を誰でもアクセスできる無料のAPIです。
今回はjavascriptのjQueryでこのAPIを使って書籍情報にアクセスします。herokuについて
公式サイト → https://jp.heroku.com/about
コンテナベースのクラウド型PaaSで、多数のプログラミング言語から選んでき、自作アプリをデプロイ・管理することができるサービス。ツールの導入
インストール済みのeclipseへSpring プロジェクトをインストール
- eclipse起動後、ヘルプ > eclipse マーケットプレースからSpring Tools 4(aka Spring Tool Suite 4) 4.7.0.RELEASEをインストール
- 全てのチェックボックスにチェックしたまま、確認
- 「使用条件の条項に同意します」にチェックを入れて完了
- 「再起動しますか?」と聞かれるのでそのまま再起動する。
もし、セキュリティ警告で「信頼性または有効性を確立できない署名されていないソフトウェアをインストールします。インストールを続行しますか?」と表示されたら、インストールボタンをクリック。
Herokuへの登録およびクレカの登録
Herokuでアカウント作成
サインアップ → https://signup.heroku.com/login
1. 上記で必要項目を入力し、アカウント作成
2. 確認メールが来るので、クリックしてパスワードを設定ここまでできていると、ダッシュボード画面になっていると思います。
MySQL利用のためにクレジットカードの登録
HerokuではデフォルトのデータベースがPostgreSQLなので、MySQLにする際はclearDBという無料のアドオンを追加する必要があります。ですが、そのためにはクレジットカードの登録をする必要があるので、登録します。
- ダッシュボード画面から右上端のアイコンからAccount settingsをクリック
- BillingタブからBilling Informationの「Add credit card」をクリック
- 必要項目を入力して、Save Detailsをクリック
テストアプリの作成・実行とherokuでの公開
テストアプリの作成
一応、作成手順を載せておきますが、GitHubにプロジェクトをあげているので、以下のコマンドダウンロードしてくださっても構いません。
terminal$ git clone https://github.com/ikuto19/test-webapp.git作成手順
- eclipse起動後、パッケージ・エクスプローラーで右クリック
- 新規 > プロジェクトをクリック
- Spring BootのSpring スターター・プロジェクトを選択し、「次へ」をクリック
- 名前を「webapp-test」、グループとパッケージを「com.app」にして、「次へ」をクリック
- 依存関係のテンプレート・エンジンからThymeleafとwebからSpring Webにチェックして、「完了」をクリック
プロジェクトの中身を確認すると、以下の画像のような構成になっていると思います。もし、templatesフォルダがなければ追加で作っておいてください。
次に以下の構成で新規のファイルを作成または既存のファイルを削除します。
各ファイルの中身は以下のように記述します。
App.javapackage com.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }IndexController.javapackage com.app.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { @GetMapping("/") public String getIndexPage(Model model) { String message = "Hello, World!!"; model.addAttribute("message",message); return "index"; } }index.html<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <meta charset="UTF-8"> <head> <title>テストアプリ</title> </head> <body> <p th:text="${message}"></p> </body> </html>Procfileweb: java $JAVA_OPTS -jar target/*.jar --server.port=$PORT実行確認
パッケージ・エクスプローラーのApp.javaを選択したまま右クリックで、実行 > Spring Bootアプリケーションをクリックして、実行。
webブラウザで http://localhost:8080/ にアクセスすると、下記のような画像が表示される。
Herokuへデプロイ
以下のコマンドを順に実行
「heroku login」を実行後に何かキーを押すと、webブラウザにとばされるので、「Log IN」ボタンをクリックterminal$ brew tap heroku/brew && brew install heroku $ heroku logincreateコマンドで「Name test-webapp is already taken」のようなエラーが出る場合、アプリ名を変えてください。他の人に使われている見たいなので。僕はアプリ名を「test-webapp01」としました。
terminal$ cd (eclipseのワークペースがあるパス)/webapp-test $ git init $ heroku create test-webapp01 $ git add . $ git commit -m "first upload" $ git push heroku master (もしくは git push -f heroku master)
このようにBUILD SUCCESSと出ていると、成功していると思います。
以下コマンドで開いて確認してください。今回はここまでにします。terminal$ heroku open終わりに
今回は書籍管理アプリを作るための準備とテストアプリの作成・公開しました。
コードの詳しい説明などは次回以降にやっていく予定で、いよいよ書籍管理アプリを作っていこうと思います。次回へ続く > 近々投稿
参考サイト
EclipseでSpring Frameworkを利用してみる
- 投稿日:2020-07-27T14:02:26+09:00
Railsのmysql接続でユーザー権限がなくconnection errorになるときの対処法
- 投稿日:2020-07-27T12:57:35+09:00
gRPC, Spring Boot, Kotlin,MySQLで作ったSNSアプリ(通話、チャット)のAPIサンプル
どんなアプリのAPIか。
- チャット、通話機能があるSNSアプリのAPIです。
- ユーザー登録、プッシュ通知、ブロック・通報機能などのsnsアプリに必要な一通りのAPIを実装しています。
システムの構成
- フレームワーク:Spring Boot
- 言語:Kotlin
- API:Protocol Buffersで定義、gRPCで実装。
- DB:MySQL
コード
https://github.com/yusuke-imagawa/talking-sns-api-sample
コメント
- gRPC, Protocol Buffersがどんなものかは他に沢山情報があるので省略します。
- 画像ファイルのアップロードはこのサンプルに含みません。
- iOSプッシュ通知の用のp8ファイルや、その他の認証用の文字列は無効なものになっています。
APIの一覧
アカウント
- ユーザー登録
- プロフィール編集
- 退会
ユーザー情報:
- ユーザーのリスト取得
- 指定したidのユーザーを取得
通話
- 通話を開始。(電話を掛ける)
- 通話を受ける。
- 通話を切る。
- 通話が継続していることを記録。
- 通話のステータス受信(開始、通話中、終了)
チャット
- メッセージ送信
- メッセージ受信
- すべてのメッセージを取得
プッシュ通知
- デバイストークン_iOS / 登録, 更新
- ON/OFF更新
その他
- ユーザーをブロック
- ユーザーを通報
Protocol BuffersによるAPI仕様定義
- account.proto
- block.proto
- calling.proto
- chat.proto
- commons.proto
- push_notify.proto
- report.proto
- user.proto
API(gRPC)のコントローラークラス
- AccountGrpcService
- AccountRegisterGrpcService
- BlockGrpcService
- CallingGrpcService
- ChatGrpcService
- PushNotifyGrpcService
- ReportGrpcService
- UserGrpcService
build.gradle: protoファイルから、APIのソースを生成
https://github.com/yusuke-imagawa/talking-sns-api-sample/blob/master/build.gradle
group 'com.talking' // gRPCのコード生成コマンド: ./gradlew generateProto // ドキュメント: gRPCの実装 // https://github.com/LogNet/grpc-spring-boot-starter buildscript { ext.kotlin_version = '1.3.61' // Required for Kotlin integration ext.spring_boot_version = '2.2.0.RELEASE' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // Required for Kotlin integration classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#spring-support classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version" classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.5" } } apply plugin: 'kotlin' // Required for Kotlin integration apply plugin: "kotlin-spring" // https://kotlinlang.org/docs/reference/compiler-plugins.html#spring-support apply plugin: 'org.springframework.boot' apply plugin: 'com.google.protobuf' def grpcVersion = '1.25.0' repositories { mavenCentral() } sourceSets { main.kotlin.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/java' main.java.srcDirs += 'src/main/generated-proto' } dependencies { compile("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") compile("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") // testCompile('org.springframework.boot:spring-boot-starter-test') // for web compile("org.springframework.boot:spring-boot-starter-web:$spring_boot_version") compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8") // for db compile("org.springframework.boot:spring-boot-starter-data-jpa:$spring_boot_version") runtime("mysql:mysql-connector-java:8.0.15") compile("org.springframework.boot:spring-boot-starter-security:$spring_boot_version") // grpc compile("io.github.lognet:grpc-spring-boot-starter:3.5.0") compile "io.grpc:grpc-api:${grpcVersion}" compile "io.netty:netty-codec-http2:4.1.42.Final" compile "io.grpc:grpc-core:${grpcVersion}" compile "io.grpc:grpc-protobuf:${grpcVersion}" compile "io.grpc:grpc-stub:${grpcVersion}" // cache compile(group: 'com.github.ben-manes.caffeine', name: 'caffeine', version: '2.8.1') // iOSプッシュ通知 compile(group: 'com.eatthepath', name: 'pushy', version: '0.13.11') } compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } protobuf { protoc { artifact = "com.google.protobuf:protoc:3.5.0" } plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } } generateProtoTasks { all().each { task -> task.builtins { java { outputSubDir = 'generated-proto' } } task.plugins { grpc { outputSubDir = 'generated-proto' } } } } generatedFilesBaseDir = "$projectDir/src/" }ddl
https://github.com/yusuke-imagawa/talking-sns-api-sample/blob/master/docs/DB/ddl.sql
テーブル
- ユーザー
- プロフィール画像
- チャット
- 通話履歴
- 通報
- ブロック
- プッシュ通知デバイストークン_iOS
工夫したところ
ログインしているユーザーしか利用できないAPIの認証処理を共通化
AuthInterceptor内でrequestのheader内のtoken,userIdで認証。
@Component class AuthInterceptor : ServerInterceptor { @Autowired private lateinit var userService: UserService // 参考ソース: // https://github.com/saturnism/grpc-by-example-java/blob/master/metadata-context-example/src/main/java/com/example/grpc/server/JwtServerInterceptor.java override fun <ReqT : Any?, RespT : Any?> interceptCall( call: ServerCall<ReqT, RespT>, headers: Metadata, next: ServerCallHandler<ReqT, RespT> ): ServerCall.Listener<ReqT> { val userId = headers.get(GrpcConstant.USER_ID_METADATA_KEY)?.toLong() ?: throw StatusRuntimeException(Status.UNAUTHENTICATED, headers) val apiToken = headers.get(GrpcConstant.API_TOKEN_METADATA_KEY) ?: throw StatusRuntimeException(Status.UNAUTHENTICATED, headers) val user = userService.findByIdAndToken(userId, apiToken) ?: throw StatusRuntimeException(Status.UNAUTHENTICATED, headers) val ctx = Context.current().withValue(GrpcConstant.AUTH_USER_CONTEXT_KEY, user) return Contexts.interceptCall(ctx, call, headers, next) } }認証処理を利用したいAPIのクラスにAuthInterceptorを設定
https://github.com/yusuke-imagawa/talking-sns-api-sample/blob/master/src/main/kotlin/com/talking/api/grpc/AccountGrpcService.kt@GRpcService(interceptors = [AuthInterceptor::class]) class AccountGrpcService: AccountServiceGrpc.AccountServiceImplBase() {
- 投稿日:2020-07-27T00:21:10+09:00
MySQLでユーザーを作成するときにパスワードを簡単なものに設定できるようにする
MySQLのバージョン確認
mysql> select version(); +-----------+ | version() | +-----------+ | 8.0.19 | +-----------+ユーザーを追加する
mysql> create user dbuser01@localhost identified by '6AVAkig2'; ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
password : 6AVAkig2
ランダムに選んだ文字列。
かつ
数字、大文字、小文字
が入っていますが、エラーになります。mysql> set global validate_password.policy=Low;これにすれば文字数だけ満たせば大丈夫。
8文字以上なら小文字だけでも大丈夫なはず。デフォルト値は変更できない
いったんMySQLを終了してからもう一回管理者で入ってユーザーを作成しようとしても、
alidate_password.policyの値がMidiumに戻って、特殊文字も入れないといけない設定に戻っちゃう。困っちゃう。