【利用シーン】仮想サーバーに環境構築をする時
こんにちは。GMOクラウドの縞子です。
以前、クラウドアカデミーに「ALTUS Basic上でDockerを使って開発環境を構築してみました」という記事を投稿しました。今回は、その後より実際的に開発環境として使うために付け加えたDockerの利用手順について紹介したいと思います。
- Ⅰ. 実現したいこと
- Ⅱ. LAMP + SSHサーバー環境の作成
- Ⅱ-Ⅰ. Dockerfileの編集
- Ⅱ-Ⅱ. 追加ファイルの内容について
- Ⅲ. Dockerイメージのビルド
- Ⅳ. Dockerコンテナの起動
- Ⅴ. DockerコンテナにSSHで接続
- Ⅵ. Apache + PHP状態確認
- Ⅶ. MySQLの接続確認
- Ⅷ. 最後に…
- Ⅸ. 参考情報
- 連載『Dockerを使って開発環境を構築してみました』のほかの記事はこちら
第1回:ALTUS Basic上でDockerを使って開発環境を構築してみました - 第2回:この記事
Ⅰ. 実現したいこと
- ALTUS Basicに作成した仮想サーバー上に、LAMP (Linux + Apache + MySQL + PHP) 環境をDockerコンテナで作る。このとき、ApacheとMySQLは自動起動するように設定する。
- 作成されたコンテナに対し、ローカルPCからSSHで接続できるようにする。
- 任意のユーザーを追加し、そのユーザーのパスワードを設定する。
- Apacheにバーチャル ホストの設定を追加し、任意のディレクトリをWebサイトのルート ディレクトリに指定する。
- 4で指定したWebサイトのルート ディレクトリ内に、3で追加したユーザーがファイルの追加、削除または変更をできるようにする。
- 作成したコンテナのイメージをDockerリポジトリにpushし、別の環境でpullできるようにする。
前回の手順をベースに、1~5までの手順を確認します。6についてはプライベート リポジトリを構築して実現したいと考えていますが、まだその準備が整っていないため今回は割愛します。
Ⅱ. LAMP + SSHサーバー環境の作成
作成する環境は次の通りです。
- CentOS 6.6
- Apache 2.2 (ssl対応無し)
- MySQL 5.6 (community版)
- PHP 5.6
- OpenSSH
Dockerコンテナを起動した際、Apache、MySQLおよびsshdなどのサービスを自動起動させたいと思います。
Dockerfileへのsshdのインストール・設定方法は、Docker公式サイトや、Docker HubにアップされているさまざまなDockerfileに例がありますので、これらを参考にします。
また、1つのサービスを起動させる際には、Dockerfileの中でCMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"] のようにCMDまたはENTRYPOINTなどのコマンドを使用しますが、複数サービスを起動させる場合には少し工夫が必要となります。
Dockerの公式サイトに、その工夫の一つとしてsupervisorを利用する手順が紹介されていましたので、こちらを参考にして設定を記述してみます。
Ⅱ-Ⅰ. Dockerfileの編集
DockerエンジンをインストールしたホストOS上に/var/opt/docker/repository/lamp_sshというディレクトリを作成し、そのディレクトリ内に必要な設定を記述したDockerfileを作成しました。
$sudo -s
#mkdir –p /var/opt/docker/repository/lamp_ssh
#cd /var/opt/docker/repository/lamp_ssh
#vi Dockerfike
※ここではエディターとしてviを使用しましたが、viに馴染みの無い方はその他のエディターを(emacsなど)を使用するか、ローカルPC上で編集したDockerfileをホストOSに転送してください。
作成したDockerfileの内容は次の通りです。
●Dockerfile
MAINTAINER GMO Cloud### Install Apache, MySQL, PHP, openssh, sudo, git and supervisor ---①
RUN yum clean all ¥
&& yum -y update ¥
&& yum install -y http://repo.mysql.com/mysql-community-release-el6-4.noarch.rpm ¥
&& yum install -y http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
RUN yum install -y httpd ¥
mysql-community-server ¥
mysql-community-client ¥
openssh-server ¥
sudo ¥
python-pip ¥
git
RUN yum --enablerepo=remi-php56 install -y ¥
php ¥
php-mysqlnd ¥
php-cli ¥
php-mbstring ¥
php-mcrypt ¥
php-pdo ¥
php-xml
RUN yum clean all
RUN pip install --upgrade supervisor supervisor-stdout### supervisord setting ---②
ADD supervisord.conf /etc/supervisor/supervisord.conf### sshd setting ---③
RUN sed -i -e "s|^#PermitRootLogin .*$|PermitRootLogin yes|" /etc/ssh/sshd_config \
&& sed 's@session\*required\*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa ¥
&& ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa ¥
&& chmod -R 700 /etc/ssh### MySQL setting ---④
RUN mv /etc/my.cnf /etc/my.cnf.org
ADD my.cnf /etc/my.cnf
RUN chmod 640 /etc/my.cnf
RUN /etc/init.d/mysqld start ¥
&& sleep 3 ¥
&& mysqladmin -u root password 'mysqlpass' ¥
&& (echo 'grant all privileges on *.* to testuser@"localhost" identified by "testuser123" with grant option;' | mysql -u root -pmysqlpass) ¥
&& (echo 'grant all privileges on *.* to testuser@"%" identified by "testuser123" with grant option;' | mysql -u root -pmysqlpass) ¥
&& /etc/init.d/mysqld stop
RUN /usr/bin/mysql_install_db### PHP setting ---⑤
RUN sed -i -e "s|^;expose_php =.*$|expose_php = Off|" /etc/php.ini ¥
&& sed -i -e "s|^;date.timezone =.*$|date.timezone = Asia/Tokyo|" /etc/php.ini ¥
&& sed -i -e "s|^;mbstring.language =.*$|mbstring.language = Japanese|" /etc/php.ini ¥
&& sed -i -e "s|^;mbstring.encoding_translation =.*$|mbstring.encoding_translation = On|" /etc/php.ini ¥
&& sed -i -e "s|^;mbstring.detect_order =.*$|mbstring.detect_order = auto|" /etc/php.ini ¥
&& sed -i -e "s|^;mbstring.substitute_character =.*$|mbstring.substitute_character = none|" /etc/php.ini### Change the root's password and add a new user ---⑥
RUN echo "root:password123" | chpasswd ¥
&& useradd testuser ¥
&& echo "testuser:testuser123" | chpasswd### Make a virtual host ---⑦
COPY develop.conf /etc/httpd/conf.d/
RUN mkdir -p /home/webroot/develop
COPY index.php /home/webroot/develop/
RUN chown -R testuser:apache /home/webroot### Expose httpd, mysqld and sshd ports. ---⑧
EXPOSE 80 3306 22### Start multiple processes from supervisor ---⑨
CMD ["/usr/bin/supervisord", "--configuration=/etc/supervisor/supervisord.conf"]
※ファイルの内容についての補足※
① 必要な各種パッケージをインストールします。
まずはApache、MySQL、sudo(rootアカウントに昇格するためのパッケージ)、PHP、gitおよびpython-pipをyumコマンドでインストールします。
Supervisorもyumのepelリポジトリからインストールできるのですが、その場合supervisorからMySQLを起動するときに使うpidproxy というツールがインストールされないため、pip(pythonのパッケージ管理用パッケージ)からsupervisorをインストールします。
② あらかじめ用意したsupervisord.confをコンテナ内にコピーします。
③ sshdの設定を行います。ここではrootアカウントのパスワードによるログオンを許可し、ログオンの前後でログオン ユーザーのuidをプロセスの属性に記録するように指定しています。
また、SSHサーバーの鍵をRSAとDSAの2つの認証方式で生成しています。
④ MySQLの初期設定を行っています。あらかじめ用意したMySQLの設定ファイル(my.cnf)をコンテナ内にコピーし、デフォルトで用意されていたmy.cnfと差し替えます。
続いてMySQLのrootアカウントのパスワードを変更し、testuserアカウントをMySQLに追加します。testuserアカウントにはローカルからの接続と、リモートからの接続の両方を許可します。
⑤ PHPの設定を行います。ここでは日本語利用のための設定を行っています。
⑥ OSのrootアカウントのパスワードを変更します。また、testuserアカウントを追加し、このユーザーのパスワードを設定します。
⑦ ApacheのデフォルトWebルート ディレクトリ(/var/www/html)以外のディレクトリ(/home/webroot/develop)に開発ソースコードを置きたいため、このディレクトリをWebルート ディレクトリとするバーチャル ホスト設定を追加します。
⑧ Apache、MySQLおよびsshdに接続するために、TCPの各ポート(80、3306および22番)を通信待ち受け状態にします。
⑨ Dockerコンテナをバックグラウンドで実行した際にsupervisorを自動起動させます。なお、SupervisorはApache、MySQLおよびsshdを起動します。
Ⅱ-Ⅱ. 追加ファイルの内容について
作成したDockerfile内では、次の4つのファイルをコンテナ内にコピーするよう指示しています。コピーする各ファイルは、Dockerfileと同じ場所(/var/opt/docker/repository/lamp_ssh/)に保存しておきます。
●コンテナ内にコピーするファイル
- supervisord.conf ・・・ supervisorの設定ファイル
- my.cnf ・・・ MySQLの設定ファイル
- develop.conf ・・・ Apacheのバーチャル ホスト設定ファイル
- index.php ・・・ Apache+PHPの動作確認用PHPファイル
それぞれのファイル次の内容で作成しました。
■supervisord.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
[program:httpd]
command=/usr/sbin/apachectl -D FOREGROUND
[program:mysql]
command=/usr/bin/pidproxy /var/run/mysqld/mysqld.pid /usr/bin/mysqld_safe
autostart=true
autorestart=true
※supervisord.confでは、プロセスの起動コマンドを記述します。最初の2行ではsupervisord自身をフォアグラウンドで起動するように設定しています。この設定が無い場合、Dockerコンテナ内でsupervisorが指定した各プロセスを起動できなくなりますので必ず記述します。
■my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
default-storage-engine=innodb
explicit_defaults_for_timestamp=true
# UTF8 settings
character_set_server = utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[mysql]
default-character-set=utf8
[client]
default-character-set=utf8
※MySQLの設定ファイルをあらかじめ用意し、コンテナ内のデフォルトで用意されたmy.cnfと差し替えます。今回は必要最小限の設定のみを記述していますので、環境に応じて設定を追加・編集します。
■develop.conf
<VirtualHost *:80>
ServerAdmin testuser@xxx.yyy.zzz (※任意のメールアドレスを指定)
ServerName xxx.yyy.zzz (※Dockerコンテナ上で動作するサーバーのDNS名を指定)
DocumentRoot /home/webroot/develop
<Directory /home/webroot/develop>
AllowOverride all
Options -MultiViews
</Directory>
</VirtualHost>
■index.php
<?php
phpinfo();
※develop.confで設定した/home/webroot/develop配下に、このindex.phpファイルを置きます。もし設定が適切になされていれば、WebブラウザからDockerコンテナのTCP 80番ポートにアクセスした際、このindex.phpファイルが読み込まれてPHPの設定が表示されるはずです。
Ⅲ. Dockerイメージのビルド
Dockerfileをビルドして、Dockerイメージをビルドします。
#docker build -t gmocloud/lamp_ssh /var/opt/docker/repository/lamp_ssh/.
ビルドが開始され、最後に「Successfully built」のメッセージが表示されたら成功です。
Ⅳ. Dockerコンテナの起動
ではいよいよDockerコンテナを起動します。
#docker run -d -p 10022:22 -p 13306:3306 -p 10080:80 --name lamp_ssh gmocloud/lamp_ssh
前回も補足しましたが、-p オプションでポートをバインディングしています。たとえばDockerコンテナ内のTCP 22番ポートをホストOSのTCP 10022番ポートにバインディングしています。また、--nameオプションでコンテナの名前を指定しています。
Ⅴ. DockerコンテナにSSHで接続
設定が適切にできていれば、コンテナにSSHで接続できるはずです。
ローカルPCからTeratermなどの端末エミュレーターを利用してコンテナに接続してみます。
●接続設定
ホスト: DockerホストOSのDNS名またはIPアドレス
接続先ポート: TCP 10022
ユーザー名: testuser
パスワード:testuser123
無事ログオンできました!
ちなみに上記の接続設定を使用してeclipseやNetBeansなどのIDEにてリモート接続設定を行いますと、通常にWebルート ディレクトリ(/home/webroot/develop)上のファイル編集が可能となります。
Ⅵ. Apache + PHP状態確認
次に、ApacheとPHPが正常に動作しているか確認します(前回も同じ確認をしましたね)。
正常に動作していれば、WebブラウザからコンテナのWebサイトにアクセスした際にindex.phpのファイルがロードされるはずです。
コンテナ内のWebサイトは次のURLでアクセスできます。
http://(DockerホストOSのDNS名またはIPアドレス):10080
PHPの設定情報が表示されましたので、ApacheとPHPは正常に動作しています。
Ⅶ. MySQLの接続確認
最後にMySQLへリモートから接続できるかを確認します。
DockerホストOSとは別のLinuxサーバーからコンテナのMySQLサーバーにリモート接続してみます。なお、接続元LinuxサーバーにはMySQLのクライアント(mysql-community-client)をあらかじめインストールしておきます。
以下のコマンドを、接続元Linuxサーバー上で実行します。
$ mysql -h {DockerホストOSのDNS名またはIPアドレス} -P 13306 -u testuser –p
Enter password:{Dockerfile内で指定したパスワード: testuser123を入力}
接続が成功しましたら、次のように" mysql>" プロンプトが表示されます。
接続できましたね!
Ⅷ. 最後に…
今回作成したDockerfileを含む各種設定ファイルは基本的な設定のみを記述しており、実際の運用環境やセキュリティについて十分な考慮、検討した設定にはなっていません。あくまでも参考情報としてご参照ください。
また、Dockerの大きなメリットであるポータル化(作成したDockerイメージを別の環境で実行する手順)については、プライベート リポジトリを用意して試したいと考えていますので、その方法を確認できましたら、またクラウドアカデミーで紹介したいと思います。