- 投稿日:2019-03-30T22:18:32+09:00
[Docker]AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.0.2. Set the 'ServerName' directive globally to suppress this messageDockerで
docker-compose up --buildってやると必ず出てくるこの警告(私が)。
解決として、https://askubuntu.com/questions/256013/apache-error-could-not-reliably-determine-the-servers-fully-qualified-domain-n
に書いてあることで解決できました。しかし、このページが英語であること。DockerでないのでDockerの場合の対策方法を書きます。
と言ってもDockerファイルに以下を追記してもらうのみです!
RUN echo "ServerName localhost" | tee /etc/apache2/conf-available/fqdn.conf RUN a2enconf fqdn内容はというと、
teeがファイルの書き込みのようなので、
fqdn.confにServerName localhostを書くということみたいです。
書き込みと言っても、もともとないのでファイル作成、書き込みを行う感じですね。a2enconfはfqdnのファイルを有効にするというものらしい。
なので上記追加でコンテナの中はこんな感じになってます!!
root@056e18a8a70b:/etc/apache2/conf-available# ls charset.conf docker-php.conf fqdn.conf localized-error-pages.conf other-vhosts-access-log.conf security.conf serve-cgi-bin.conf root@056e18a8a70b:/etc/apache2/conf-available# cat fqdn.conf ServerName localhost root@056e18a8a70b:/etc/apache2/conf-available#上記の内容を簡単に説明
現在いるところ(/etc/apache2/conf-available) で フォルダの中のリスト表示(ls)
fqdn.conf が追加されていることが確認できるとで cat で中身確認
ServerName localhostが記述されている
っと言った感じです。
ちなみにこれ、
https://help.ubuntu.com/community/ApacheMySQLPHP#Troubleshooting_Apache
のトラブルシューティングに書いてあるよと言っていますね!参考
https://askubuntu.com/questions/256013/apache-error-could-not-reliably-determine-the-servers-fully-qualified-domain-n
https://eng-entrance.com/linux-command-tee
http://www.ei.fukui-nct.ac.jp/~t-saitoh/mt/2015/10/debianapache2.html
- 投稿日:2019-03-30T09:37:05+09:00
redisとruby on railsの連携
環境
macOS Mojava 10.14.4
Docker 18.09.2
Rails 5.2.2
ruby 2.6.1p33Webアプリケーションのセッション管理の方法はいくつかあるのですが、ruby on railsは特に指定しなければローカルのCookieにセッションが保存されます。
この状態でrailsを動作させるとCookieが作成されています。
Safariだと
Safari > 環境設定 > プライバシー > CookieとWebサイトのデータ:
を確認すると127.0.0.1のWebサイトのデータが保存されています。(ローカル開発時)開発だけであればいいんですが、実際の環境でユーザーCookieでセッション情報を管理するのは問題があるのでredisで管理するようにしました。
redisをインストール
$brew install redis ・・・インストールログ・・・ ==> Summary ? /usr/local/Cellar/redis/5.0.4: 13 files, 3.1MBなんかログにビールが出ました。多分成功の証です。
$redis-cli Could not connect to Redis at 127.0.0.1:6379: Connection refusedインストールできていました。
redisサーバーが起動してないので接続できていません。せっかくなんで学習のため、redisサーバーはDockerコンテナを使ってみようかと思います。
Dockerのインストールはこちらを参考にしました。
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81redisのDockerコンテナーの起動
停止したら削除するために--rmをつけます。
-pでコンテナのポートを公開します。(ホストのポート6379をコンテナのポート6379に接続)$docker container run --name local-redis -d --rm -p 6379:6379 redis Unable to find image 'redis:latest' locally latest: Pulling from library/redis 27833a3ba0a5: Pull complete cde8019a4b43: Pull complete 97a473b37fb2: Pull complete c6fe0dfbb7e3: Pull complete 39c8f5ba1240: Pull complete cfbdd870cf75: Pull complete Digest: sha256:000339fb57e0ddf2d48d72f3341e47a8ca3b1beae9bdcb25a96323095b72a79b Status: Downloaded newer image for redis:latest cbc1a37039dab71ce996cecdae2cd7cbdbbb78cd76e281ff5837eac3113dd403dockerイメージがローカルにない場合はDocker Hubから自動でPullしてくれます。
https://hub.docker.comredisのコンテナが動作しているかの確認
$docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cbc1a37039da redis "docker-entrypoint.s…" 51 seconds ago Up 50 seconds 0.0.0.0:6379->6379/tcp local-redis--nameで指定した名前がNAMESに出力されています。(コンテナの名称)
接続できることを確認します。
redis-cli 127.0.0.1:6379>exitを入力し、終了
redisサーバーが用意できたので、railsのセッションをredisで管理するように変更します。
redisを使うためGemfileにredis-railsを追加します。
Gemfilegem ‘redis-rails’インストールを行います。
bundle installrailsのセッションの設定を行います。
config/initializers/session_store.rbにredisにセッション情報を格納することを記載します。
特に何も設定していない場合はsession_store.rbは存在しないので作成します。session_store.rbRails.application.config.session_store :redis_store, { servers: [ { host: ENV['REDIS_HOST'] || 'localhost', port: ENV['REDIS_PORT'] || 6379, db: 0, namespace: 'session' } ], expire_after: 10.minutes }これでセッション情報はredisに記録されるようになります。
実際にredisコンテナを停止させてからrailsを起動するとredisに接続できないことによるエラーが発生します。
SafariでCookieを確認しても127.0.0.1のWebサイトの情報はなくなります。ローカル開発でこれをやると、毎回redisコンテナを起動させないとエラーで落ちてしまうのでなにか自動化は別途しようと思います。
- 投稿日:2019-03-30T07:02:47+09:00
Windows7環境なのにdocker入れて開発することになった話【③docker開発環境編】
はじめに
2章では、不足していたライブラリやソフトウェアを導入し、実際に動作確認を行いました。3章では、2章で動作確認を行ったモジュール群を、docker環境下でどのように実行させるのかを記述していきます。ついにdockerについて触れます。章の構成としては、以下の構成となります。
開発環境における動作確認
- コンテナにマウントするためのpythonファイルをテストする
python XXXX.pyにてモジュールを実行する(2章で解説したため割愛)- DockerFile、docker-compose.yml、shellを駆使して「1.」と同様の動きを実現する
デプロイ環境における動作確認
- 開発環境にて作成したDockerFile、docker-compose.ymlを利用してデプロイする
本章を読んでいただくことで、以下のDockerFileを作ることのメリットが伝わると幸いです。
メリット1
dockerをインストール済みの環境(1章参照)であれば、DockerFileとソースコードを共有することで、環境構築なしで実行することができる。GitHubではソースコードの共有まではできるが、開発環境の共有はできないため、共同開発を行う際は非常に有用なメリット。
メリット2
コンテナを利用可能なサービス(AWSではESC)において、簡単にデプロイできる。(本章では開発環境までしか触れられないので次章以降になります)
メリット3
そのアプリケーションを実行するための環境が、DockerFile内に全て書かれているため、開発環境・本番環境に対してどのようなソフトウェアやライブラリが必要か一目で分かる。
一応デメリットも
- DockerはLinuxカーネルを利用しているため、Linux環境下を推奨。(Windows10からはDocker ToolboxからWSLを利用することで実行できるが、まだまだ不安定なのが現状
- 開発者が、開発環境にインストールされるソフトウェア/ライブラリを意識せずに開発を行えてしまうため、開発終盤までいっても環境を把握している人はチームに数人しかいないことになる
ついにdockerに触れられるということで前置きが長くなりましたが、今しばらくの間お付き合いください。
第3章
技術バリバリの人「動作確認お疲れ!DockerFile書けた?」
わたし「書けるわけないじゃないですか。そもそもなんですかdockerって」
技術バリバリの人「1章で教えて上げたじゃん」
技術バリバリの人「あ、あと開発環境はもちろんgit使うし、ビルドの情報とかは全部Dockerファイルに書くね。さらに言えばdocker-compose使っちゃえば複数のサーバーをビルドする情報がチーム全体でで同時に管理できちゃったりするねー」
わたし「そういえば単語は一回聞きましたね。でも何言ってるか分からないです。簡単に教えてください!」
技術ばりばりの人「…分かった、Dockerの中身の話を全部話すと長くなるから、1章の辞書整理を見てね。今からは、実際にdockerを使った際に実感できるメリットについて2つ話すね」
技術ばりばりの人「まずこの図を見てね。これは、今回のアプリケーションのライブラリやソフトウェアを、dockerを利用して管理した場合の概念図だよ。左の青い部分がDockerfileで、今回は2つのDockerfileを作ろう。上の『GetNews_Dockerfile』の部分が、インターネットからデータを取得するモジュールに必要なライブラリ/ソフトウェア郡だね。下の『Post_Dockerfile』部分はまだ実装していないけど、取得したデータを外部に送信する部分だね」
わたし「『GetNews_Dockerfile』に、2章でインストールした、スクレイピングで使用する『beautifulsoup4』、AWSにローカルからアクセスする『boto3』、自然言語処理で利用する『mecab』が書いてますね」
技術ばりばりの人「そうだね。2章で既に君が開発環境にインストールしたライブラリ/ソフトウェアを書いただけだよ。次は真ん中の黄色い部分、docker-compose.ymlについて説明するね」
技術ばりばりの人「docker-composeを使うことで、Dockerfileに定義されたコンテナを共通管理することができるんだ。開発したソフトウェアをコンテナ上のどの領域にマウントして、最初に実行するコマンドは何を実行するか等を定義することができるよ」
わたし「もしdocker-composeが無かったらどうなるんですか?」
技術ばりばりの人「もしdocker-composeを使わなかった場合、ビルド・デプロイ・破棄・スケール・ネットワーク設定などのコマンドを、それぞれのDockerコンテナ/イメージに対して実行する必要があるんだ」
わたし「ビルド・デプロイ・破棄だけでも単純にコンテナの数だけコマンドたたく回数が増えちゃうんですね」
技術ばりばりの人「そうだね。正確にはスケールやネットワーク設定についてはDockerfileでやれちゃう部分もあるんだけど、ソフトウェア/ライブラリ部分はDockerfile、ネットワークやスケールなどのインフラ周りについてはdocker-composeに任せちゃう運用が分かりやすいね」
わたし「開発環境の管理が楽なことがなんとなく分かってきました!」
技術ばりばりの人「じゃぁこれでもDockerfileとdocker-compose.ymlが書けるね!よろしく!」
わたし「はい!」
技術ばりばりの人「あ、そうだ、MeCabのDocker化は1癖も2癖もあるらしいから気をつけてね。まぁ大丈夫だね!それじゃ!」
わたし「え、ちょ」
辞書整理
本文章(第3章)を読む上で頭に入れておいたほうが良い文言をピックアップ。文中分からない文言が出たら見返してください。(不足あれば、コメントいただけたら追記していきます)
忙しい人はここだけ読めばDockerの概念がつかめるので、下記は補足として読んでください。
コンテナ
- ホストOS(Linux限定)のkernel機能を利用することで、仮想サーバのような立ち振る舞いをする
- プロセス・メモリ・デバイス・ネットワーク等、仮想サーバとして必要な部分についてはコンテナごとに保有する
- ホストOSから見ると、単に1プロセスが起動しているように見えている
- kernel部分は複数コンテナで共有しているため、kernelにかかわるような操作はできない(正確にはできるがやらない)
- kernelを共有しているため、kernel依存のエラーである「オープンしているファイルの最大数を超える」等のエラーが、ゲストOS(コンテナ)・ホストOSをまたいで生じることがある
- Dockerとコンテナは意味が異なり、「Dockerソフトウェアを用いてコンテナという概念を扱っている」が正しい
- Dockerにおいては、コンテナがkernelを共有して実行している部分は「Docker daemon」が担っている
- 参考:コンテナ技術の基礎知識
Dockerデーモン
- Linux kernelをコンテナから実行する、いわばホストOSとゲストOS(コンテナ)の橋渡しの部分
- ホストOSの環境変数、プロキシ設定、DNS設定などをコンテナでも利用したい場合は、Dockerデーモンのオプションを修正する
- コンテナから見ると、ある意味kernelのような存在
- Linuxのコマンド、「systemctl」で操作できる
- 参考:Dockerデーモンに関するもう少し詳しい説明
Dockerイメージ
- コンテナを実行する時に必要なファイルシステム
- イメージ・レイヤ(Dockerイメージを構成するファイルシステム)の集まり
- 難しいので、OSおよび必要なアプリケーションに必要なソフトウェア一式が書き込まれているディスクのようなものだと認識していれば良い
- 自分で1から作成することも可能であるが、GitHubのような形でイDockerメージを管理しているDockerHubから取得することも可能
- Dockerイメージを作成することをビルド、Dockerイメージをビルドし、アプリケーションをその環境下で実行させることをデプロイと呼んでいる
- 参考:Dockerイメージとは?【Docker解説】
WSL
- Windows Sybsystem for Linux
- Windows環境からLinuxの実行環境を実現するサブシステムのこと
- Windows10以降しか使えない
- Windows10以降にDockerがWindows環境でも使えるようになった原因
- Windows10環境にてDockerを利用するには、DockerToolboxをインストールすることで、同ツールがWSLを利用して、Linuxカーネルを叩いている仕組み
- とはいえ実際動作確認を行っていく中で、まだ不安定であるという噂や、アップデートで動くようになっているという噂もある
- 参考:WSL上でDocker Engineが動くようになっていたっぽいという話
1.Dockerの設定
第1章で書いた内容も重複しますが、インストールした後の設定が一番難しく、しくじるともちろん動かないので、再掲します。ちなみに、公式ドキュメントが一番参考になります。参考:Docker-docs-ja
前提条件
第1章のDockerのインストールが完了している
proxyおよびDNS設定
社内等プロキシ環境下で実行している場合、Dockerデーモン実行時にプロキシの設定を渡す必要があるため、Dockerデーモンのオプション設定を変更する。(Ubuntu環境を想定しています。)
- プロキシおよびDNSサーバの設定
$ sudo mkdir -p /etc/systemd/system/docker.service.d/$ sudoedit /etc/systemd/system/docker.service.d/http-proxy.conf[Service] Environment="HTTP_PROXY=http://各プロキシサーバ:8080/" "HTTPS_PROXY=http://各プロキシサーバ:8080/" "NO_PROXY=127.0.0.1,localhost" "DOCKER_NETWORK_OPTIONS=--dns 各DNSサーバ" ExecStart= ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONSDockerデーモンのオプションファイル自体は別にありますが、『docker.service.d/』以下に記載した設定が、Dockerデーモン実行時に上書かれて実行されます。「ExecStart=」の部分はおまじない。最初に空実行を設定することで、2回目の実行時にオプションを指定した状態で上書き実行ができる仕組み。
- Dockerデーモンのリロード
sudo systemctl daemon-reload- Dockerの再起動
sudo systemctl restart docker2.Dockerfileの記載
2章で開発したモジュール郡を動かすためには、下記を「Getnews_Dockerfile(拡張子不要)」という名称で作成する。
Get_news_Dockerfile
FROM python:3.6.5 RUN apt-get update && apt-get upgrade -y RUN apt-get install -y sudo RUN pip install --upgrade pip # ----------- install scrayping module at Python --------------- RUN pip install beautifulsoup4==4.6.3 # --------------------- mecab configure ------------------------ RUN apt-get install mecab mecab-ipadic libmecab-dev -y RUN pip install mecab-python3==0.7 RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git /usr/src/mecab-ipadic-neologd \ && /usr/src/mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y -p /var/lib/mecab/dic/mecab-ipadic-neologd \ && rm -rf /usr/src/mecab-ipadic-neologd # -------------- install aws module at Python ------------------ RUN pip install boto3==1.7.4 WORKDIR ./解説
FROM python:3.6.5
- DockerHub上から、どのDockerイメージをベースにカスタマイズするかを指定。今回の場合は、Python3.6.5を導入したDockerイメージをベースにカスタマイズを加えている
RUN apt-get update && apt-get upgrade -y~RUN pip install --upgrade pip
- apt-getやpipなどソフトウェア管理ツールを最新化しておくおまじない
# ----------- install scrayping module at Python ---------------以降
- スクレイピングに利用するライブラリのインストール
# --------------------- mecab configure ------------------------以降
- MeCabを利用する際に必要なライブラリ/ソフトウェア郡のインストール
# -------------- install aws module at Python ------------------以降
- PythonからAWSアクセスに必要なライブラリのインストール
WORKDIR ./
- デプロイ時、コンテナ内の最初に居るディレクトリを指定
3.docker-compose.ymlの記載
「2.Dockerfile」の記載にて定義したイメージを、コンテナ化して実行するための「docker-compose.yml」を記載する。
docker-compose.yml
version: '2' services: get-news: env_file: .env build: context: ./ dockerfile: Get_news_Dockerfile volumes: - ./shell:/root/shell - ${get_news_root_dir}/backEndLogic:/root/backEndLogic - ${host_aws_credential}:/root/.aws command: > bash -c "chmod +x /root/shell/get_news.sh && /root/shell/get_news.sh" tty: true解説
version: '2'
- docker-composeのバージョンを指定する。HTMLの一番初めに書くバージョン宣言と同じ(HTML5からは書かないが…)
get-news:
- 任意のコンテナ名称。コンテナを立ち上げる際、ターミナルから指定する名称となる
env_file .env
- AWSのシークレットキーやマウントのパスなど、ホストOSの環境依存でパスを指定する部分については別途「.env」ファイルを作っている。Dockerの設定を完璧に行っても、唯一各環境で書き換える必要がある部分。docker-compose.ymlと同フォルダに作成している
build:
- どのDockerfileをbuildするかをここに書く
contextにDockerfileのあるフォルダを指定。今回の場合はdocker-compose.ymlと同フォルダに作成しているdockerfileに、このコンテナ(今回の場合get-news)をbuildするために利用するDockerfile物理名称を指定volumes:
- 各種ローカルからコンテナへのマウント情報。今回の場合は、①shell(後述)、②作成したモジュール郡、③AWSクレデンシャルをマウントする
- ①shellについては各開発者環境で共通して利用するため、docker-compose.ymlと同フォルダに作成し、envを介さずに相対パスを記載
- ②作成したモジュール郡および③AWSクレデンシャルについては各開発者環境で異なるため、envで指定した環境変数を記載
command: >
- デプロイ後最初に実行するコマンドを記載。今回はshell(後述)を呼び出すことで、2章で作成したPythonモジュールの管理や、MeCabの辞書コンパイルなどを行う
参考(.envファイル中身)
# ------------------以下ホストの環境に合わせて変更してください ------------------ # ソースディレクトリへのPath. 各コンテナは以下Pathを参照して環境を構築します. # 指定したディレクトリは、コンテナ上からmountされ参照されます. get_news_root_dir=/home/username/backEndLogic # AWSのcredential情報を記載したファイルパス host_aws_credential=/home/username/.awsインフラ周りの設定情報についても、docker-compose.ymlに書く。たとえばファイルオープン数が最大に達してしまい、コンテナにもっとリソースを割きたい場合は、volumeと同じ階層に以下のように追記すると良い。
ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000※この場合、後述するshellの中にスタックサイズの開放コマンド
$ ulimit -s unlimitedを書く必要がある。4.shellの記載
1~3までで、コンテナ環境の構築や、コンテナ環境へのPythonモジュールのマウントは完了した。しかし、デプロイ後に実際にPythonモジュールを実行したり、MeCabの設定が必要だったりするので、shellを外だしで作成する。
get_news.sh
- MeCabの辞書がローカルで更新されていた場合、Dockerコンテナ上で毎回ユーザ辞書を更新する必要があるため、shellに任せました
- 作成したPythonモジュールを実行するために、main.pyに飛ばしました(ここは各々好きに作ればよいと思います)
get_news.sh# ユーザ辞書のコンパイル cd /root/backEndLogic/mecabDict /usr/lib/mecab/mecab-dict-index \ -d /var/lib/mecab/dic/mecab-ipadic-neologd \ -u /root/backEndLogic/mecabDict/select_dic.dic \ -f utf-8 \ -t utf-8 select_dic.csv # mecabの設定ファイルにユーザ辞書を追記 cd /etc sed -i -e 's@.*userdic.*@userdic = /root/backEndLogic/mecabDict/select_dic.dic@' mecabrc # モジュールのおいてあるパスへ移動 cd /root/backEndLogic/ # News収集機能を実行 python /root/backEndLogic/main.pymain.py
main.pyimport subprocess def main(): subprocess.check_call(['python','ニュース取得機能.py']) print("complete get_news") subprocess.check_call(['python','ニュース選定機能.py']) print("complete select_target") if __name__ == '__main__': main()※実際のアプリケーションとは異なるため、簡易的に「ニュース取得機能.py」、「ニュース選定機能.py」を呼び出すような記載としています
docker-compose実行
ここまでくれば、後は2つコマンドを実行してあげるだけです。その前に、現状のフォルダ構成はこうなっています。
.../ - shell - get_news.sh - Get_news_Dockerfile - docker-compose.yml - .envdocker-compose.ymlと同フォルダに、Dockerfileや.env、shellが置いてあります。(docker-compose.ymlの記載次第)
いよいよコマンドを実行します。実行するコマンドはたったの2つ。(コンテナが増えても同様に2つです)
build
プロキシ環境下
-$ docker-compose build --build-arg https_proxy=${https_proxy} --build-arg http_proxy=${http_proxy} get-news
非プロキシ環境下
-$ docker-compose build get-newsコンテナ起動&デプロイ
$ docker-compose upあとがき
わたし「Docker環境で、pythonモジュールが動きました!」
技術バリバリの人「これで実際にAWS環境にデプロイするときも簡単にできるし、モジュールが複雑化しても実行環境を修正するのが簡単になったね!」
技術バリバリの人「次回はついに、取得したデータをフロントエンドに出力する部分を作っていこう!」
続く
- 投稿日:2019-03-30T06:28:58+09:00
KubernetesとNode.jsでマイクロサービスを作成する 5/8 Dockerを使ったサービス構築
第5章 Dockerを使ったサービス構築
第4章までで、Twitterライクなマイクロサービスを構成する、3つのサービスを作成してきました。
次はいよいよ、これらのサービスをマイクロサービスとして構築するのですが、いきなりKubernetesを利用する前にワンクッションはさみます。本章では、各サービスのDockerイメージを作成し、以下のような構成で、ローカルのDocker環境でTwitterライクなサービスを起動します。
完成版のリポジトリはこちらにあるので、実装がうまくいかない場合は比較してみてください。
reireias/microservice-sample-integrationチュートリアル全体
- 第1章 概要
- 第2章 Tweetサービス
- 第3章 Userサービス
- 第4章 Webサービス
- 第5章 Dockerを使ったサービス構築
- 第6章 Kubernetes with minikube
- 第7章 Kubernetes with GCP
- 第8章 Kubernetes with AWS
構成
dockerとdocker-compose
まずはローカルに
dockerとdocker-composeがインストールされていることを確認しましょう。docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.4 Git commit: e68fc7a Built: Fri Jan 25 14:33:54 2019 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.4 Git commit: e68fc7a Built: Thu Jan 24 10:56:33 2019 OS/Arch: linux/amd64 Experimental: falsedocker-compose version docker-compose version 1.23.2, build 1110ad0 docker-py version: 3.7.0 CPython version: 3.7.2 OpenSSL version: OpenSSL 1.0.2g 1 Mar 2016microservice-sample-integrationリポジトリの作成
ここからは、各サービスのリポジトリ内のコードを利用して、DockerイメージやKubernetesの設定を作成していくことになります。
そのためには、各サービスのコードが参照できる構成が望ましいです。今回は下記のディレクトリ構成をとるような、
microservice-sample-integrationリポジトリを作成します。microservice-sample-integration └── services ├── microservice-sample-tweet ├── microservice-sample-user └── microservice-sample-web実際の開発現場では、このリポジトリの管理をSREチームが主導して行ったり、各サービスの開発者が協力して行ったりします。
microservice-sample-integrationという名前でリポジトリを作成し、cloneしておきましょう。つづいて、このリポジトリ内で行う各種操作を
Makefileに記述し、makeコマンドから実行できるようにします。
作成するコマンドは下記の通りです。
clone: 各サービスをservicesディレクトリ以下にcloneするpull: 各サービスをgit pullするbuild: 各サービスのDockerイメージのビルドを行うup: 全サービスをdocker-composeを使って、ローカルのDocker環境で立ち上げるdown: 全サービスをdocker-composeを使って削除するseed: UserサービスとTweetサービスでscripts/initialize.jsを実行する
Makefileは以下のようになります。MakefileWEB_REPOSITORY := https://github.com/reireias/microservice-sample-web USER_REPOSITORY := https://github.com/reireias/microservice-sample-user TWEET_RESPOSITORY := https://github.com/reireias/microservice-sample-tweet clone: git clone $(WEB_REPOSITORY) ./services/microservice-sample-web git clone $(USER_REPOSITORY) ./services/microservice-sample-user git clone $(TWEET_RESPOSITORY) ./services/microservice-sample-tweet pull: cd ./services/microservice-sample-web && git pull cd ./services/microservice-sample-user && git pull cd ./services/microservice-sample-tweet && git pull build: docker-compose build up: docker-compose up -d down: docker-compose down seed: docker-compose exec user node /app/scripts/initialize.js docker-compose exec tweet node /app/scripts/initialize.js
Makefileが作成できたら、make pullを実行し、各サービスをservicesディレクトリ配下へcloneします。make cloneDockerイメージの作成
つづいて、各サービスのDockerイメージを作成するための、Dockerファイルを実装していきます。
このファイルから生成されるDockerイメージは本番環境でも使用されます。
実際の開発現場では各サービスが責任を持って作成する場合もありますし、SREチームなど、Dockerのノウハウに長けたチームがサービス横断で管理するケースもあるでしょう。services/microservice-sample-tweet/DockerfileFROM node:11.10-alpine ENV NODE_ENV=production WORKDIR /app RUN apk add --no-cache curl && \ curl -sfL https://install.goreleaser.com/github.com/tj/node-prune.sh | sh ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait RUN chmod +x /wait COPY package.json . RUN yarn install && ./bin/node-prune COPY . . EXPOSE 3000 CMD /wait && yarn startservices/microservice-sample-user/DockerfileFROM node:11.10-alpine ENV NODE_ENV=production WORKDIR /app RUN apk add --no-cache curl && \ curl -sfL https://install.goreleaser.com/github.com/tj/node-prune.sh | sh ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.5.0/wait /wait RUN chmod +x /wait COPY package.json . RUN yarn install && ./bin/node-prune COPY . . EXPOSE 3000 CMD /wait && yarn startservices/microservice-sample-web/DockerfileFROM node:11.10-alpine as builder ENV NODE_ENV=production ARG GITHUB_CLIENT_ID ARG GITHUB_CLIENT_SECRET WORKDIR /app RUN apk add --no-cache curl && \ curl -sfL https://install.goreleaser.com/github.com/tj/node-prune.sh | sh COPY package.json . COPY yarn.lock . RUN yarn install && ./bin/node-prune COPY . . RUN yarn build FROM node:11.10-alpine WORKDIR /app ADD package.json ./ ADD nuxt.config.js ./ COPY --from=builder ./app/server ./server COPY --from=builder ./app/node_modules ./node_modules COPY --from=builder ./app/.nuxt ./.nuxt EXPOSE 3000 CMD yarn startWebサービスに関してはマルチステージビルドを利用して最終的なイメージのサイズを軽くするように工夫しています。
実装後、各
Dockerfileはcommitしておきましょう。docker-compose.ymlの作成
上記で用意した
Dockerfileを、dockerコマンドを利用してビルド、コンテナの起動等やってもよいのですが、環境変数等、引数が多くなってしまうため、今回はdocker-composeを利用して一元管理します。
docker-compose.ymlに起動したいコンテナの設定を書いていくことで、一括で立ち上げたり、削除することが可能です。今回は、Webサービス、Userサービス、Tweetサービスと、Userサービス用DB、Tweetサービス用DBの合計5つのコンテナを定義します。
docker-compose.yml--- version: '3' services: web: build: context: ./services/microservice-sample-web dockerfile: Dockerfile image: microservice_web:1.0 ports: - 3000:3000 environment: NUXT_HOST: 0.0.0.0 USER_SERVICE: http://user:3000 TWEET_SERVICE: http://tweet:3000 GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID} GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET} user: build: context: ./services/microservice-sample-user dockerfile: Dockerfile image: microservice_user:1.0 environment: MONGODB_URL: mongodb://user-db:27017/user MONGODB_ADMIN_NAME: root MONGODB_ADMIN_PASS: example WAIT_HOSTS: user-db:27017 depends_on: - user-db user-db: image: mongo volumes: - user-db:/data/db environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example tweet: build: context: ./services/microservice-sample-tweet dockerfile: Dockerfile image: microservice_tweet:1.0 environment: MONGODB_URL: mongodb://tweet-db:27017/user MONGODB_ADMIN_NAME: root MONGODB_ADMIN_PASS: example WAIT_HOSTS: tweet-db:27017 USER_SERVICE: http://user:3000 depends_on: - tweet-db tweet-db: image: mongo volumes: - tweet-db:/data/db environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example volumes: user-db: tweet-db:GitHubのOAuthのキー等はGit管理する対象ではないので、
.envファイルに記述します。
docker-composeの機能により、カレントディレクトリの.envファイルが読み込まれ、docker-compose.yml中で利用することができるようになります。
値はDocker環境の場合エンドポイントがlocalhost:3000と、前章までと同じなため、前章で使用していたのと同じGitHubのOAuth設定が利用可能です。.envGITHUB_CLIENT_ID=xxxxxxxxxxxxxxxxxxx GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
services/.gitkeepファイルを作成しておきます。touch services/.gitkeep
.gitignoreファイルを以下のように設定します。.gitignoreservices/* !services/.gitkeep .envサービスを起動してみる
それでは、サービスを起動してみます。
# Dockerイメージをビルド make build # サービスの立ち上げ make up # ダミーデータの投入 make seed
http://localhost:3000へアクセスしてみましょう。
問題なく動作していれば本章の実装は完了になります。第5章まとめ
本章では、各サービスの
Dockerfileを作成し、docker-composeを利用してマイクロサービスをローカルのDocker環境上に構築しました。次の章ではいよいよKubernetes上でマイクロサービスを動作させてみます。
- 投稿日:2019-03-30T00:57:24+09:00
metabaseを別サーバーに移行する
はじめに
先日、metabase(構築したのは自分ではない)を別サーバーに移行することがありました。
既存環境にて登録済みのユーザーやクエリを別サーバーに移行する点で、
いまいちそれっぽい情報が見つからず、手間取ったので手順を書いておきます。やりたいこと
- metabaseを別サーバーに移行する
- 移行対象はmetabaseに登録してあるユーザー情報とクエリなど諸々の設定
前提など
公式のdocker imageを使用して、既存環境が構築されている
(それ以外の環境の場合は、やることとしては大体一緒かもしれませんが調べてないので不明です)公式が書いた下記の記事を参考にして進めています。
metabase: "Running Metabase on Docker" > Mounting a mapped file storage volumeの箇所ざっくり手順
- 設定ファイルが格納されているディレクトリをコンテナから引っこ抜く(デフォルトは
/metabase.db)- 移行先のサーバーに1.で抜いた設定ファイルが格納されているディレクトリを置き、
docker run -vなどでマウントしてmetabaseを起動する- 起動後は必要に応じて、参照するDBの向き先を変更する
手順
1. 設定ファイルが格納されているディレクトリを引っこ抜く
まずマウントされているか確認
// マウントされていたらホスト側に設定ファイルが入ったディレクトリがあるはずなので、そのディレクトリを移行先に持っていく。 // 仮に、記事通りのコマンドで、マウントして起動されていた場合、`docker inspect ~~~` を叩くと下記の通りになる $ docker run -d -p 3000:3000 -v ~/metabase-data:/metabase-data -e "MB_DB_FILE=/metabase-data/metabase.db" --name metabase metabase/metabase $ docker inspect metabaseのコンテナID |grep -E "Source|Destination" "Source": "/metabase-data", // ホスト側 "Destination": "/metabase-data", // コンテナ側マウントしていない場合、デフォルトではルート直下にmetabase.dbというディレクトリがあるので、このディレクトリをホスト側にコピーする
マウントせずにコンテナを立ち上げてみた場合こうなります$ docker run -d -p 3000:3000 --name metabase metabase/metabase // ルートにmetabase.dbというディレクトリが確認できる $ docker container exec -ti metabase ls /metabase.db metabase.db.mv.db metabase.db.trace.dbホスト側にコピーするコマンドはこれ(一応)$ docker cp metabase:/metabase.db . $ tree . └── metabase.db ├── metabase.db.mv.db └── metabase.db.trace.db2. 移行先でmetabaseを起動する
あとは移行先の任意のディレクトリにmetabase.dbを配置して、下記のコマンドが動くようマウントしてコンテナを立ち上げる
$ docker run -d -p 3000:3000 -v ~/metabase-data:/metabase-data -e "MB_DB_FILE=/metabase-data/metabase.db" --name metabase metabase/metabase記事のコマンド通りにするなら、
あらかじめ下記のように、~/metabase-dataの下にmetabase.dbを置くディレクトリ構成にし、metabase-detaをマウントする$ tree -a ~/metabase-data metabase-data └── metabase.db ├── metabase.db.mv.db └── metabase.db.trace.db3. 起動後
- 移行前のmetabaseから参照先のDBが変わっていないのであれば、動作確認して終わり
- ステージングから本番へ、ユーザーやクエリだけ移動するようなケースであれば向き先のDBを変更して終わり

