docker-composeコマンドメモ~Rails5.1 + webpacker~

前回までとは違う話ですが, 開発環境をdockerで作ろうとしています.

今回はRailsでwebpackerを使ってReactを動かしたいので, その環境構築の自分なりのメモです. 

いまいちdockerのイメージとコンテナの違いが, あとdocker-composeのbuild, run, upの違いがわからないので整理しようかと思います. (間違っていたら教えていただけると幸いです(涙))

 

 

Dockerでイメージ作成からコンテナ起動まで

Dockerfileでビルドするイメージ作成

やりたいことはこんな感じ.

onoxeve.com

で, Dockerの公式にもRails+Postgresのがあったので, そちらを主な参考にしてみる.

docs.docker.com

 

Dockerfileはコンテナが起動時の参考にする環境である"イメージ"を作成するものと認識.  このイメージを作成してdocker imagesでimageが表示される様にすることを"build"と認識.

 

・Dockerfile

# Ruby2.5.1のイメージをベースとして取得
FROM ruby:2.5.1
# ruby:2.5.1が取得したイメージ[buildpack-deps:stretch]の元が[debian:stretch]なので, aptコマンドを使用する
# インデックスファイルの更新とパッケージのダウンロード
# -q : 進行状況非表示, -y : 全てyesを自動回答
RUN apt-get update -q && apt-get install -y build-essential libpq-dev
# nodesourceのapiから情報をget -> bashコマンドで読み込んだファイルを実行
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash
# バージョンを指定したnodejsのインストールを実行
RUN apt-get install -y nodejs
# yarnのstabelバージョンをインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install yarn
# コンテナ内での作業フォルダ作成と作業ディレクトリへの移動(指定)
RUN mkdir /web_container
WORKDIR /web_container
# ホストからコンテナ側へファイルのコピー(事前にホスト側で作成しておく)
COPY Gemfile /web_container/Gemfile
COPY Gemfile.lock /web_container/Gemfile.lock
# コンテナ内でGemfileのインストール&更新
RUN bundle install
# ホストの作業ディレクトリ内を全てコンテナ側にコピー
COPY . /web_container

これがイメージをビルドするベースのファイルになる.

 

docker-compose.yml作成

従来ではコンテナ間通信で"network"とか"--link"とかしてたのを簡単にするものと認識.

・docker-compose.yml

version: '3'
services:
db:
# postgresqlをvrsion10でインストール
image: postgres:10
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: my_db
volumes:
# 作業ディレクトリ:コンテナ内でデータのマウント
- ./tmp/db:/var/lib/postgresql/data
# PG Commanderから接続するためにポート変更
ports:
- '5433:5432'
container_name: "my_db"
web:
# 作業ディレクトリ内のDockerfileをビルド
build: .
# ポートの3000番を利用. localhost以外のIPアドレスからアクセス可能な様に0.0.0.0にバインド
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/web_container
container_name: "my_web"
ports:
- "3000:3000"
depends_on:
- db

あとは

 ・Gemfile

source 'https://rubygems.org'
gem 'rails', '5.1.2'

と, 空のGemfile.lockを用意して終了.

 

イメージのビルドとコンテナ操作

docker-compose run --rm web rails new . --force --database=postgresql --webpack=react

を実行. これの中身を解説していく.

 

別のDockerの公式(Quickstart: Compose and Django | Docker Documentation)をみると,

Create the Django project by running the docker-compose run command as follows.

 sudo docker-compose run web django-admin.py startproject composeexample .

This instructs Compose to run django-admin.py startproject composeexample in a container, using the web service’s image and configuration. Because the web image doesn’t exist yet, Compose builds it from the current directory, as specified by the build: . line in docker-compose.yml.

Once the web service image is built, Compose runs it and executes the django-admin.py startprojectcommand in the container. This command instructs Django to create a set of files and directories representing a Django project.

 とある. つまり run service名 コマンド で, service名のイメージから立ち上げられた(立ち上げられる予定の)コンテナ内でコマンドが実行される. しかし, run実行時点ではwebコンテナはおろか, webコンテナの起動ベースとなるイメージがビルドされていないので, docker-compose.ymlの build: . で, まずDockerfileを読み込んでイメージのビルドが行われると認識.

ちなみにここではrunされたservice: webの依存関係として depends_on: dbとなっているので, まずdbのイメージがビルドされる. それはimage: postgres:10であり, dockerhubからpullされる. postgresのコンテナはdocker-compose upしなくてもこのコマンドだけで起動状態を保っている. 調べきれていないが, databaseはrunでイメージのビルドからコンテナ起動まで出来るっぽい??

で, service: webのイメージがビルドされたらrails new .... 以降のコマンドが実行される. 

