20191001のMySQLに関する記事は7件です。

【Oracle】DBA_SOURCEからソース文を綺麗に抽出して表示する

最近業務関連でOracleやMySQLを使用することが増えて色々調べ物をする機会があったので、その際のちょっとした忘備録

ストアド・プロシージャのテキストソースを調べるには...

ViewのテキストはDBA_VIEWSの中にデータがあるが、DBA_PROCEDURESには類似のカラムは存在しない。
プロシージャやファンクションのテキストを知りたいときはDBA_SOURCESから抽出する必要がある。

DBA_SOURCES
Oracle公式のドキュメントはこちら

公式ドキュメントを参照していただいてもわかるかと思うが、DBA_SOURCESはテキストソース1行ずつをデータとして持っている。
そのため、

badExample
  select * from dba_sources where name="***"

単純に抽出するのではダメで、

goodExample
  select text from dba_sources where name="***" order by line

綺麗に抽出する場合は逐一このようにtextだけをlineカラムでソートして表示する必要がある。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL上でRuby on Rails + MySQLの環境づくり

はじめに と 注意

Ruby on Rails + MySQLの環境構築をしていく記事です。

先人様の記事の内容を主に進めていって、エラーが出たとこの解決策を書いてます。

初記事なのでやさしい目で見てください。

背景

Rails + MySQL でアプリ作ってみたいけど環境構築で意味わかんないエラー出ちゃった。

全部Windowsのせいにしよう(逃避)。

でもmac持ってない......WSLならできるかな...?

(ちなみに過去にWSL上で開発環境整えようとして失敗した。)

対象

  • WSL上でRuby on Railsの開発をしたい!
  • SQLiteじゃなくてMySQLでやりたいけど環境構築わかんね!

という方向け。

環境

  • Windows 10 Home 64bit
  • WSL( Windows Subsystem for Linux ) Ubuntu 18.04.3 LTS

1. WSLにRuby on Rails環境を整える

さっそく他人様まかせで申し訳ないですが

とても、とても素晴らしい記事があるので
ほぼこれを参考にやっていきます...

※一部別の方法でインストールする部分があるのでリンク先とこの記事を見比べながら作業してください。
(一個一個のインストールに割と時間かかるので気長に待ちましょう。特にrubyのインストール)

少し変更を加える部分 (と軽いhelp)

「2. Node.jsを入れよう」部分

nodejsを導入する際の

sudo apt-get install npm

というコマンドだとnodeおよびnpmのバージョンが最新ではないためやり方を変更。

間違えて入れちゃったというひとも指示に従ってすれば大丈夫(たぶん)

さあ説明を読むぞって思ったひとにはごめんなさい。この記事が神。

- 続・WSL(Ubuntu)でnode.jsの開発をする準備

さっきのコマンドで入れちゃったって人は「削除する」って項目からやってください。

もう1つ

WSLを再起動とかするとnode -vをしたときにnot found エラーが起きるかも。
そういうときは

export PATH=$HOME/.nodebrew/current/bin:$PATH

を vim かなんかで~/.bashrcに追記して試してみてください。

vim で追記する方法は下の方。

「3. rbenvを入れよう」部分

たいしたことではないですが最後の方で

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

を ~/.bashrc に追記する(厳密には上の1行はすでに追記されているはず)手順があります。

「どうやって!?」と思った方は下の方に書いてある「.bashrcに追記ってどうするの!!」を見て追記してみてください。

「5. Rubyを入れよう」部分

本当に時間かかります。環境にもよると思うけれど僕は2~30分かかりました(笑)

解決策?

  • 普通は長くて10分くらいらしいのでいったん待ってみる。
  • "rbenv install ruby 遅い"でググって出てきたのを試す

BUILED ERROR!! となる人へ

僕も一度なりました。エラー文中に

Try ~~~ `apt -------` 

といった感じであったので(詳細なエラー文コピー取るの忘れてました;;)、

