はじめに
Dockerによるマルチサイト構築手順です。
WordPress、Ruby on Railsでマルチサイトを構築です。
投稿者の環境は、CentOS7環境です。
できること
- WordPress、Ruby on RailsのWebサイトをマルチサイトで公開する。
- サイト数は、追加、削除が容易に行える。
- Webサイトは、Let'sEncryptでSSL化して公開する。
- 1つのMySQLコンテナを共通DBとして利用する。
- Ruby on Railsの既存プロジェクトをDocker上で動作させる。
- Ruby on Railsコンテナに対して、dbcreate、migration、seed投入、アセットプリコンパイルする。
- ホストOSのCronスケジュールで、Ruby on Railsコンテナ上のバッチスクリプトをスケジュール実行する。
- OS起動時にコンテナは自動起動にする。
- postfixコンテナでsmtpサーバを建てる。
WordPress、ruby on railsからsmtp接続設定を行い、メール送信する。
上記が実現できれば、一連のWebサービス公開できると思います。
マルチサイトの完成図
投稿者の環境は、サーバ2台を利用し、postfixコンテナだけ、さくらVPSで稼働する。
コンテナの構成
コンテナ | 使用イメージ | 内容 |
---|---|---|
MySQL | mysql:5.7 | コンテナで使用する共通DB |
WordPress (1番目) |
wordpress:latest | WordPressのWebサイト |
WordPress (2番目) |
wordpress:latest | WordPressのWebサイト |
Ruby on Rails | ruby:2.4.1 | Ruby on RailsのWebサイト |
nginx-proxy | jwilder/nginx-proxy | リバースプロキシ、1台のサーバで複数Webサイトをホストする |
letsencrypt-nginx-proxy | jrcs/letsencrypt-nginx-proxy-companion | nginx-proxyと同時使用し、Webサイトの環境変数のVIRTUAL_HOSTを定義することで、WebサイトをSSL化する |
postfix | catatnight/postfix | smtpサーバ |
準備ファイル
順を追って説明するが、下記ファイルを作成する。
/home/web
│
├── docker-compose.yml #コンテナの定義ファイル
│
├── mywebservice.service #OS起動時のコンテナ自動起動のサービス定義ファイル
│
├── rails #配下にRuby on Railsのプロジェクトを配置
│ └── rails_web1 #Ruby on Railsサイト1つ目
│ ├── Dockerfile #Ruby on RailsサイトのDockerfile
│ └── src #Ruby on Railsサイトのソース一式
│
└── sql #Mysqlコンテナ初期起動時に実行するスクリプト
└── docker-entrypoint.sh #WordPress2つ目以降のDB作成スクリプト
docker-compose up後のフォルダ構成
/home/web
│
├── certs #LetsEncryotの証明書配置
│ └── ・・・
│
├── docker-compose.yml #コンテナ定義
│
├── mysql #MySQLデータ
│ └── ・・・
│
├── mywebservice.service #OS起動時のコンテナ自動起動サービス定義
│
├── rails #Ruby on Railsのプロジェクトルート
│ └── rails_web1 #Ruby on Railsサイト1つ目
│ ├── Dockerfile #Ruby on RailsサイトのDockerfile
│ └── src #Ruby on Railsサイトのソース一式
│ ├── config
│ │ ├── database.yml
│ │ └── environments
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── ・・・
│ └── ・・・
│
├── sql #MySQLコンテナ初回起動時スクリプト
│ └── docker-entrypoint.sh #WordPress2つ目以降のDB作成スクリプト
│
└── wordpress #WordPressのフォルダ
├── wp_1 #Wordpressサイト1つ目
│ └── wp-content
│ └── ・・・
│
└── wp_2 #Wordpressサイト2つ目
└── wp-content
└── ・・・
章立て
1.事前準備
2.WordPressサイトを2つ立ち上げる。
3.Let'sEncryptでWordPressサイトをSSL化する。
4.Ruby on Railsサイトを立ち上げる。
5.Ruby on Railsのバッチ処理をCronでスケジュール実行する。
6.postfixのメールサーバを立ち上げる。
7.WebサイトをOS起動時に自動起動にする。
1.事前準備
Docker環境インストール
Docker-Compose環境インストール
Dockerサービス開始、自動起動を設定
#systemctl start docker #Dockerサービス開始
#systemctl enable docker #Docker自動起動
2.WordPressサイトを2つ立ち上げる
(1)docker-compose.yml に導入するコンテナを定義する。
#vi docker-compose.yml
version: '2'
services:
db:
container_name: mysql
image: mysql:5.7
ports:
- 3306:3306
volumes:
- ./sql:/docker-entrypoint-initdb.d
- /home/web/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_USER : root
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wp_1
MYSQL_USER: wp_1
MYSQL_PASSWORD: password
restart: always
wordpress1:
container_name: wp_1
depends_on:
- db
image: wordpress:latest
volumes:
- /home/web/wordpress/wp_1/wp-content:/var/www/html/wp-content
external_links:
- db
expose:
- 80
environment:
VIRTUAL_HOST: XXXXXX.XXX #WordPress1つ目のドメイン名
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wp_1
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: password
restart: always
wordpress2:
container_name: wp_2
depends_on:
- db
image: wordpress:latest
volumes:
- /home/web/wordpress/wp_2/wp-content:/var/www/html/wp-content
external_links:
- db
expose:
- 80
environment:
VIRTUAL_HOST: XXXXXX.XXX #WordPress2つ目のドメイン名
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wp_2
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: password
restart: always
nginx-proxy:
container_name: nginx_proxy
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/nginx/vhost.d
- /usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
- restart: always
networks:
default:
external:
name: net-proxy
nginx-proxyコンテナは、リバースプロキシです。VIRTUAL_HOSTの定義を自動で探して、Webサイトを公開してくれます。
(2)2つ目のDB作成
MySQLコンテナは、初回起動時に初期DBは作成してくれるが、2番目以降のDBは作成しない。
今回、WordPressサイト毎にDBを用意するため、2つDBを用意する。
2つ目以降のDB作成方法として、MySQLコンテナ内のエントリーポイントを利用する。
このエントリーポイントのフォルダにシェルやSQLを配置しておくと、これらを初回起動時に実行してくれる。
この仕組を利用し、WordPressの2番目以降のDBを作成する。
docker-compose.ymlに、エントリーポイントのフォルダ記載を行い、ホスト側のエントリーポイントにシェルを配置する。
services:
db:
#---途中省略---
volumes:
- ./sql:/docker-entrypoint-initdb.d
#---途中省略---
#mkdir /home/web/sql -p
#vi /home/web/sql/docker-entrypoint.sh
echo "CREATE DATABASE IF NOT EXISTS \`wp_2\`;" | "${mysql[@]}"
echo "GRANT ALL ON \`wp_2\`.* TO '"$MYSQL_USER"'@'%';" | "${mysql[@]}"
echo 'FLUSH PRIVILEGES;' | "${mysql[@]}"
(3)コンテナ用のネットワーク作成
#docker network create net-proxy
(4)コンテナ起動
#docker-compose up -d
(5)ブラウザで動作確認
ブラウザでアクセスすると、WordPressのサイト1、サイト2が表示される。
3.Let'sEncryptでwordpressサイトをSSL化する。
letsencrypt-nginx-proxy-companionコンテナを導入する。
WordPressコンテナのenvironmentに以下の2つを追加すると、Let'sEncryptでSSL化される。
- LETSENCRYPT_HOST
- LETSENCRYPT_EMAIL
(1)letsencrypt-nginx-proxy-companionコンテナを導入する。
#vi docker-compose.yml
#---途中省略---
wordpress1:
#---途中省略---
environment:
#---途中省略---
LETSENCRYPT_HOST: xxxxxx.xxx #+追加行、WordPress1つ目のドメインのホスト名
LETSENCRYPT_EMAIL: xx@xxxxxx.xxx #+追加行、メールアドレス
#---途中省略---
wordpress2:
#---途中省略---
environment:
#---途中省略---
LETSENCRYPT_HOST: xxxxxx.xxx #+追加行、WordPress2つ目のドメインのホスト名
LETSENCRYPT_EMAIL: xx@xxxxxx.xxx #+追加行、メールアドレス
letsencrypt-nginx-proxy-companion: #+追加行
image: jrcs/letsencrypt-nginx-proxy-companion #+追加行
volumes: #+追加行
- /home/web/certs:/etc/nginx/certs:rw #+追加行
- /var/run/docker.sock:/var/run/docker.sock:ro #+追加行
volumes_from: #+追加行
- nginx-proxy #+追加行
restart: always #+追加行
nginx-proxy:
#---途中省略---
volumes:
- /home/home/web/certs:/etc/nginx/certs:ro #+追加行
#---途中省略---
(2)コンテナ再起動
#docker-compose restart
(3)ブラウザで動作確認
ブラウザでアクセスすると、WordPressのサイト1、サイト2がSSL化されて表示される。
4.Ruby on Railsサイトを立ち上げる。
Ruby on Railsサイトの既存プロジェクトをDocker環境に移行し、稼働させる。
(1)Ruby on Railsのコンテナを追加する。
#vi docker-compose.yml
rails_web1: #+追加行
build: #+追加行
context: ./rails/rails_web1 #+追加行、rubyコンテナのDockerfileの場所
dockerfile: Dockerfile #+追加行、rubyコンテナのDockerfile
container_name: rails_web1 #+追加行
#command: bundle exec rails s -p 80 -b '0.0.0.0' -e production #+追加行、developmentの場合
command: bundle exec rails s -p 80 -b '0.0.0.0' -e development #+追加行、productionの場合
environment: #+追加行
VIRTUAL_HOST: xxxxxx.xxx #+追加行、Ruby on Railsサイトのドメイン名
LETSENCRYPT_HOST: xxxxxx.xxx #+追加行、Ruby on Railsサイトのドメインのホスト名
LETSENCRYPT_EMAIL: xx@xxxxxx.xxx #+追加行、メールアドレス
volumes: #+追加行
- ./rails/rails_web1/src:/myapp #+追加行
expose: #+追加行
- 80 #+追加行
depends_on: #+追加行
- db #+追加行
restart: always #+追加行
(2)Dockerfileを定義する。
#mkdir -p ./rails/rails_web1/src
#vi ./rails/rails_web1/Dockerfile
FROM ruby:2.4.1
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /myapp
WORKDIR /myapp
ADD ./src/Gemfile /myapp/Gemfile
ADD ./src/Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD ./src /myapp
(3)Ruby on Railsの既存ソース一式をホスト側の「src」ディレクトリに配置する。
/home/web
└── rails #配下にRuby on Railsのプロジェクトを配置
└── rails_web1 #Ruby on Railsサイト1つ目
├── Dockerfile #Ruby on RailsサイトのDockerfile
└── src #Ruby on Railsサイトのソース一式
(4)Ruby on RailsのDB定義を行う。
docker-compose.ymlに記載したServiceのDB情報をdatabase.ymlに記載する。
vi /home/web/rails/rails_web1/src/config/database.yml
default: &default
adapter: mysql2
encoding: utf8
pool: 5
username: root
password: password
host: db
database: db_rails
development:
<<: *default
production:
<<: *default
(5)コンテナ再起動
#docker-compose restart
(6)ブラウザで動作確認
ブラウザでアクセスすると、Ruby on RailsサイトがSSL化されて表示される。
(7)db_create、migration、seed投入、アセットプリコンパイル
Ruby on Railsサイトに対して、db_create、migration、seed投入、アセットプリコンパイルを行う。
docker exec rails_web1 bundle exec rake db:create db:migrate db:seed
docker exec rails_web1 bundle exec rake assets:precompile RAILS_ENV=production
5.Ruby on Railsのバッチ処理をCronでスケジュール実行する。
コマンドラインからのバッチ実行で動作するかを確認する。
#docker exec rails_web1 bundle exec rake cron:xxxxx RAILS_ENV=production
動作に問題なければ、ホスト側のcrontabに登録する。
#crontab -e
0 18 * * * docker exec rails_web1 bundle exec rake cron:xxxxx RAILS_ENV=production
6.postfixのメールサーバを立ち上げる。
(1)catatnight/postfixのコンテナを稼働する。
docker run -p 25:25 \
-e maildomain=xxxxxx.xxx -e smtp_user=user:password \
--name postfix -d catatnight/postfix
dockerで起動したメールサーバコンテナのローカルIPアドレスは、以下で取得できます。1台のサーバ内でWebサーバ、メールサーバ等が同居して動かしている場合は、ここで取得するローカルIPがメールサーバのIPアドレスとなります。
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' コンテナID
(2)Ruby on Railsのメール送信を設定する。
Ruby on RailsのAction Mail設定を行う。
vi /home/web/rails/rails_web1/src/config/environments/production.rb
#Error キャッチ有効化※メールが送信できない時の調査用
config.action_mailer.raise_delivery_errors = true
#メールテスト送信設定
config.action_mailer.smtp_settings = {
:address => "xxxxxx.xxx",
:port => 25,
:domain => 'xxxxxx.xxx',
:user_name => "user@xxxxxx.xxx", #アドレス
:password => "password", #パスワード
:openssl_verify_mode => 'none' #SSL無効
}
設定後、Ruby on Railsサイトからメール配信を行い、正常にメール送信する事を確認する。
(3)WordPressのメール送信を設定する。
WordPressに「WP Mail SMTP」プラグインを導入し、メール送信サーバを設定する。
WordPress側のSMTP送信テストを行い、正常にメール送信することを確認する。
7.WebサイトをOS起動時に自動起動にする。
(1)サービスファイルを作成する。
#vi /home/web/mywebservice.service
[Unit]
Description=My Service
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/home/web
ExecStartPre=/usr/local/bin/docker-compose stop
ExecStartPre=/usr/local/bin/docker-compose rm
ExecStartPre=/usr/local/bin/docker-compose down
ExecStartPre=rm /home/web/rails_web1/src/tmp/pids/server.pid -f
ExecStart=/usr/local/bin/docker-compose up -d
[Install]
WantedBy=multi-user.target
(2)サービスファイルを有効にする。
#cp /home/web/myservice.service /etc/systemd/system/
#systemctl daemon-reload
#systemctl enable myservice.service
#systemctl start myservice.service