--rm : runで一時的にコンテナに入ると中間コンテナと呼ばれるコンテナが出来るっぽくて, そのままにしておくとコンテナの数が増えていくっぽい. ので--rmで中間コンテナを削除すれば, docker-compose upでコンテナを作成しても, 諸々インストールされたコンテナが1つ起動するだけで済む??

rails new . : カレントディレクトリでrails newする??

--force : ファイルが存在していれば上書きする. GemfileとかGemfile.lockのことかなぁ...?(railsコマンド(rails) - - Railsドキュメント

 

以上でmy_webコンテナ(docker-compose.ymlに記したコンテナ名)内ではrailsアプリの環境が出来上がっているはず.

この時点では,docker ps -aしてもNAMES: my_webは無い. docker imagesするとREPOSITORY: my_webはある.

 

次いで以下を参考にデータベースの接続設定を行う.

Connect the database

config/database.yml with the following:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: user
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

 

イメージのリビルド

 さっきの処理でGemfileに変更が生じたっぽいので, Gemfile.lockを更新する必要があり, その場合my_webコンテナが利用するイメージのリビルドが必要になる. 今後Gemfileの更新があった場合は, 

docker-compose run --rm web bundle install

docker-compose up -d --build

をすれば良い模様. 2つめのコマンドを実行すると, service: webのbuildが呼ばれ, Dockerfileが呼び出される. Dockerfileは以前と変更がないコマンドが現れるまでの処理を飛ばしてくれるので, ここでは COPY Gemfile /web_container/Gemfile 以降が実行される. その後service: webのコンテナをデタッチモード(バックエンド)で起動してくれる.

 

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my_web latest ********* 2 minutes ago 1.22GB
<none> <none> ********* 2 hours ago 1.05GB

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
******** my_web "bundle exec rails s…" 2 minutes ago Up 2 minutes 0.0.0.0:3000->3000/tcp my_web

と, 謎の<none>イメージができている. コンテナはmy_webイメージを元に起動されているので, noneイメージは不要だと思われるので消す. イメージのリビルドが行われると前のイメージが<none>になって新しいイメージが作成されるのか??? 

docker rmi -f IMAGE IDでイメージ削除.

 

で, 最後にデータベースを作成すれば完了.

docker-compose run --rm web rake db:create

 

これでlocalhost:3000にアクセスすれば一応動く. パソコンを再起動するとコンテナは終了しているので(restart: alwaysしてないため), docker-compose.ymlのあるディレクトリに移動して, docker-compose up -dをすれば良い.

 

データベース接続

postgresデータベースの中身を見たかったので, ちょっとメモしておきます.

# コンテナに入る
$ docker exec -it データベースのコンテナID bash

# データベースに接続
/# psql --username=user --dbname=my_db

# データベース一覧表示
my_db=# \l

# 抜ける
ctrl P Q

となる. 

 

GUIツールであるPG Commanderでの接続方法は以下です.

Nickname: 好きな名前で良い

# dockerの場合, HostはdockerコンテナのIPではないらしい
Host: 127.0.0.1

# Portはdocker-compose.ymlで指定したやつ
Port: 5433

User: POSTGRES_USERで指定したやつ
Pass: POSTGRES_PASSWORDで指定したやつ
Database: POSTGRES_DBで指定したやつ

localに別のpostgresがあった場合, PG Commanderで接続するとブッキングするっぽかったので, docker-compose.ymlでホスト側はポート番号5433で, dockerコンテナのデータベース(ポート5432)に接続できる様に変えました.

 

まとめ

ひとまず環境構築はできたみたいなので, 次はyarnとかwebpackerの使い方, es6でReactコンポーネント作るあたりまでやります.

WordPressでテーマから作成したメモ

前回から色々試行錯誤していたのですが, ひと段落(?)したのでメモを残しておきます.

 

前回の記事はこちら.

dai7igarashi.hatenablog.com

 

 

テーマから作成

作ったサイトはこちらです. 

YouTube編集教室YES | 小学生向け!夏のイベント開催中!

( ↑ よくあるご質問のデザインは友達です)

WordPressには素敵なテーマがたくさんありましたが, どうも手を加えようとすると難しい部分がありました. なので自分でテーマから作成しました.

 

最低限必要なファイル

今回のデザインとしてはフロントページ があって基本はそこでランディング, 予約フォームや一部のページだけルーティングって感じです. これを実現するために以下のファイルを作成しました.

  • index.php : 必須
  • style.css : 必須
  • header.php : ヘッダー記述用
  • nav.php : ナビゲーションバー用
  • front-page.php : ホームのページ用
  • page.php : 個別ページの内容表示用
  • footer.php : フッター用
  • function.php : 外部ファイルの読み込みなど用

nav.php以外はwordpress側がファイル名を自動で認識して役割や表示の優先順位を決めてくれます. nav.phpは今回自分で作ったファイルです. 自作のphpファイルは<?php get_template_part('nav'); ?>のように記述すれば読み込めます.

 

各ファイルの基本の記述

具体的なコンテンツ部分を除いた記述は以下のようになりました.

テーマ作成に関して, こちらの記事を参考にさせていただきました.

plusers.net

 

index.php
<!-- header.phpを呼び出し -->
<?php get_header(); ?>

<!-- bootstrap4を使用したのでcontainer指定しとく -->
<div class="container">

<!-- 自作のnav.phpを呼び出し -->
<?php get_template_part( 'nav' ); ?>

</div>
<!-- footer.phpを呼び出し -->
<?php get_footer(); ?>

 

style.php
@charset "utf-8";

/*
Theme Name: myTheme ←必須
Author: hogehoge taro
*/

 

header.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<!-- レスポンシブルデザインに対応させる -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- header.phpを呼び出し -->
<?php wp_head(); ?>
</head>
<!-- wordpressが読み込みファイルを扱いやすいようにしてる? -->
<body <?php body_class(); ?>>
固定のナビゲーションバー
wordpressに共通して言えることはないので割愛
front-page.php
<?php get_header(); ?>

<!-- コンテンツ -->

<?php get_template_part( 'nav' ); ?>

<!-- コンテンツ -->

<?php get_footer(); ?>
page.php
<?php get_header(); ?>

<div class="container">
<?php get_template_part( 'nav' ); ?>

<!-- データベースに保存された固定ページの内容を取得 -->
<!-- ※投稿と違っていくつものコンテンツを取ってこなのでwhileは不要かも... -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; endif; ?>
</div>

<?php get_footer(); ?>
footer.php
<footer>
<div class="copyright">
<p class="text-center">copyright ©<?php bloginfo( 'name' ); ?> All Rights Reserved.</p>
</div>
</footer>
<?php wp_footer(); ?>
</body>
</html>
function.php
<?php

add_theme_support( 'title-tag' );
add_theme_support( 'html5', array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption' ) );
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'post-thumbnails' );

function my_scripts() {
// wp標準のjQueryは使用しない
wp_deregister_script('jquery');
wp_enqueue_script('jq', "https://code.jquery.com/jquery-3.3.1.min.js");
wp_enqueue_script('boot', get_template_directory_uri() . '/bootstrap-4.1.3-dist/js/bootstrap.min.js', array('jq'));
.
.
.
読み込みたいjsファイル
}

function my_style() {
wp_enqueue_style('style', get_stylesheet_uri());
wp_enqueue_style('boot', get_template_directory_uri() . '/bootstrap-4.1.3-dist/css/bootstrap.min.css');
.
.
.
読み込みたいjsファイル
}

add_action('wp_enqueue_scripts', 'my_scripts');
add_action('wp_enqueue_scripts', 'my_style');

register_nav_menu( 'header-nav', ' ヘッダーナビゲーション ' );
register_nav_menu( 'footer-nav', ' フッターナビゲーション ' );

 

気づいたこと

wordpress関係ありませんが, bootstrap4のグリッドレイアウトでレスポンシブデザインを考えるのが難しかった(というか出来ていないのでは...).

font-sizeを動的に変えるやり方についてあまり理解できていないですね.

 

具体的には, 指定したrowとcolの"box"にぴったり文字が収まるようにできていないです. つまり"box"がfont-sizeによって動的に変化してしまっている(はみ出してる)感じです.

これから

bootstrapとcssの勉強ですね............

あとは綺麗なhtmlの書き方ですね.....

Hello はてなブログ ~WordPress on Dockerの備忘録~

はじめまして, Igarashiです.

最近Qiita(https://qiita.com/Dai7Igarashi)をはじめたんですが, 何でしょう, Qiitaって"綺麗に書かなきゃ"って思ってしまうんですよね. 構成がしっかりしているからでしょうか...

で, なかなか更新できずじまい. コードとか書いて備忘録書こうと思っても, サクッと書けないんですよね^^;


ということで備忘録ははてなブログ, 清書はQiitaって感じで使い分けようと思います!(なので読みにくいかもしれませんが悪しからず...汗)

 

 

公開済みのWordPressをローカルで開発

経緯

友達がWordPressでサイトを構築したんですが, その一部を作ることになりました. オンラインで作業してもいいのですが

  • jsとか各種ファイルの書き換えが大変そう
  • ミスしたら復元が大変そう

ということがあったので, ローカルでWordPressの開発環境を作ることにしました.

実行環境

docker-composeの設定

WordPressMySQLのイメージ取得とコンテナ起動

Docker for Machttps://docs.docker.com/)をインストールします.

作業フォルダを作成してそこに移動します. そのフォルダ直下にdocker-compose.ymlを以下の内容で保存.

version: '3.3'

services:
   db:
     image: mysql:5.6
     volumes:
       # - ./db_data:/var/lib/mysql
       # コンテナ起動時に読み込まれるinstall_wordpress.sqlを読み込みたいdumpファイルで置換
       - ./db_data/読み込みたいsqlファイル.sql:/docker-entrypoint-initdb.d/install_wordpress.sql
     restart: always
     container_name: "wp_yes_db_1"
     environment:
       MYSQL_ROOT_PASSWORD: ①ルートパスワード(ex. rootpass)
       MYSQL_DATABASE: ②mysqlで作成されるデータベース名(ex. my_db)
       MYSQL_USER: ③データベースにアクセスするユーザ名(ex. user)
       MYSQL_PASSWORD: ④データベースにアクセスするパスワード(ex. pass)

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     container_name: "wp_yes_wordpress_1"
     environment:
       # DB_HOST名は起動したmysqlのコンテナ名:mysqlのポート番号を記述
       WORDPRESS_DB_HOST: wp_yes_db_1:3306
       # DB_NAMEはデフォルトでwordpressなので書き換える
       WORDPRESS_DB_NAME: wordpressがアクセスするデータベース => ②で記述したデータベース名(my_db)
       WORDPRESS_DB_USER: wordpressがアクセスする時のユーザ名 => ③で記述したユーザ名(user)
       WORDPRESS_DB_PASSWORD: wordpressがアクセスする時のパスワード => ④で記述したパスワード(pass)
     volumes:
        # ホストOSの作業ディレクトリ:dockerコンテナの作業ディレクトリ
        - ./:/var/www/html/
       
volumes:
    db_data:
        driver: local

基本の書き方は以下3つにあり.

1. Quickstart: Compose and WordPress | Docker Documentation

2. https://hub.docker.com/_/mysql/

3. https://hub.docker.com/_/wordpress/

このdocker-compose.ymlがあるフォルダでdocker-compose up -dコマンド実行. 

因みにdbの中身ごと破棄するにはdocker-compose down --volumes

するとDockerコンテナ上にWordPressMySQLがインストールされ, 起動完了.

起動するとコンテナとマウントしたホスト側のディレクトリ(./)に新規インストールされたWordPressの各種データが保存される.

※ 後に登場するwp-config.phpWORDPRESS_DB_NAMEで結構つまずきました(~_~;)

phpmyadminからデータベースのデータ取得

友達はロリポップを使用していたので, ロリポップの管理画面にログインしてphpmyadminに入りました. この辺りは以下を参考に. そして**.sqlをダウンロード.

WordPress手動バックアップとDocker環境でのリストア

FileZillaでサーバー上のデータをダウンロード

以下を参考にダウンロード.

【FileZillaの使い方】WordPressでFTPソフトを使おう

 

ダウンロードしたmysqlデータの書き換え

WordPressは画面遷移(ルーティング)の情報をmysql側で保持しているらしいです. なのでダウンロードしたファイルではhttp://www.123456/Aboutみたいな記述になっています. これをローカルホストで動かすにはhttp://localhost:8000/Aboutで置換します. (今回はports: - "8000:80"でホスト側のポートを8000にしたのでこう書く.)

テキストエディタとかで検索->全て置換すれば一瞬です.

書き換えたデータはmysqlのコンテナとマウントしたフォルダ(./db_data/)以下に設置します.

 

ダウンロードしたWordPressデータで置き換え

FileZillaで落としたデータを全て先ほどインストールされたWordPressデータと入れ替えます.

 

wp-config.phpの書き換え

仕上げです. wp-config.phpのデータベースの記述部分を以下のように書き換えます.

// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define('DB_NAME', '②で記述したデータベース名(my_db)');

/** MySQL データベースのユーザー名 */
define('DB_USER', '③で記述したユーザ名(user)');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', '④で記述したパスワード(pass)');

/** MySQL のホスト名 */
define('DB_HOST', 'WORDPRESS_DB_HOSTの中身(wp_yes_db_1:3306)');

docker-compose.ymlのWORDPRESS_DB_NAMEはデフォルトでwordpressになるので, ymlのこれとconfigのDB_NAMEは一致させるように.

 

ログイン

ブラウザでlocalhost:8000/admin/と打てばログイン画面になるはずです. いつも通りのIDとパスワードで入れます. お疲れ様でした.

 

まとめ

とりあえずローカルで本番環境を再現することが目的だったので, 細かな設定とかは考えていません. 次はサイトのphpとかjsとかいじったことを備忘録として残します!!(Qiitaのようにはならないぞ💪)