「Laravel(+Vue.js)でSNS風Webサービスを作ろう!」をWindows+Laradock+PostgreSQL(永続化対応)でやってみた

はじめに

共同開発でこの教材を試してみることになったのでLaradockの環境構築に挑戦してみました。

今回は起動までです。ボリュームコンテナを使った永続化はまだできておりません。

⇒5/23追記:PostgreSQLでの永続化までできました。こちらの記事は長くなってしまったので別記事でまとめています。

Docker学んでみた

✅ゴール
・Laradockの理解を深める

✅環境
Windows/Laradock

✅参考教材
Laravel(+Vue.js)でSNS風Webサービスを作ろう!

※2か月前は思いっきり挫折しましたがとりあえず今回起動まですることができました。

Docker for Windowsでpostgresのデータマウントができない人へ

永続化するには上記の記事を参考にdocker volume create –name <db名>するしかなさそう。

【Laravel】Docker for WindowsでLaradock(+PostgreSQL)に挑戦してみた。

Laradock環境構築

①Laradockのインストール

mkdir laravel-sns
git clone https://github.com/Laradock/laradock.git -b v9.6

②Laradockの.envファイルを作成する

cd laradock
cp env-example .env

③.envファイルを編集

変更前

APP_CODE_PATH_HOST=../
DATA_PATH_HOST=~/.laradock/data
COMPOSE_PROJECT_NAME=laradock

変更後

APP_CODE_PATH_HOST=../laravel
DATA_PATH_HOST=../data
COMPOSE_PROJECT_NAME=laravel-sns

※以下の場所です

④laradock/postgres/Dockerfileの編集

変更前

FROM postgres:alpine

変更後

FROM postgres:11.6

⑤コンテナ起動

※Laradockディレクトリにて

\laravel-sns\laradock> docker-compose up -d workspace php-fpm nginx postgres
>> Creating laravel-sns_docker-in-docker_1 ... done
   Creating laravel-sns_postgres_1         ... done
   Creating laravel-sns_workspace_1        ... done
   Creating laravel-sns_php-fpm_1          ... done
   Creating laravel-sns_nginx_1            ... done

⑥サーバー確認

http://localhost/へアクセス。

⑦プロジェクト生成

※docker-composeコマンドはLaradockディレクトリに移動した上で実行すること。

\laravel-sns\laradock> docker-compose exec workspace composer create-project --prefer-dist laravel/laravel . "6.8.*"

再度http://localhost/へアクセス。

現状のディレクトリ構造はこんな感じ。

laravel-sns
 - .vscode
 - data // postgresディレクトリ
 - laradock // laradock諸々のファイル
 - laravel // laravelプロジェクト

⑧コントローラー作成

\laravel-sns\laradock> docker-compose exec workspace php artisan make:controller ArticleController
Controller created successfully.

※1-4終了時点の画面

⑨データベースの作成 教材1-5

docker-compose exec workspace psql -U default -h postgres
default=# create database larasns;
>> CREATE DATABASE
default=# \q

laravel/.envを編集してLaravel側からデータベースに接続できるようにする。

DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=larasns
DB_USERNAME=default
DB_PASSWORD=secret

マイグレーションファイルの作成

docker-compose exec workspace php artisan make:migration create_articles_table --create=articles

マイグレーション(※ファイルの編集部分は割愛)

docker-compose exec workspace php artisan migrate
>> Migration table created successfully.
   Migrating: 2014_10_12_000000_create_users_table
   Migrated:  2014_10_12_000000_create_users_table (0.02 seconds)
   Migrating: 2014_10_12_100000_create_password_resets_table
   Migrated:  2014_10_12_100000_create_password_resets_table (0.01 seconds)
   Migrating: 2019_08_19_000000_create_failed_jobs_table
   Migrated:  2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
   Migrating: 2020_05_18_104829_create_articles_table
   Migrated:  2020_05_18_104829_create_articles_table (0.01 seconds)

モデル作成

docker-compose exec workspace php artisan make:model Article

※教材1章終えた段階ではデータすっからかん。

⑩任意のデータベースへのログイン