それに従ってコマンド実行すると治りました。

.bashrcに追記ってどうするの!!

下のコマンドで、vim で .bashrc を開いて一番下とかに追記していく。

vim ~/.bashrc

vim の使い方はこちらでどうぞ

- 知識0から始めるVim講座

2. Ruby on Rails + MySQL

Ruby on Railsの環境構築お疲れさまでした。

僕自身この記事を書きながらやっていたら3時間程度たっていました...笑

ということで次はMySQLです。

MySQLのインストール

まずはMySQLをインストールしていきます。が、ここでもとても良い記事を見つけました。

- WSLのUbuntu 18.04でMySQL 5.7をセットアップ

これ通りに行えばエラーなく行けるはずですが、

過去にMySQLいれたことある人や間違えちゃった人はエラーが起こるかも。(体験談)

僕の場合はWSL上からきれいにMySQLを消してもう一回やればいけました。

過去のMySQL関連のファイルとか消したくないって人以外は下記コマンドを実行しましょう。

sudo apt-get remove --purge mysql-*
sudo apt-get autoremove --purge 
sudo rm -r /etc/mysql
sudo rm -r /var/lib/mysql

MySQLが起動中だとうまく全ファイルを消せないので、

sudo service mysql stop

としてサーバを停止してから行ってください。
またサーバが止まらない!止められない!という方は
MySQLのプロセスを確認して

ps ax | grep mysql

でてきたプロセスを片っ端からkillしていけばサーバが停止します。

sudo kill プロセス番号

Railsと組み合わせる

MySQLのインストールが終わったのでRailsアプリケーションのデータベースをMySQLとして作っていきます。

まずはRailsで使うMySQLのアカウントを作ります!

rootでログインして、

 mysql -u root -p

現在あるアカウントをチェック

 select User,Host from mysql.user;

+------------------+-----------+
| User             | Host      |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+

Rails用のアカウントを作ってチェック

create user 'ユーザネーム'@'localhost' identified by 'パスワード';
select User,Host from mysql.user;

+------------------+-----------+
| User             | Host      |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| railsuser        | localhost |
| root             | localhost |
+------------------+-----------+

ちゃんと追加されました!

次はRails上でMySQLを使うためのgemをインストールしていきます。

gem install mysql2

しかしここでエラー

 ERROR: Error installing mysql2:
        ERROR: Failed to build gem native extension.
-省略-
mysql client is missing. You may need to 'apt-get install libmysqlclient-dev'  or 'yum install mysql-devel', and try again.
 -省略-

指示に従って、一応sudoをつけて...

 sudo apt-get install libmysqlclient-dev

もう一回..!

 $ gem install mysql2
Building native extensions. This could take a while...

...

Done installing documentation for mysql2 after 0 seconds
1 gem installed

通りました。

次にデータベースをMySQLに指定したRailsアプリケーションを作成。名前は適当。

 rails new mysql-app -d mysql

次にデータベース設定ファイルの書き換えをします。

Ruby on Railsの環境を構築したときにシンボリックリンクを設定したフォルダがあると思うのでそこに先ほど作ったRailsアプリケーションを移動。

最初からそこでrails newすればよかったのでは?

 mv アプリの名前 移動先 -r

vscodeを起動

ファイル > フォルダを開く > Railsアプリ(僕の場合mysql-app)

を選択してvscodeで開く。

config > database.yml を開いて自分の登録したユーザネームとパスワードを入力します。

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: [ユーザネーム]
  password: [パスワード]
  socket: /var/run/mysqld/mysqld.sock

development:
  <<: *default
  database: mysql_app_development

test:
  <<: *default
  database: mysql_app_test

production:
  <<: *default
  database: mysql_app_production
  username: mysql_app
  password: <%= ENV['MYSQL_APP_DATABASE_PASSWORD'] %>

セーブ後データベースを作って

rails db:create

