PROGRAMMING

【シンプル解説】Dockerで作るpostgreSQL,Laravel,nginx環境構築

dockerで環境構築する方法教えてください。

ということあるかと思います。

MySQLじゃなくてポスグレ使うんですよね。って現場があったり、なんか使ってみたいということありますよね。

早速やっていきましょう。

※MySQLで解説を見たい場合はこちらを見ていただければいいと思います。

動画でも解説しております

ローカル環境

名前バージョン
OSmacOS Monterey 12.6
docker
docker-compose

これから作る環境

名前バージョンコンテナ名
PHP8.1web
Laravel8web
nginx1.20nginx
postgreSQL14postgres

Dockerfileの紹介

php/Dockerfile

FROM php:8.1-fpm
WORKDIR /var/www
ADD . /var/www

# permission
RUN chown -R www-data:www-data /var/www

# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

# install packages
RUN apt-get update \
  && apt-get install -y \
  gcc \
  make \
  git \
  unzip \
  vim \
  libpng-dev \
  libjpeg-dev \
  libfreetype6-dev \
  libmcrypt-dev \
  libpq-dev \
  curl \
  gnupg \
  openssl \
  && docker-php-ext-install pdo_pgsql pgsql \
  && docker-php-ext-configure gd --with-freetype --with-jpeg \
  && docker-php-ext-install -j$(nproc) gd

# Add php.ini
COPY php.ini /usr/local/etc/php/

# install stable node and latest npm
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash
RUN apt-get update \
  && apt-get install -y nodejs 
# install node packages
RUN npm install -g n
RUN n stable
RUN npm update -g npm

gd はVue.jsとか使う時に画像の処理なんかで使いますので入れておきます。これと以下はセットみたいなものです。

~    
libpng-dev \
libmcrypt-dev \
libpq-dev \
~

nodeのバージョンは現時点での最新を入れているんで、もし古くなっていたらこちらを確認してみてください。
https://github.com/nodesource/distributions#installation-instructions

nginx/Dockerfile

FROM alpine:3.6

# nginxのインストール
RUN apk update && \
    apk add --no-cache nginx
RUN mkdir -p /run/nginx

# TimeZoneをAsia/Tokyoに設定する
RUN apk --no-cache add tzdata \
    && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && apk del tzdata

# フォアグラウンドでnginx実行 これがないとコンテナが停止する
CMD nginx -g "daemon off;"

各種の設定ファイル

docker-config/php/php.ini

[Date]
date.timezone = "Asia/Tokyo"

docker-config/nginx/default.conf

server {
    listen 80;
    # server_name localhost;
    
    # laravel
    root /var/www/public; 
    index index.php index.html;
    allow all;
    
    access_log /var/log/nginx/ssl-access.log;
    error_log  /var/log/nginx/ssl-error.log;

    location / { 
        #for laravel
        root /var/www/public;
        try_files $uri $uri/ /index.php$is_args$args;
    }  

    location ~ \.php$ {
        try_files $uri =404;
        
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass web:9000;
        fastcgi_index index.php;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;

        # CORS start
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
        add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
        add_header Access-Control-Allow-Credentials true;
        # CORS end
    }   
}

docker-composeの紹介

docker-compose.yml

version: '3' 

services:
    
  web: 
    build: ./docker-config/php 
    volumes:
      - ./:/var/www #後で書き換えます
      - ./docker-config/php/php.ini:/usr/local/etc/php/php.ini
    depends_on:
      - postgres

  nginx:
    build: ./docker-config/nginx 
    ports:
      - "8888:80"
    volumes:
      - .:/var/www #後で書き換えます
      - ./docker-config/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - web
    # restart: always

  postgres:
    image: postgres:14
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      PGPASSWORD: postgres
      POSTGRES_DB: main
      TZ: "Asia/Tokyo"
    ports:
      - 5432:5432 #MySQLと違うので注意
    volumes:
      - ./docker-config/postgres/data:/var/lib/postgresql/data
      - ./docker-config/postgres/logs:/var/log

コンテナ立ち上げ作業

docker-compose.ymlがあるところに移動