psqlコマンド

docker-compose exec workspace psql -U default -h postgres -d larasns
larasns=# SELECT id, name FROM users ORDER BY id;
 id | name 
----+------
  1 | test
(1 row)
larasns=# DELETE FROM users WHERE id = 1; // 削除したい場合
DELETE 1

Tinkerの利用

docker-compose exec workspace php artisan tinker
>>> App\User::all();
=> Illuminate\Database\Eloquent\Collection {#3765
     all: [
       App\User {#3764
         id: 1,
         name: "test",
         email: "testtest@gmail.com",
         email_verified_at: null,
         created_at: "2020-05-18 11:38:27",
         updated_at: "2020-05-18 11:38:27",
       },
     ],
   }

両方試すとTinkerの便利さを痛感します。

⑪リクエストの作成 教材4-4

docker-compose exec workspace php artisan make:request ArticleRequest

環境設定

config/app.php

'timezone' => 'Asia/Tokyo',

コンテナ停止 参考

docker-compose stop // 起動中のコンテナを削除せずに停止する。docker-compose startで再起動可能。
docker-compose down // 起動中のコンテナを削除する

※現在教材4-5まで

躓いた点

✅Docker Toolboxからの移行

※Docker Toolboxを入れる前に環境変数をメモっておくべきだった。。。

参考:DOCKER TOOLBOX から DOCKER DESKTOP への移行

どうやらDocker toolboxの環境変数が残るようなので削除する必要あり。

確認

PowerShellから以下コマンドで削除