アプリケーションを起動して

rails s

ブラウザ(http://localhost:3000) で確認出来たら終了です!

お疲れさまでした。

a.jpg

参考
- Ruby on RailsでMySQLを使用・接続する際の手順と注意点
- RailsのDBを(初めから| |後から)MySQLに変更する

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

技術書典の本を検索できるアプリを作ってみた~サーバーサイド 編~

はじめに

この記事は、時間ができた学生が暇つぶしに「技術書典の本を検索できるアプリを作ってみた」というものです。
技術書典に参加する前にある程度購入する本を決めると思うのですが、その際に欲しい技術について書いてある本を探したいと思うはずです。サークル一覧から本を探すのはとても大変で時間が足りません。そこでスクレーピングしてデータ収集し、検索できるアプリを開発してみました(自己満)。
この記事ではサーバーサイドについて書きます。次の記事で「Androidアプリを作ってみた」を書きたいと思います。

サーバーサイドの流れ

  1. Pythonでデータを収集する
    I.技術書典のサークルリスト からURL情報を収集する
    II. 集めたURLにアクセスしてそれぞれのサークルが出している本の情報を収集する
  2. 収集したデータをDBに保存する
  3. Goでサーバーを立てる

1. Pythonでデータ収集

I. 技術書典のサークルリスト からURL情報を収集する

技術書典のサークルリストの<a>タグをひたすら保存するコード

collect_url.py
# coding: UTF-8
from bs4 import BeautifulSoup
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.chrome.options import Options

# ブラウザのオプションを格納する変数
options = Options()

# Headlessモードを有効にする
options.set_headless(True)

# ブラウザを起動する
driver = webdriver.Chrome(chrome_options=options)

# ブラウザでアクセスする
driver.get("https://techbookfest.org/event/tbf07/circle")

# HTMLを文字コードをUTF-8に変換してから取得
html = driver.page_source.encode('utf-8')

# BeautifulSoupで扱えるようにパース
soup = BeautifulSoup(html, "html.parser")

# ファイル出力
file_text = open("url_data.txt", "w")
elems = soup.find_all("a")
for elem in elems:
    print(elem.get('href'),file=file_text)
file_text.close()

II. 集めたURLにアクセスしてそれぞれのサークルが出している本の情報を収集する

1.で集めたURLにアクセスし、
出店しているサークル名、配置場所、ジャンル、ジャンル詳細、サークル画像、出品している本の名前、内容
のデータを収集する。(残念ながらペンネームは集められなかった。html にclass or idを貼って無いから面倒

collect_data.py
# coding: UTF-8
from bs4 import BeautifulSoup
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.chrome.options import Options
import pickle
import sys

# データを保存する
i = 0
sys.setrecursionlimit(10000)
with open('../data/getData.txt', 'wb') as ff:

    # 保存するデータ
    save_datas = []

    # ブラウザのオプションを格納する変数
    options = Options()

    # Headlessモードを有効にする
    options.set_headless(True)

    # ブラウザを起動する
    driver = webdriver.Chrome(chrome_options=options)

    urlHeader = "https://techbookfest.org"
    pathfile = "../data/url_data.txt"

    with open(pathfile) as f:
        for _path in f:
            i += 1
            url = urlHeader + _path
            print(i,url)
            # ブラウザでアクセスする
            driver.get(url)

            # HTMLを文字コードをUTF-8に変換してから取得
            html = driver.page_source.encode('utf-8')

            # BeautifulSoupで扱えるようにパース
            soup = BeautifulSoup(html, "html.parser")

            circle = soup.find(class_="circle-name").string
            arrange = soup.find(class_="circle-space-label").string
            genre = soup.find(class_="circle-genre-label").string
            keyword = soup.find(class_="circle-genre-free-format").string

            circle_image = soup.find(class_="circle-detail-image").find(class_="ng-star-inserted")

            book_title = []
            for a in soup.find_all(class_="mat-card-title"):
                book_title.append(a.string)

            book_content = []
            for a in soup.find_all(class_="products-description"):
                book_content.append(a.string)

            for title, content in zip(book_title, book_content):
                data = [circle,circle_image['src'],arrange,genre,keyword,title,content,url]
                save_datas.append(data)

    pickle.dump(save_datas,ff)

2. 収集したデータをDBに保存する

ファイルに保存したデータを取得し、MySQLにInsertするだけのプログラムです。Insertするだけなので適当なプログラムになってしまった。

insertDB.py
# coding: UTF-8
import MySQLdb
import pickle

# データベースへの接続とカーソルの生成
connection = MySQLdb.connect(
    host='0.0.0.0',
    user='user',
    passwd='password',
    db='techBook')
cursor = connection.cursor()

# id, circle, circle_image, arr, genere, keyword, title, content
with open('../data/getData.txt','rb') as f:
    load_datas = pickle.load(f)
    for load_data in load_datas:
        data = []
        if load_data[6] == None:
            for dd in load_data:
                if dd == None:
                    continue
                dd = dd.replace('\'','')
                data.append(dd)
            sql = "INSERT INTO circle (circle, circle_image, arr, genere, keyword, title, circle_url) values ('" + data[0] + "','" + data[1] + "','" + data[2]+"','" + data[3]+"','" + data[4]+"','" + data[5]+"','" + data[6]+"')"
        else:
            for dd in load_data:
                dd = dd.replace('\'','')
                data.append(dd)
            sql = "INSERT INTO circle (circle, circle_image, arr, genere, keyword, title, content, circle_url) values ('" + data[0] + "','" + data[1] + "','" + data[2]+"','" + data[3]+"','" + data[4]+"','" + data[5]+"','" + data[6]+"','" + data[7]+"')"
            print(sql)
        cursor.execute(sql)

# 保存を実行
connection.commit()

# 接続を閉じる
connection.close()

3. Goでサーバーを立てる

Pythonで書いてもよかったのですが、気分的にGoで書きました。
レイアードアーキテクチャで書いています。(宣伝)
ファイル数が多いので全部載せることはできませんでした。Githubを参照ください。
検索はSQLの部分一致検索で行います。

SELECT * FROM circle where content like '%swift%';

取得したデータをjson形式で返して終わりです!!

[request] 
{
"keyword":"..."
}

[response]
{
    "result": [
        {
            "CircleURL": "...",
            "Circle": "...",
            "CircleImage": "...",
            "arr": "...",
            "Genere": "...",
            "Keyword": "...",
            "Title": "...",
            "Content": "..."
        },
    ]
}

終わりに

久々にPythonを書いた気がします。全体的に書いてて楽しかったです。今回書いたコードはこちら
読んでいただきありがとうございました。次回のAndroid編をお楽しみに!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

技術書典の本を検索できるアプリを作ってみた~サーバーサイド 編(Python, Go)~

はじめに

この記事は、時間ができた学生が暇つぶしに「技術書典の本を検索できるアプリを作ってみた」というものです。
技術書典に参加する前にある程度購入する本を決めると思うのですが、その際に欲しい技術について書いてある本を探したいと思うはずです。サークル一覧から本を探すのはとても大変で時間が足りません。そこでスクレーピングしてデータ収集し、検索できるアプリを開発してみました(自己満)。
この記事ではサーバーサイドについて書きます。次の記事で「Androidアプリを作ってみた」を書きたいと思います。

サーバーサイドの流れ

  1. Pythonでデータを収集する
    I.技術書典のサークルリスト からURL情報を収集する
    II. 集めたURLにアクセスしてそれぞれのサークルが出している本の情報を収集する
  2. 収集したデータをDBに保存する
  3. Goでサーバーを立てる

1. Pythonでデータ収集

I. 技術書典のサークルリスト からURL情報を収集する

技術書典のサークルリストの<a>タグをひたすら保存するコード

collect_url.py
# coding: UTF-8
from bs4 import BeautifulSoup
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.chrome.options import Options

# ブラウザのオプションを格納する変数
options = Options()

# Headlessモードを有効にする
options.set_headless(True)

# ブラウザを起動する
driver = webdriver.Chrome(chrome_options=options)

# ブラウザでアクセスする
driver.get("https://techbookfest.org/event/tbf07/circle")

# HTMLを文字コードをUTF-8に変換してから取得
html = driver.page_source.encode('utf-8')

# BeautifulSoupで扱えるようにパース
soup = BeautifulSoup(html, "html.parser")

# ファイル出力
file_text = open("url_data.txt", "w")
elems = soup.find_all("a")
for elem in elems:
    print(elem.get('href'),file=file_text)
file_text.close()

II. 集めたURLにアクセスしてそれぞれのサークルが出している本の情報を収集する

1.で集めたURLにアクセスし、
出店しているサークル名、配置場所、ジャンル、ジャンル詳細、サークル画像、出品している本の名前、内容
のデータを収集する。(残念ながらペンネームは集められなかった。html にclass or idを貼って無いから面倒

collect_data.py
# coding: UTF-8
from bs4 import BeautifulSoup
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.chrome.options import Options
import pickle
import sys

# データを保存する
i = 0
sys.setrecursionlimit(10000)
with open('../data/getData.txt', 'wb') as ff:

    # 保存するデータ
    save_datas = []

    # ブラウザのオプションを格納する変数
    options = Options()

    # Headlessモードを有効にする
    options.set_headless(True)

    # ブラウザを起動する
    driver = webdriver.Chrome(chrome_options=options)

    urlHeader = "https://techbookfest.org"
    pathfile = "../data/url_data.txt"

    with open(pathfile) as f:
        for _path in f:
            i += 1
            url = urlHeader + _path
            print(i,url)
            # ブラウザでアクセスする
            driver.get(url)

            # HTMLを文字コードをUTF-8に変換してから取得
            html = driver.page_source.encode('utf-8')

            # BeautifulSoupで扱えるようにパース
            soup = BeautifulSoup(html, "html.parser")

            circle = soup.find(class_="circle-name").string
            arrange = soup.find(class_="circle-space-label").string
            genre = soup.find(class_="circle-genre-label").string
            keyword = soup.find(class_="circle-genre-free-format").string

            circle_image = soup.find(class_="circle-detail-image").find(class_="ng-star-inserted")

            book_title = []
            for a in soup.find_all(class_="mat-card-title"):
                book_title.append(a.string)

            book_content = []
            for a in soup.find_all(class_="products-description"):
                book_content.append(a.string)

            for title, content in zip(book_title, book_content):
                data = [circle,circle_image['src'],arrange,genre,keyword,title,content,url]
                save_datas.append(data)

    pickle.dump(save_datas,ff)

2. 収集したデータをDBに保存する

ファイルに保存したデータを取得し、MySQLにInsertするだけのプログラムです。Insertするだけなので適当なプログラムになってしまった。

insertDB.py
# coding: UTF-8
import MySQLdb
import pickle

# データベースへの接続とカーソルの生成
connection = MySQLdb.connect(
    host='0.0.0.0',
    user='user',
    passwd='password',
    db='techBook')
cursor = connection.cursor()

# id, circle, circle_image, arr, genere, keyword, title, content
with open('../data/getData.txt','rb') as f:
    load_datas = pickle.load(f)
    for load_data in load_datas:
        data = []
        if load_data[6] == None:
            for dd in load_data:
                if dd == None:
                    continue
                dd = dd.replace('\'','')
                data.append(dd)
            sql = "INSERT INTO circle (circle, circle_image, arr, genere, keyword, title, circle_url) values ('" + data[0] + "','" + data[1] + "','" + data[2]+"','" + data[3]+"','" + data[4]+"','" + data[5]+"','" + data[6]+"')"
        else:
            for dd in load_data:
                dd = dd.replace('\'','')
                data.append(dd)
            sql = "INSERT INTO circle (circle, circle_image, arr, genere, keyword, title, content, circle_url) values ('" + data[0] + "','" + data[1] + "','" + data[2]+"','" + data[3]+"','" + data[4]+"','" + data[5]+"','" + data[6]+"','" + data[7]+"')"
            print(sql)
        cursor.execute(sql)

# 保存を実行
connection.commit()

# 接続を閉じる
connection.close()

3. Goでサーバーを立てる

Pythonで書いてもよかったのですが、気分的にGoで書きました。
レイアードアーキテクチャで書いています。(宣伝)
ファイル数が多いので全部載せることはできませんでした。Githubを参照ください。
検索はSQLの部分一致検索で行います。

SELECT * FROM circle where content like '%swift%';

取得したデータをjson形式で返して終わりです!!

[request] 
{
"keyword":"..."
}

[response]
{
    "result": [
        {
            "CircleURL": "...",
            "Circle": "...",
            "CircleImage": "...",
            "arr": "...",
            "Genere": "...",
            "Keyword": "...",
            "Title": "...",
            "Content": "..."
        },
    ]
}

終わりに

久々にPythonを書いた気がします。全体的に書いてて楽しかったです。今回書いたコードはこちら
読んでいただきありがとうございました。次回のAndroid編をお楽しみに!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MySQLでSELECT文の結果に固定値を入れる

SELECT文の結果に固定値を入れる

以下のようにすることで、select文の結果に固定値を入れることが出来ます。

sql
SELECT id, name, email, '固定値' AS label FROM users;

実際に以下のようなSQLを実行すると

sql
SELECT id, name, 'ゲスト' AS label FROM users;

以下のように固定値が入ります。

id name label
1 一郎 ゲスト
2 次郎 ゲスト
3 三郎 ゲスト

では、どんなときに使うかですが次に示します。

INSERT文と組み合わせると便利

SELECT結果の固定値はINSERT文と組み合わせると便利です。

sql
INSERT INTO wainting_users (id, name, label) SELECT id, name, 'ゲスト' AS label FROM users;

INSERT文と合わせることでSELECT文の結果につけたいカラムの情報を固定値で追加してINSERTすることが出来ます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DjangoでMySQLに繋いだ後にAdminにログインできなくなった時の解決法

背景

ローカルで一通り開発した後によっしゃGAEのMYSQLに繋ぐか!ってなった時に繋いでmigrateしたらerrorが出てしかもadminにログイン出来ない!となった。

実際のエラー内容は
table django_session doesn't exist

環境

MacOS Mojave 10.14
Python 3.7.3
Django 2.2

原因探し

とりあえずpython manage.py showmigrationsしてみたら

$ python3 manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
blog
 [ ] 0001_initial
 [ ] 0002_auto_20190912_2307
 [ ] 0003_auto_20190912_2314
 [ ] 0004_auto_20191001_1124
sessions
 [ ] 0001_initial

こんな感じ。
そもそもmigrateをした時にblogで詰まっていた為そのあとのsessionsが実行されていないために起こっていたerrorみたいですね。

応急処置

sessionsがmigrateされればとりあえずadminにログインできるようになるだろうという仮説を立てて、

python3 manage.py migrate sessions

をやってみると

Operations to perform:
  Apply all migrations: sessions
Running migrations:
  Applying sessions.0001_initial... OK

と出て実際にログインもできたのでとりあえず応急処置的になんとかするならこれで大丈夫かと。

blogのmodel.pyをしっかり書けていればそもそも発生しなかった現象なのでもう一度modelの書き方をしっかり学び直そうと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

macでdocker-composeを使ってPHPとnginxをすぐに使えるようにする方法

PHPの勉強用に「折角だからnginxをdockerで立てて使おう〜」と軽い気持ちでコンテナ立てて実行しようとしたところ「コンテナのnginxのドキュメントルートにどうやってファイル置くんだろ。」とか「もしかしてコンテナ入って置かないとダメ?」とか前知識が無くて全然うまく行かず。。

docker-composeを使って速攻で準備

出来ねぇ出来ねぇボヤいてたらwebエンジニアにdocker-composeを使って速攻でその辺の環境を作る方法を教えてもらいました。
コンテナを立てたい場所に下記のdocker-compose.ymlファイルを作成します。

[docker-compose.yml]

### nginxでphpをブラウザ上に表記するのに必要なコンテナ一式。
version: '3'
services:
  app:
    image: laradock/php-fpm:2.2-7.2
    # ローカルのカレントディレクトリに格納したファイルをコンテナの/var/phpappにマウントする
    volumes:
      - ./:/var/phpapp/

  nginx:
    image: nginx:latest
    # 8080ポートから来た接続をコンテナの80番ポートに連携する
    ports:
      - "8080:80"
    volumes:
      # ローカルの./docker/nginx/nginx.confのをnginxコンテナの/etc/nginx/conf.d/default.confにマウントする
      - ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      # ローカルカレントディレクトリをコンテナの/var/phpappにマウント
      - ./:/var/phpapp/

  mysql:
    image: mysql:5.7
    # 33306ポートから来た接続をコンテナの3306番ポートに連携する
    ports:
      - 33306:3306
    volumes:
      - ./testdata/:/data
    environment:
        MYSQL_DATABASE: app
        MYSQL_ROOT_PASSWORD: root

あとnginx.confの内容を下記にします。
これはローカルの.docker/nginx/nginx.confに作成してください。

[nginx.conf]

server {
  listen 80;
  server_name localhost;
  root  /var/phpapp/web;
  index index.php index.html;
  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ \.php$ {
    fastcgi_pass   app:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
  }
}

nginx.confの方は深く説明しませんが、この設定にしておけばローカルのカレントディレクトリのwebフォルダに格納したPHPファイルはちゃんと処理されてブラウザ上で表示されます。

あとはdocker-composeファイルを起動させれば準備完了します!

$ docker-compose up -d

出来たものはこちらです。

$ docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                                NAMES
04e0f98cc4ef        mysql:5.7                  "docker-entrypoint.s…"   7 hours ago         Up 7 hours          33060/tcp, 0.0.0.0:33306->3306/tcp   memo_keizi_mysql_1
8c0639887fb3        laradock/php-fpm:2.2-7.2   "docker-php-entrypoi…"   23 hours ago        Up 23 hours         9000/tcp                             memo_keizi_app_1
c3574c4c67b9        nginx:latest               "nginx -g 'daemon of…"   34 hours ago        Up 33 hours         0.0.0.0:8080->80/tcp                 memo_keizi_nginx_1

IMAGEのところがdocker-composeのimageで記述したものになっています。

PHPをブラウザで表示させるところまで確認する

折角なので格納したPHPファイルがブラウザ上で表示されるところまで確認します。
※今回MySQLは使用しません。

nginx.confで設定したroot /var/phpapp/web;によりwebフォルダがドキュメントルートになります。
カレントディレクトリにwebフォルダを作成し、PHPファイルを格納します。

$ ls web/
index.php

ファイルの内容はありきたりですが、Hello World出力で。。

[index.php]
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <?php echo '<p>Hello World</p>'; ?> 
 </body>
</html>

http://localhost:8080/でアクセスすると、、

image.png

問題なく出力されました。
このwebフォルダにPHPのファイルを入れてパス指定すれば問題なく起動します。

終わりに

半端な知識で「nginxはコンテナで!PHPはローカルに入ってるからそれで勝手に処理してくれるでしょ!」くらいの軽い気持ちでやったら泥沼でした。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む