$ cd php-postgresql-nginx
# 以下を実行
$ docker-compose up -d

立ち上げ終わったらコンテナが立ち上がっているか確認します。(今回は3つ立ち上がっていればOK)

$ docker ps

コンテナが立ち上がってない場合

コンテナのログを確認しましょう。

$ docker logs [コンテナID OR コンテナNAME]

解説動画内では、いらないファイルが入っており、そちらを削除したことで成功しました。

無事に全てのコンテナが立ち上がったら、ブラウザでアクセス確認します。

そうしたら以下のように表示されるかと思います。

なんで404と表示されているんですか?

これは、読み込み先をLaravelが入った後のパスにしているからです。

404になる解説

docker-config/nginx/default.conf の

root /var/www/public; 

は nginxの /var/www/publicを最初に読み込むように設定してます。

で、docker-compose.ymlを見てみると

~
web: 
    build: ./docker-config/php 
    volumes:
      - ./:/var/www #後で書き換えます
      - ./docker-config/php/php.ini:/usr/local/etc/php/php.ini
~

  nginx:
~
    volumes:
      - ./:/var/www #後で書き換えます
      - ./docker-config/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
~

volumesの部分で、 /var/ww配下に載せている部分ってのは、

.
├── docker-compose.yml //ここ
├── docker-config //ここ
│   │	├── nginx
│   │   ├── Dockerfile
│   │   └── default.conf
│   ├── php
│   │   ├── Dockerfile
│   │   └── php.ini
│   └── postgres
│       ├── data
│       └── logs
└── webApp //laravel 

つまり、index.htmlもないところを読み込んでいるわけです。

なので、Laravelをインストールしていきましょう。

Laravelインストール作業

まずwebコンテナ内に入ります。

$ docker exec -it php-postgresql-nginx-web-1 bash

そしたら、composerをつかってインストールしていきます。

composer create-project "laravel/laravel=8.*" webApp

=の後ろにバージョンを入れると任意のバージョンになります。今回は8系にします。

その後ろがディレクトリ名ですね。

そうすると、以下のような形になります。

.
├── docker-compose.yml
├── docker-config 
└── webApp //laravel 

webAppディレクトリが完成したら、こちらを読み込むようにします。

docker-compose.yml

web: 
    build: ./docker-config/php
    volumes:
      - ./webApp:/var/www #変更
      - ./docker-config/php/php.ini:/usr/local/etc/php/php.ini
    depends_on:
      - postgres

  nginx:
    image: nginx
    build: ./docker-config/nginx
    ports:
      - "88:80"
    volumes:
      - ./webApp:/var/www #変更
      - ./docker-config/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - web
    # restart: always
~

これ変更を反映させるためにもう一度docker-compose を立ち上げます

$ docker-compose up -d

そうすると、

こんな感じで出てくるかなと。

PostgreSQL接続テスト

テストするために データベース名を表示させようと思います。

webApp/resources/views/welcome.blade.php

{{-- TEST DB --}}
        <strong>Database Connected: </strong>
        <?php
            try {
                \DB::connection()->getPDO();
                echo \DB::connection()->getDatabaseName();
                } catch (\Exception $e) {
                echo 'None';
            }
        	//Info
        	phpinfo();
        ?>
    </body>
</html>

こんな感じで追加してみます。接続ができていればデータベース名を返すはずです。

phpinfo(); は確認用です。

環境変数を変更しましょう。

webApp/.env

DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=main
DB_USERNAME=postgres
DB_PASSWORD=postgres

これでブラウザで見てください。

たぶん「main」と表示されてるはずです。

もし表示されてないなら?

環境変数の反映がされていないかもしれません。

その時は以下をwebコンテナ内で叩いてみてください。

$ php artisan config:clear

【補足】postgreSQLの基本操作

まず、コンテナに入る。

$ docker exec -it php-postgresql-nginx-postgres-1 bash

操作方法

#アクセス
psql -U postgres

#データベース名一覧
\l 

#現在の接続先
\c 

#接続先を変更
\c [DATABASE NAME]


# テーブルを確認
\dt

# EXIT
\q

-PROGRAMMING