[Environment]::SetEnvironmentVariable("DOCKER_CERT_PATH", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_HOST", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_MACHINE_NAME", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_TLS_VERIFY", $null, "User")
[Environment]::SetEnvironmentVariable("DOCKER_TOOLBOX_INSTALL_PATH", $null, "User")

Hyper-Vにチェックを入れて再起動。

docker-compose up -d workspace php-fpm nginx postgres
Starting laravel-sns_postgres_1 ... done
Starting laravel-sns_docker-in-docker_1 ... done
Recreating laravel-sns_workspace_1 ... done
Recreating laravel-sns_php-fpm_1 ... done
Recreating laravel-sns_nginx_1 ... done

docker-compose ps
             Name                           Command              State                    Ports
-----------------------------------------------------------------------------------------------------------------
laravel-sns_docker-in-docker_1   dockerd-entrypoint.sh           Up      2375/tcp, 2376/tcp
laravel-sns_nginx_1              /bin/bash /opt/startup.sh       Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laravel-sns_php-fpm_1            docker-php-entrypoint php-fpm   Up      9000/tcp
laravel-sns_postgres_1           docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp
laravel-sns_workspace_1          /sbin/my_init                   Up      0.0.0.0:2222->22/tcp

無事http://localhost/で起動を確認。

この記事読むとどうやらMacとはマウントのパスが異なるのが総じてマウントできない原因っぽい。

✅psqlコマンドが使えない(※マイグレーションできない)

参考:LaradockでPostgreSQLを起動できないときの対処法

\laravel-sns\laradock> docker-compose exec workspace psql -U default -h postgres
psql: could not translate host name "postgres" to address: Name or service not known

確認(PostgreSQLが起動できていないことを確認)

laravel-sns\laradock> docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------------------
laravel-sns_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp, 2376/tcp
laravel-sns_nginx_1 /bin/bash /opt/startup.sh Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laravel-sns_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp
laravel-sns_postgres_1 docker-entrypoint.sh postgres Exit 1
laravel-sns_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp

再起動してもダメ。

docker-compose restart

確認(やっぱりだめだけどpsqlコマンドは確認できた。)

\laravel-sns\laradock> docker-compose exec workspace bash
root@16255c75eb53:/var/www# psql -h postgres -U  default
>> psql: could not translate host name "postgres" to address: Name or service not known
root@16255c75eb53:/var/www# psql -V
>> psql (PostgreSQL) 9.5.19 // コマンドは確認できた。
root@16255c75eb53:/var/www# psql -h localhost -U  default // localhostにしてみる。
>> psql: could not connect to server: Connection refused
           Is the server running on host "localhost" (127.0.0.1) and accepting
           TCP/IP connections on port 5432?
   could not connect to server: Cannot assign requested address
           Is the server running on host "localhost" (::1) and accepting
           TCP/IP connections on port 5432?

ちなみにlaradock/.envファイル確認

POSTGRES_DB=default
POSTGRES_USER=default
POSTGRES_PASSWORD=secret
POSTGRES_PORT=5432
POSTGRES_ENTRYPOINT_INITDB=./postgres/docker-entrypoint-initdb.d

友人にup時の-dオプションをなくしたらエラー内容が出ると教えていただいたので試す。

抜粋
ブートストラップスクリプトを実行しています… 2020-05-18 00:47:05.366 UTC [80]致命的:データディレクトリ「/ var / lib / postgresql / data」の所有権が間違っています
postgres_1 | 2020-05-18 00:47:05.366 UTC [80]ヒント:サーバーは、データディレクトリを所有するユーザーが起動する必要があります。
postgres_1 |子プロセスが終了コード1で終了しました
postgres_1 | initdb:データディレクトリ「/ var / lib / postgresql / data」の内容を削除
laravel-sns_postgres_1はコード1で終了しました

参考:Docker で作る postgres 環境

init.shの改行を確認したが、LFで間違いなかった。

参考:Windows 10でDocker + Laravel環境構築

laradock/.envの最終行に以下を追記。

DB_HOST=postgres

これでは解決しなかった。

解決パターン①

参考:Windows環境ではDBのデータ永続化をすると起動しない

docker-compose.yml 469行目 ボリュームのデータ永続化部分ををコメントアウト

    postgres:
      build: ./postgres
      # volumes:
        # - ${DATA_PATH_HOST}/postgres:/var/lib/postgresql/data
        # - ${POSTGRES_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d

すると起動した

\laravel-sns\laradock> docker-compose ps
   Name Command State Ports
   -----------------------------------------------------------------------------------------------------------------
   laravel-sns_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp, 2376/tcp
   laravel-sns_nginx_1 /bin/bash /opt/startup.sh Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
   laravel-sns_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp
   laravel-sns_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
   laravel-sns_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp
\laravel-sns\laradock> docker-compose exec workspace psql -U default -h postgres
   Password for user default: 
   psql (9.5.19, server 11.6 (Debian 11.6-1.pgdg90+1))
   WARNING: psql major version 9.5, server major version 11.
            Some psql features might not work.
   Type "help" for help.
   
   default=#

laradock/.envの情報通り、パスワードはsecretで入れる。

POSTGRES_DB=default
POSTGRES_USER=default
POSTGRES_PASSWORD=secret
POSTGRES_PORT=5432
POSTGRES_ENTRYPOINT_INITDB=./postgres/docker-entrypoint-initdb.d

解決パターン②

Docker for WindowsとLaradockでpostgresのコンテナが起動できない場合の対処
DockerとLaradockで環境構築してみた!Windows10編!

両記事共にdocker-compose.ymlの/data部分を削除。これに従うと起動する。

${DATA_PATH_HOST}/postgres:/var/lib/postgresql // 末尾の/dataを消すと起動したらしい。

この方法が一番シンプル。ただなぜか永続化できない(※dataに同期されない)。

✅docker-compose.yamlの変更が反映されない

コンテナの再起動は以下のはずだが。。。

docker-compose stop
docker-compose up -d workspace php-fpm nginx postgres
docker-compose restart // 再起動。別パターン。

上記PostgreSQL起動のために変更した諸々のスクリプトをデフォルトの状態に戻して起動してもPostgreSQLが起動する。。。

解決:docker-compose.yamlはcontainer作成時に読み取るファイルなのでコンテナの再作成が必要。

docker-compose downで削除して起動しなおすと再度コンテナを作り直せる。

✅Postgreディレクトリの中身が空=データの永続化ができていない

未解決です。

参考:Laravelで簡単なページを作成するまで

永続化についてpostgresの永続化はwindowsだと上手くいかずnamed volumeを作成してそこを指定するというのが一般的です。と記載されている。

参考:DockerでDBを永続化すっぞ

永続化とはコンテナが削除されてもホスト側と同期することで再度コンテナを立ち上げてもデータが読み込まれる仕組み。

volumeオプションは、「左にホストOSのパス:右にコンテナのパス」形式で指定できる。

yamlファイルを確認するとこうなっている。

postgresql:
  volumes:
   - ${DATA_PATH_HOST}/postgres:/var/lib/postgresql // .envから../dataを代入
   - ${POSTGRES_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d

(ゲスト側の確認)postgreコンテナへログイン

\laravel-sns\laradock> docker-compose exec postgres bash
cd var/lib/postgresql/data
root@6b9019162329:/var/lib/postgresql/data# ls
base pg_commit_ts pg_hba.conf pg_logical pg_notify pg_serial pg_stat pg_subtrans pg_twophase pg_wal postgresql.auto.conf postmaster.opts
global pg_dynshmem pg_ident.conf pg_multixact pg_replslot pg_snapshots pg_stat_tmp pg_tblspc PG_VERSION pg_xact postgresql.conf postmaster.pid

(ホスト側の確認)同期されていない!!

C:\xampp\htdocs\laravel-sns\data\postgres\data> ls

参考:Docker for Windowsでpostgresのデータマウントができない人へ

docker-compose.yamlの編集

version: '3' // 記事では2だけど今回は3で。
services:
  db:
    image:
      postgres
    ports:
      - "5432"
    volumes:
      - test_db:/var/lib/postgresql/data // 今回編集したのはこの部分
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d // 今回編集したのはこの部分

volumes:
  test_db: // 追記
    external: true // 追記

ボリュームの作成 参考

ボリュームはデータを永続化できるコンテナ外部の場所のことらしい。外部HDDのイメージ。

作成

docker volume create --name test_db

これで起動はできる。

参考:Docker、ボリューム(Volume)について真面目に調べた

確認

docker volume ls
~~~~
>> local test_db
docker volume prune // 使われていないボリュームを削除
docker volume inspect test_db // 属性を調べる
>> [
       {
         "CreatedAt": "2020-05-18T04:46:40Z",
         "Driver": "local",
         "Labels": {},
         "Mountpoint": "/var/lib/docker/volumes/test_db/_data",
         "Name": "test_db",
         "Options": {},
         "Scope": "local"
       }
   ]

※volume は仮想マシン上の /var/lib/docker/volumes 配下においてあるらしい

参考:Docker for WindowsでマウントするDocker for WindowsをWSLから使う時のVolumeの扱い方

Dockerがどこのフォルダを共有しているか確認する。

Cドライブになっている。

Cドライブを確認。たしかに今日(5/18)付けで変更されている部分がある。けど違う気がする。。。

ただtest_dbが気に入らないので元に戻して起動したところ。。。エラーが出るようになってしまった。

👉解決:ホスト側のpostgresqlディレクトリ下のデータが存在したため。

yamlファイルで一度これでコンテナ作成する。

${DATA_PATH_HOST}/postgres/data:/var/lib/postgresql

削除して再度作成。

${DATA_PATH_HOST}/postgres:/var/lib/postgresql

するとHost側のdindファイルが削除できなくなるのでこれが原因っぽい。

おわりに

永続化ができておらず、個人的にはこの状態では使いたくない感じ。

コンテナを起動するたびにDBから作り直すなんてめんどくさすぎる。。。

追記:👇MySQLだと簡単に永続化できてしまったので、まずはこちらで使いこなそうかと思う。

Docker for WindowsでLaradock(+MySQL)の環境構築

学習の備忘録

備忘録

workspaceコンテナへログイン 参考

docker-compose exec workspace bash // こちらだとrootユーザーになる
>> root@14dcd58cd86f:/var/www# 
docker-compose exec --user=laradock workspace bash // こちらだとcomposerコマンドの警告が出ない
>> laradock@14dcd58cd86f:/var/www$

✅コマンド

docker ps:コンテナ確認

docker stop <コンテナ名>:停止

docker-compose down:コンテナ削除

コメントを残す