- 投稿日:2019-05-23T23:17:43+09:00
Let's Encrypt のワイルドカード証明書を取得して、rancherに設定する
最初に
この記事は、備忘録です。
Let’s Encryptがワルドカード証明に対応するのを待ちわびていたことをふと思い出したので、開発環境のRancher環境ように取得して、設定してみたというものです。
環境
サクッと試したかったので、Ubuntu16.04コンテナで取得しました。
- DNS:AuzreのDNS
- コンテナ:手元のMacの上
手順
参考にした記事によると、公式では「dns-plugin」を使うと書いてありますが、
面倒なので元記事と同じく手動で取得しました。証明書の取得
CertBot環境を作る。と言っても、使い捨てのコンテナだけど。
❯ docker run -it --rm ubuntu:16.04 bash root@ad7f41c5773c:/# apt update ・・・ Building dependency tree Reading state information... Done 2 packages can be upgraded. Run 'apt list --upgradable' to see them. root@ad7f41c5773c:/# apt upgrade < 念のため。。。 Reading package lists... Done ・・・ root@ad7f41c5773c:/# apt install certbot <ここからが本番 ・・・ Get:49 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 certbot all 0.23.0-1~ubuntu16.04.1 [17.4 kB] Fetched 16.0 MB in 17s (932 kB/s) E: Failed to fetch http://61.26.74.210:80/pdata/07e41ece3becb885/archive.ubuntu.com/ubuntu/pool/main/p/python-pbr/python-pbr_1.8.0-4ubuntu1_all.deb Writing more data than expected (15617 > 12552) E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing? root@ad7f41c5773c:/# apt install --fix-missing certbot <再度 ・・・ 148 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. root@ad7f41c5773c:/# certbot --version certbot 0.23.0 < 0.22.0以上なので大丈夫証明書の取得
root@ad7f41c5773c:/# certbot certonly --manual --preferred-challenges dns -d *.[自分のドメイン] --server https://acme-v02.api.letsencrypt.org/directory Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator manual, Installer None Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): [自分のメールアドレス。期限切れ通知が届くので良く見るやつにしないと痛い目見ます] Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org ------------------------------------------------------------------------------- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory ------------------------------------------------------------------------------- (A)gree/(C)ancel: A ------------------------------------------------------------------------------- Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights. ------------------------------------------------------------------------------- (Y)es/(N)o: Y Starting new HTTPS connection (1): supporters.eff.org Obtaining a new certificate Performing the following challenges: dns-01 challenge for [自分のドメインが表示される] ------------------------------------------------------------------------------- NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that. Are you OK with your IP being logged? ------------------------------------------------------------------------------- (Y)es/(N)o: (Y)es/(N)o: Y ------------------------------------------------------------------------------- Please deploy a DNS TXT record under the name _acme-challenge.[自分のドメインが表示される] with the following value: xxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx-x Before continuing, verify the record is deployed. ------------------------------------------------------------------------------- Press Enter to Continue < 自分のDNSに上記のテキストレコード追加するまでEnterは触らない。 Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/[自分のドメイン]/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/[自分のドメイン]/privkey.pem Your cert will expire on 2019-08-21. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le root@ad7f41c5773c:/# cd /etc/letsencrypt/live/ root@ad7f41c5773c:/etc/letsencrypt/live# ll total 12 drwx------ 3 root root 4096 May 23 13:14 ./ drwxr-xr-x 9 root root 4096 May 23 13:14 ../ drwxr-xr-x 2 root root 4096 May 23 13:14 [自分のドメイン]/ root@ad7f41c5773c:/etc/letsencrypt/live# cd [自分のドメイン]/ root@ad7f41c5773c:/etc/letsencrypt/live/[自分のドメイン]# ll total 12 drwxr-xr-x 2 root root 4096 May 23 13:14 ./ drwx------ 3 root root 4096 May 23 13:14 ../ -rw-r--r-- 1 root root 543 May 23 13:14 README lrwxrwxrwx 1 root root 39 May 23 13:14 cert.pem -> ../../archive/[自分のドメイン]/cert1.pem lrwxrwxrwx 1 root root 40 May 23 13:14 chain.pem -> ../../archive/[自分のドメイン]/chain1.pem lrwxrwxrwx 1 root root 44 May 23 13:14 fullchain.pem -> ../../archive/[自分のドメイン]/fullchain1.pem lrwxrwxrwx 1 root root 42 May 23 13:14 privkey.pem -> ../../archive/[自分のドメイン]/privkey1.pemいつもの通り証明書が取得できている。
Azure DNSへのテキストレコード登録
・・・特に書くこともないです・・・登録後に「Press Enter to Continue」を。
Rancherへの登録
インフラ->証明書から、証明書追加を選択。
ロードバランサーへの登録
ロードバランサーの編集画面の一番下のプルダウンに、登録した証明書が表示されているはず。この時、個別に取得してた証明書の設定を外しました。
確認
素晴らしい。。
雑感
今まではNginx経由で取得していたが、DNS操作でサクッと作れるのはとても助かります。今回設定したrancherは開発環境のため、サブドメインがたくさんありSSL証明書の設定が面倒でしたが、ワイルドカード証明書は素敵です。
これから
- 自動取得(現rancher環境)
- Kube環境への適用
- 投稿日:2019-05-23T22:21:36+09:00
一足遅れて Kubernetes を学び始める - 10. config&storage その1 -
ストーリー
- 一足遅れて Kubernetes を学び始める - 01. 環境選択編 -
- 一足遅れて Kubernetes を学び始める - 02. Docker For Mac -
- 一足遅れて Kubernetes を学び始める - 03. Raspberry Pi -
- 一足遅れて Kubernetes を学び始める - 04. kubectl -
- 一足遅れて Kubernetes を学び始める - 05. workloads その1 -
- 一足遅れて Kubernetes を学び始める - 06. workloads その2 -
- 一足遅れて Kubernetes を学び始める - 07. workloads その3 -
- 一足遅れて Kubernetes を学び始める - 08. discovery&LB その1 -
- 一足遅れて Kubernetes を学び始める - 09. discovery&LB その2 -
- 一足遅れて Kubernetes を学び始める - 10. config&storage その1 -
前回
一足遅れて Kubernetes を学び始める - 08. discovery&LB その2 -では、様々なserviceを学習しました。
今回は、config&storageのconfigを学びます。config&storage
Kubernetesには、下記のようにリソースの種類が存在します。
リソースの分類 内容 Workloadsリソース コンテナの実行に関するリソース Discovery&LBリソース コンテナを外部公開するようなエンドポイントを提供するリソース Config&Storageリソース 設定・機密情報・永続化ボリュームなどに関するリソース Clusterリソース セキュリティやクォータなどに関するリソース Metadataリソース リソースを操作する系統のリソース ※ KubernetesのWorkloadsリソース(その1)
環境変数
静的設定や、Podやコンテナの情報を設定、シークレットでの設定があるみたいです。
sample-env.yamlapiVersion: v1 kind: Pod metadata: name: sample-env labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 env: - name: MAX_CONNECTION value: "100" - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: LIMITS_CPU valueFrom: resourceFieldRef: containerName: nginx-container resource: limits.cpupi@raspi001:~/tmp $ k apply -f sample-env.yaml pi@raspi001:~/tmp $ k exec -it sample-env env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ... MAX_CONNECTION=100 POD_IP=10.244.1.97 LIMITS_CPU=4 ...MAX_CONNECTIONは、静的に設定できています。
Podやコンテナの設定は、POD_IP,KIMITS_CPUで設定できています。
Podやコンテナの情報は、k get pods sample-env -o yaml
で得ることができます。ふむふむ。Secret
パスワードなどの機密情報をSecretで暗号化してくれます。
手段の種類が下記のようにいくつかあります。
- Generic
- TLS
- Docker Repository
- Service Account
Genericの場合は、スキーマレスなため、汎用性の高い指定が可能になります。それを使ってみようと思います。(TLSの場合は、tls.crt,tls.keyが必要)
使い方して、ファイル参照、envfile参照、直接指定、マニュフェスト指定の4パターンです。それぞれ試してみます。
ファイル参照
pi@raspi001:~/tmp $ echo -n "root" > ./username pi@raspi001:~/tmp $ echo -n "rootpassword" > ./password pi@raspi001:~/tmp $ k create secret generic --save-config sample-db-auth --from-file=./username --from-file=./password pi@raspi001:~/tmp $ sudo apt-get install jq pi@raspi001:~/tmp $ k get secrets sample-db-auth -o json | jq .data { "password": "cm9vdHBhc3N3b3Jk", "username": "cm9vdA==" }envfile参照
env-secret.txtusername=root password=rootpasswordpi@raspi001:~/tmp $ k create secret generic --save-config sample-db-auth2 --from-env-file ./env-secret.txt pi@raspi001:~/tmp $ k get secrets sample-db-auth2 -o json | jq .data { "password": "cm9vdHBhc3N3b3Jk", "username": "cm9vdA==" }直接指定
pi@raspi001:~/tmp $ k create secret generic --save-config sample-db-auth3 --from-literal=username=root --from-literal=password=rootpassword pi@raspi001:~/tmp $ k get secrets sample-db-auth3 -o json | jq .data { "password": "cm9vdHBhc3N3b3Jk", "username": "cm9vdA==" }マニュフェスト指定
sample-db-auth.yamlapiVersion: v1 kind: Secret metadata: name: sample-db-auth4 type: Opaque data: username: cm9vdA== # root password: cm9vdHBhc3N3b3Jk # rootpasswordpi@raspi001:~/tmp $ k apply -f sample-db-auth.yaml pi@raspi001:~/tmp $ k get secrets sample-db-auth4 -o json | jq .data { "password": "cm9vdHBhc3N3b3Jk", "username": "cm9vdA==" }どれも、正しく動きましたね。プロダクトとしては使わないと思いますが、お試しで確認するには
Genericは扱いやすくて良いですね。では、設定した値を使ってみましょう。
Secretの利用
手段として、環境変数かVolumeかの2つです。
環境変数からSecretを使う
sample-secret-single-env.yamlapiVersion: v1 kind: Pod metadata: name: sample-secret-single-env spec: containers: - name: secret-container image: nginx:1.12 env: - name: DB_USERNAME valueFrom: secretKeyRef: name: sample-db-auth key: usernamepi@raspi001:~/tmp $ k apply -f sample-secret-single-env.yaml pi@raspi001:~/tmp $ k exec -it sample-secret-single-env env | grep DB_USERNAME DB_USERNAME=root環境変数から使う場合、値が固定されてしまいます。(静的)
VolumeからSecretを使う
sample-secret-single-volume.yamlapiVersion: v1 kind: Pod metadata: name: sample-secret-single-volume spec: containers: - name: secret-container image: nginx:1.12 volumeMounts: - name: config-volume mountPath: /config volumes: - name: config-volume secret: secretName: sample-db-auth items: - key: username path: username.txtpi@raspi001:~/tmp $ k apply -f sample-secret-single-volume.yaml pi@raspi001:~/tmp $ k exec -it sample-secret-single-volume cat /config/username.txt rootこちらは、動的に書き換えることができるそうです。逐次Volumeを見ているんでしょうね。(環境変数の場合、コンテン起動した時点で固定される)
pi@raspi001:~/tmp $ cat << EOF | k apply -f - > apiVersion: v1 > kind: Secret > metadata: > name: sample-db-auth > type: Opaque > data: > username: YMRtaW4= > # root > admin > EOF pi@raspi001:~/tmp $ k exec -it sample-secret-single-volume cat /config/username.txt amin動的に書き換わっていますね。OK!
※ adminのaが文字化けしていた...ConfigMap
設定情報をKey-Value形式で登録することができます。
こちらも手段としては、ファイル参照、直接参照、マニフェスト参照があります。
さっきと同じなので、ファイル参照のみ試してみます。sample.txthogehoge fugafugapi@raspi001:~/tmp $ k create configmap --save-config sample-configmap --from-file=./sample.txt pi@raspi001:~/tmp $ k get configmaps sample-configmap -o json | jq .data { "sample.txt": "hogehoge\nfugafuga\n" }secretと同じ感じですね。これって、どんなファイルでも(1MBまで)保存できちゃうそうです。
secretと同様で、設定したデータは環境変数、Volumeの2つから参照可能です。お片付け
pi@raspi001:~/tmp $ k delete -f sample-env.yaml -f sample-db-auth.yaml -f sample-secret-single-env.yaml -f sample-secret-single-volume.yaml pi@raspi001:~/tmp $ k delete secret sample-db-auth sample-db-auth2 sample-db-auth3 pi@raspi001:~/tmp $ k delete configmap sample-configmap最後に
環境変数の設定方法について、学びました。
個人開発で、外部サービスをアプリケーションに組み込む際、
API_KEYを環境変数として登録して開発しています。
今回は、GenericでSecretを保存しましたが、プロダクトでは、
service_accountを使うのが一般的なのでしょうか?次回は、Storageについて学習します。
- 投稿日:2019-05-23T21:35:24+09:00
docker redmineへpluginをインストール 備忘録
docker redmineへPlug-inをインストールする
Redmineのメニューなどの文字を置き換えるプラグイン。
Redmine.tokyoで紹介された
redmine_message_customize
https://github.com/ishikawa999/redmine_message_customize前回、dockerでredmineをデプロイした環境の続きから
作業してます。Gitからインストールします。
dockerの状態確認をする。
ps -a この状態から開始します。$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 517586f4b9b5 redmine "/docker-entrypoint.…" 2 days ago Exited (255) About a minute ago 0.0.0.0:3000->3000/tcp some-redmine 8695e2683fc5 postgres "docker-entrypoint.s…" 2 days ago Exited (255) About a minute ago 5432/tcp some-postgres$docker exec -it some-redmine bashroot@517586f4b9b5:/usr/src/redmine#bundle install --without development test cd plugins git clone https://github.com/ishikawa999/redmine_message_customizeCloningされます。
再起動する。
docker stop redmine docker start redmineRunTestする
$ docker exec -it some-redmine bash # bundle exec rake test TEST=plugins/redmine_message_customize/test RAILS_ENV=tes
- 投稿日:2019-05-23T21:31:05+09:00
Dockerのコンテナのロケール設定(ubuntu16.4ではうまくいかないという話)
はじめに
Dockerのコンテナのローケール設定がUTCから変更できない。
解決先は試していないが、状況を記載する。状況
事実
RUN ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
をしたが、起動したコンテナはUTCのまま。- 起動したコンテナ上で
ls -l /etc/localtime
とすると、リンクは貼られている- そもそもzoneinfo配下がなかった
- ubuntu14.4では
RUN ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
でJSTになる未確認情報
- ubuntu16.4ではzoneinfoが省かれているので追加パッケージが必要
- apt-getで入れる方法があるらしい
- 投稿日:2019-05-23T19:41:12+09:00
rails hands on
rails で Web アプリを作ってみよう!
Web アプリを作って、動かして、触って、デプロイしてみよう!
事前準備
docker
,bundler
はインストールしておいてねdocker
- 公式
- Mac の人は
bundler
- 公式
- Mac の人は
他
docker-compose.yml
Dockerfile
dockerをローカルにコピー
TODO: curl でダウンロードできるようにするやってみよう!
$ mkdir rails_sample && cd rails_sample $ cp -a ~/Download/Dockerfile ~/Download/docker-compose.yml ~/Download/docker . remove `Gemfile.lock` in Dockerfile $ bundle init $ docker-compose run --rm web bundle exec rails new . -d mysql --skip-testここで今日のゴールを
https://rails-sample-fot-lt.herokuapp.com/users/sign_in
(今日はログインやらんけど)ログインあり&デプロイありの、ハンズオンやりたいと思う人!
希望あれば日程調整しましょう
3時間ぐらい
うまくいけば30分edit database.yml
pool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %> username: <%= ENV.fetch('MYSQL_USERNAME') { 'root' } %> password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %> host: <%= ENV.fetch('MYSQL_HOST') { '127.0.0.1' } %> port: <%= ENV.fetch('MYSQL_PORT') { 3306 } %>add
Gemfile.lock
in Dockerfile$ docker-compose up $ docker-compose exec web bin/rails g scaffold post content $ docker-compose exec web bin/rails db:migratehands on メモ
$ mkcd rails_sample $ cp -a ~/Download/Dockerfile ~/Download/docker-compose.yml ~/Download/docker .remove
Gemfile.lock
in Dockerfile$ bundle init $ docker-compose run --rm web bundle exec rails new . -d mysql --skip-test create remote repository $ cp -a ~/Download/Gemfile .edit database.yml
database.ymlpool: <%= ENV.fetch('RAILS_MAX_THREADS') { 5 } %> username: <%= ENV.fetch('MYSQL_USERNAME') { 'root' } %> password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %> host: <%= ENV.fetch('MYSQL_HOST') { '127.0.0.1' } %> port: <%= ENV.fetch('MYSQL_PORT') { 3306 } %>add
Gemfile.lock
in Dockerfile$ docker-compose up $ docker-compose exec web bundle install $ docker-compose exec web rails generate simple_form:install $ docker-compose exec web rails haml:erb2haml $ docker-compose exec web rails g annotate:install $ docker-compose exec web bin/rails g scaffold post content $ docker-compose exec web bin/rails g scaffold user name $ docker-compose exec web bin/rails db:migrate $ docker-compose exec web bundle exec rails generate devise:installadd
%p.notice= notice %p.alert= alertin app/views/layouts/application.html.haml
$ docker-compose exec web bundle exec rails g devise:views $ docker-compose exec web rails generate devise user $ docker-compose exec web bin/rails db:migrateadd
before_action :authenticate_user!
in app/controllers/posts_controller.rb and app/controllers/users_controller.rbadd
root to: 'post#show'
route.rbaccess http://localhost:3000/users
heroku deploy
create app in gui
$ heroku login $ heroku git:remote -a rails-sample-fot-lt $ git push heroku master $ heroku addons:create cleardb:ignite $ heroku config | grep CLEARDB_DATABASE_URL mysql://[username]:[password]@[hostname]/[db_name]?reconnect=true $ heroku config:add DB_NAME="[db_name]" $ heroku config:add DB_USERNAME="[username]" $ heroku config:add DB_PASSWORD="[password]" $ heroku config:add DB_HOSTNAME="[hostname]" $ heroku config:add DB_PORT="3306" $ heroku run rake db:migrate
コピー用
DockerfileFROM ruby:2.6.2 RUN apt-get update --fix-missing \ && apt-get -y upgrade \ && apt-get install -qq -y \ nodejs \ mysql-client \ && apt-get autoremove -y \ && apt-get clean all \ && fc-cache -f -v # Add dumb init to process system events RUN wget https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 -O /usr/local/bin/dumb-init RUN chmod +x /usr/local/bin/dumb-init RUN gem update --system RUN gem install bundler WORKDIR /rails_sample COPY Gemfile Gemfile.lock ./ RUN bundle install --jobs=4 --retry=3 COPY . . EXPOSE 3000 # Start the main process. CMD bin/rails server -b 0.0.0.0docker-compose.ymlversion: '3.7' services: db: restart: always image: mysql:latest environment: MYSQL_ROOT_PASSWORD: password ports: - 3306:3306 volumes: - ./docker/mysql/conf:/etc/mysql/conf.d:rw - dbdata:/var/lib/mysql web: build: . depends_on: - db volumes: - .:/rails_sample - "bundle:/usr/local/bundle" environment: - MYSQL_HOST=db command: > bash -c " bundle install --quiet && docker/bin/start rails" ports: - 3000:3000 volumes: bundle: dbdata:docker/mysql/conf/default_authentication.cnf[mysqld] default_authentication_plugin=mysql_native_passworddocker/bin/rails#!/bin/sh docker-compose run --rm backend bin/rails "$@"docker/bin/start#!/bin/sh if [ $# = 0 ]; then echo "usage:" echo " start rails: Start rails server" echo " start rails recreate db: Start rails server recreate db" echo " start sidekiq: Start sidekiq process" echo " start sidekiq-web: Start sidekiq web server" exit 1 fi case "$1" in "rails") bundle exec rails tmp:pids:clear bundle exec rails log:clear tmp:clear bundle exec rails server --port 3000 --binding "0.0.0.0" ;; "rails recreate db") bundle exec rails tmp:pids:clear bundle exec rails db:reset bundle exec rails db:migrate bundle exec rails log:clear tmp:clear bundle exec rails server --port 3000 --binding "0.0.0.0" ;; "rails migrate db") bundle exec rails db:migrate ;; "sidekiq") bundle exec sidekiq ;; "sidekiq-web") bundle exec rackup --host "0.0.0.0" --port 9292 lib/sidekiq_web/config.ru ;; esac
- 投稿日:2019-05-23T18:42:33+09:00
Raspberry Piで学ぶdocker入門
はじめに
本文書を参照頂きありがとうございます。
この文書は社内勉強会に向けた文書である為、一部期待値と異なる表現、記載がある場合がありますので、ご利用になられる際はその辺りも加味して頂いてご利用下さい。勉強会お題
- 第01回(2019.05.22):Raspberry Piのセットアップ、Docker環境のセットアップ
- 第02回
- 第03回
- 第04回
- 第05回
- 第06回
- 第07回
- 第08回
- 第09回
- 第10回
- 第11回
Special Thanks
※貴重な技術文書の参照先の皆様、リンク先等のご紹介
<@kotaro-drさん>
・【図解】Dockerの全体像を理解する -前編-
・【図解】Dockerの全体像を理解する -中編-
・【図解】Dockerの全体像を理解する -後編-
- 投稿日:2019-05-23T18:11:19+09:00
Serverless Framework を Docker で動かす Dockerfile テンプレート
概要
Serverless Framework のコマンドを Mac で叩きたかったがローカル環境を汚したくなかったので
Docker コンテナ上で叩けるような Dockerfile を作成しました。環境
Mac
Docker version 18.09.2, build 6247962
docker-compose version 1.23.2, build 1110ad01作成した Dockerfile
FROM python:3.7-alpine ARG AWS_ACCESS_KEY_ID ARG AWS_SECRET_ACCESS_KEY ENV NODE_PATH /usr/lib/node_modules/ # install nodejs RUN apk update \ && apk add --no-cache nodejs npm # install aws-cli RUN pip install awscli # install serverless framework RUN npm install -g serverless serverless-plugin-existing-s3 # set aws key RUN sls config credentials --provider aws --key $AWS_ACCESS_KEY_ID --secret $AWS_SECRET_ACCESS_KEY # change work directory RUN mkdir -p /app WORKDIR /app作成した docker-compose ファイル
version: '3.5' services: serverless: build: context: . dockerfile: ./dockerfiles/serverless/Dockerfile args: - AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY tty: true stdin_open: true image: serverless working_dir: /app volumes: - .:/app container_name: serverless解説
Docerfile の設定
まず Dockerfile について解説します
コンテナの設定
FROM python:3.7-alpine ARG AWS_ACCESS_KEY_ID ARG AWS_SECRET_ACCESS_KEY ENV NODE_PATH /usr/lib/node_modules/aws cli をインストールするために alpine linux の python をインストールします。
OS は何でもいいのですが alpine linux は容量が少ないのでよく採用させてもらってます。
ちなみに python:3.7-alpine は 87MB でした。次に docker-compose から渡された AWS のアクセスキーとシークレットキーを読み込ませます。
こちらはサーバレスフレームワークを利用する上で必要になります。
最後にNODE_PATH
の環境変数を設定します。NODE_PATH
は npm のグローバルインストールを行うための
node_module
フォルダパスを指定します。パッケージのインストール
# install nodejs RUN apk update \ && apk add --no-cache nodejs npm # install aws-cli RUN pip install awscli # install serverless framework RUN npm install -g serverless serverless-plugin-existing-s3次にパッケージのインストールです。
RUN
コマンドを利用して alpine-linux のapk
コマンドを叩きます。
サーバレスフレームワークは npm で管理されているのでnpm
とnodejs
をインストールします。
また、裏で AWS CLI コマンドが動くので awscli をpip
コマンドでインストールしています。
npm install
コマンドでグローバルに serverless フレームワークと関連するプラグインをインストールしています。
作成済みの S3 バケットに対して後から lambda イベントを付与したかったのでserveless-plugin-existing-s3
プラグインも入れてます。https://github.com/matt-filion/serverless-external-s3-event
sls コマンドの実行
# set aws key RUN sls config credentials --provider aws --key $AWS_ACCESS_KEY_ID --secret $AWS_SECRET_ACCESS_KEY # change work directory RUN mkdir -p /app WORKDIR /app最後に sls コマンドを実行して アクセスキーとシークレットキーの設定を実行しています。
docker-compose の設定
version: '3.5' services: serverless: build: context: . dockerfile: ./dockerfiles/serverless/Dockerfile args: - AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY tty: true stdin_open: true image: serverless working_dir: /app volumes: - .:/app container_name: serverlessdocker-compose は特に複雑なことはせず Mac のローカルに設定されている環境変数を
args
で Dockerfile に渡してあげています。
dockerfile は先程作成した dockerfile のパスを指定します。
作成した serverless.yml ファイルをコンテナ側でも参照できないと行けないので volume をマウントしてあげましょう。解説した dockerfile と docker-compose のファイルは github においています。
ご自由にお使いください。
- 投稿日:2019-05-23T16:40:36+09:00
Dockerでlaravelの環境構築
Dockerを使用したlaravel環境構築
laradock
を使用することで簡単にlaravelの環境構築をすることができるので、以下に手順をまとめる。開発環境
MacOS Mojave
既にDocker
Git
はMacに導入済として下記記述します。laradockのダウンロード
Gitを使用して、任意のフォルダにlaradockをダウンロードします。
git clone https://github.com/Laradock/laradock.git // laradockへ移動 cd laradock // 公式ページの記載通り、下記コマンドを入力 cp env-example .envMysqlのバージョンを指定(現行最新版の8だと、通常とは違う認証になり、詰まる可能性大。指定がなければ、5.7を使用したほうが無難)
// .envを開き、"MYSQL_VERSION=latest" を以下のように変更 MYSQL_VERSION=5.7コンテナの作成
開発に必要なプログラムを指定し、コンテナを作成。なお、プログラムを指定しないとすべてのコンテナを作成しようとするため、時間がかかります。
通常のlaravel開発であれば、下記コマンドの指定で問題ないかと思います。docker-compose up -d nginx mysql workspace phpmyadmin終了後、
http://localhost
にアクセスすると、404 Not Found
が表示されます。
これにより、Nginxに無事アクセスできたことが確認できます。laravelアプリの作成
コンテナの
workspace
内にて、laravelアプリを作成します。// docker ps にて、workspaceのコンテナID確認後、下記コマンドでコンテナ内に入る docker-compose exec -it workspaceのコンテナID bash // コンテナに入り、"/var/www$"にて、下記コマンドを実行。バージョンは5.5以外でも変更できます。 composer create-project laravel/laravel sample --prefer-dist "5.5.*"これによって、
sample
というアプリファイルが作成されます。
次に、laradockディレクトリの.env
に、このアプリを作成したことを伝えるため、下記のように記述します。### Paths ################################################# # Point to the path of your applications code on your host APP_CODE_PATH_HOST=../sample設定を反映させるため、dockerを再起動させます。
// 停止 docker-compose stop // 再起動。以後は、nginxとmysqlのみを指定すればよい docker-compose up -d nginx mysql再度ブラウザで
http://localhost
にアクセスするとlaravelの画面が表示されます。MySQLとの接続
MySQLコンテナと、laravelのDB設定を合わせます。
sample
フォルダ内の.env
ファイルを開き、下記のように記述。
この内容はlaradockフォルダの.env
内のMySQLの記述と合わせたものになります。// laravelアプリ内の.envファイル DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=default DB_USERNAME=default DB_PASSWORD=secret参考:laradockフォルダ
.env
のMySQL記述内容### MYSQL ################################################# MYSQL_VERSION=5.7 MYSQL_DATABASE=default MYSQL_USER=default MYSQL_PASSWORD=secret MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=root MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d再度、
workspace
コンテナに入り、migrateを実行php artisan migrateMySQLコンテナに入り、テーブルが確認できれば完了です。
mysql -u default -p -h 127.0.0.1 show tables from default参照
Laravel & Docker 環境構築 with Laradock
Laradockを使ったLaravel開発環境構築のやさしい解説
Laradock公式サイト
- 投稿日:2019-05-23T14:33:25+09:00
【Docker超入門】DockerでつくるLaTex環境
本稿に関してツッコミなどがあれば適宜コメントいただけるとありがたいです.
はじめに
大学の研究会で講義を1コマ持つことになったため,弊研究会では必須なLaTeX環境をDockerで作る方法を解説することにしました.
読者としてはDockerの知識が一切ない人を想定しています.
なお,本稿ではLaTex自体の使い方に関してはあまり触れません.
LaTexとは?
Latexとは,Donald E. Knuth氏が開発したレイアウトシステムのTexをLeslie Lamport氏が文書作成のために改良したものだそうです.主に学術論文を書く際に使用されており,数式を綺麗にレイアウトしてくれます.
例えば,世界一美しいとされるオイラーの等式でさえ,テキストで表現すると美しくないですが,
e^{iπ} + 1 = 0
TeXを用いてコンパイルすれば,以下のように美しくレイアウトされます.
$e^{iπ} + 1 = 0$
Dockerとは?
Dockerとはコンテナ仮想化技術のプラットフォームです.
従来の仮想化技術では,ホストOS上の仮想ハードウェアや,Hypervisorを利用してゲストOSを動かしていたのに対し,DockerではDocker EngineがホストOSのカーネルの利用を上手く管理することでプロセスとユーザを隔離しているため,VMに比べて軽量な仮想化環境を実現しています.
事前準備
本稿では,このDockerを用いてLatexのディストリビューションであるTexLiveの環境を行うため,まずはDockerと生成されたPDFの閲覧用にSkimをインストールします,
Dockerのインストール
下記ページからDockerHubのアカウントを作成しdmgをダウンロードしてインストールします.
MAC=> https://docs.docker.com/docker-for-mac/install/
Windows=> https://docs.docker.com/docker-for-mac/install/Mac用Skim(軽量PDFビューワー)のインストール
下記ページよりダウンロードしてインストール
https://skim-app.sourceforge.io/全体像を把握する
今回は下記のような構成でDockerを用いてLaTeX環境を構築します.
とりあえずDockerでLaTex環境を建ててみる
DockerとSkimのインストールが完了したら,筆者が事前に用意したLatexLiveのDockerイメージ(nontan18/latexmk)を用いて以下のコマンドでLaTex環境を実際に構築してみましょう.
// 作業用のworkディレクトリを作成し移動 $ mkdir work && cd work
work
ディレクトリに入ったら下記の内容のファイルを作成します.sample.tex\documentclass[twocolumn, a4j]{article} \usepackage{multirow} \usepackage{amsmath,amssymb} \usepackage[T1]{fontenc} % \usepackage[dvipdfmx]{graphicx} \title{サンプル用のTexファイル} \renewcommand{\thefootnote}{\fnsymbol{footnote}} \author{YOUR NAME\footnotemark[2] hoge@sfc.wide.ad.jp} \renewcommand{\thefootnote}{\arabic{footnote}} \date{\today} \begin{document} \twocolumn[ \begin{@twocolumnfalse} \maketitle \vspace{-6mm} \begin{abstract} ここに概要を書きましょう. \end{abstract} \vspace{2mm} \end{@twocolumnfalse} ] \renewcommand{\thefootnote}{\fnsymbol{footnote}} \footnotetext[2]{慶應義塾環境情報学部 村井研} \renewcommand{\thefootnote}{\arabic{footnote}} \section{はじめに} hoge hoge hoge hoge \renewcommand{\refname}{参考文献} \begin{thebibliography}{数字} \bibitem[Shigeo 2000]{Shigeo 2000} Test \end{thebibliography} \end{document}// 生成したdocument.texをdocument.pdfにコンパイル $ docker run -v $(pwd):/root/work -it nontan18/texlive latexmk --pvc ./sample.texこれでworkディレクトリ内にsample.pdfが出力されますので,SkimなどのPDFビューワーを使って表示してみましょう.
表示できたら,お好きなエディタを用いて,sample.texを編集してみます.
$ vim sample.tex
編集が完了すると自動でコンパルが始まり,document.pdfが更新されるかと思います.
Dockerの基本的な使い方
このセクションでは上記のDockerコマンドで一体何が起きているのかを説明します.
docker run
docker run
はDockerイメージを元にDockerコンテナを起動するコマンドです.
run
コマンドの第1引数で指定したコマンドが起動したコンテナ内で実行されます.上記の
$ docker run -v $(pwd):/root/work -it nontan18/texlive latexmk --pvc ./sample.texにおいては
latexmk --pvc ./sample.tex
コマンドが実行されています.
(latexmk --pvc ./sample.tex
コマンドは任意のTexファイルを監視して更新されるたびに自動コンパイルするコマンドです.)
-t
オプションでDockerイメージを参照することができます.
上記の例ではDockerHubに登録されているnontan18/texlive
というイメージを参照して,それを元にDockerコンテナを作成しています.
(ちなみに,このDockerHubのようなDockerImageが登録されている場所をDockerRegistryと呼びます.)
-v
オプションはボリュームのマウントオプションで,DockerホストのボリュームをDokcerコンテナ内の任意の場所にマウントすることができます.上記の例では,texの作業用に作った
(-v オプションでは相対リンクでボリュームを指定できないので,pwd
コマンドで現在のディレクトリを取得してそれを引数に取っています.)docker ps
docker run
コマンドで動いているDockerコンテナはdocker ps
コマンドで確認することができます.$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1349e83ba710 nontan18/texlive "latexmk --pvc ./sam…" 5 seconds ago Up 3 seconds gallant_galileodocker exec
また,
docker exec -it [CONTAINER ID] [COMMAND]
コマンドを使うと,起動中のコンテナ内でコマンドを実行することができます.// $CONTAINER_IDはdocker psで取得したコンテナのIDに変更(example:1349e83ba710) $ docker exec -it $CONTEAINER_ID bash // ここからコンテナ内 root@1349e83ba710:~/work# ls sample.aux sample.dvi sample.fdb_latexmk sample.fls sample.log sample.pdf sample.synctex.gz sample.tex // TeXLiveの絵文字パッケージが入っているか調べる root@1349e83ba710:~/work# tlmgr search fontawesome // コンテナ内にTeXLiveの絵文字パッケージをインストール root@1349e83ba710:~/work# tlmgr install fontawesome //...省略 tlmgr: package repository http://mirror.utexas.edu/ctan/systems/texlive/tlnet (verified) [1/1, ??:??/??:??] install: fontawesome [498k] running mktexlsr ... done running mktexlsr. running updmap-sys ... done running updmap-sys. tlmgr: package log updated: /usr/local/texlive/2019/texmf-var/web2c/tlmgr.log // コンテナから出る root@1349e83ba710:~/work# exit exit // ホストのシェルに戻った $上記の例では先程建てたコンテナ内でbashコマンドを実行して,ターミナルからコンテナ内に入り,TeXLiveの絵文字パッケージ(fontawsome)が入っていないことを確認して,TeXLiveパッケージマネージャー(tlmgr)を用いて絵文字パッケージをインストールしました.
docker commit(※あんま使わない)
ただ,これだけではDockerコンテナ内での変更でしか無いため,一度Dockerコンテナを削除し,
docker run
コマンドで再度コンテナを建てると,絵文字パッケージはインストールされていない状態に戻ってしまいます.このDockerコンテナの変更をDockerイメージに反映させるためには
docker commit [CONTAINER ID] [IMAGE NAME]
コマンドを用います.$ docker commit 1349 nontan18/texlive sha256:a64dcff68e35d56082c52817f9432b9a2c1142d32a631f461474188912207341
これでローカルのイメージに変更が反映され,新しいイメージのSHA256ハッシュ値が出力されます.
docker images
ローカルのDockerイメージは
docker images
コマンドで確認することができ,以下の用に,変更したDockerイメージ(nontan18/texlive)のIMAGE ID
が先程のハッシュ値になっていることが確認できます.$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nontan18/texlive latest a64dcff68e35 3 minutes ago 1.48GB
実際に,
docker run -it [IMAGE_NAME] [COMMAND]
コマンドを用いて,更新したDockerイメージからDockerコンテナを作成すると,今度は絵文字パッケージ(fontawesome)がはじめからインストールされていることがわかります.// コンテナを立てるとともにbashを起動してコンテナ内に入る $ docker run -it nontan18/texlive bash // fontawesomeがインストールされているか調べる root@59b145c7371a:~/work# tlmgr search fontawesome fontawesome - Font containing web-related icons root@59b145c7371a:~/work# exit exit※ただ,上記の方法でイメージを更新すると,イメージの中身が不透明になりメンテナンスが難しくなるので
docker commit
コマンドの仕様はあまり推奨しません.そこで次にDockerイメージの元となるDockerfileを変更する方法を解説します.
Dockerfile
DockerfileはDockerイメージの作り方が書かれたファイルです.
今回使っているnontan18/texliveのDockerfileはgithubに公開されているので確認してみましょう.// githubからローカルにレポジトリをクローン $ git clone https://github.com/nontan18/texlive.git // クローンしてきたディレクトリに移動 $ cd texlive // ディレクトリ内のファイル一覧を出力 $ ls Dockerfile README.md app docker-compose.yml sample // Dockerfileの中身を出力 $ cat Dockerfile今回使ったDockerイメージ(nontan18/texlive)の元となった以下のようなDockerfileが出力されるかと思います.
FROM ubuntu:16.04 # MAINTAINER nontan <nontan@sfc.wide.ad.jp> LABEL maintainer="nontan@sfc.wide.ad.jp" WORKDIR /root/work # TexLiveの依存関係ライブラリをインストール RUN apt-get -q update RUN apt-get -qy install wget build-essential libfontconfig1 # RUN rm -rf /var/lib/apt/lists/* # TexLiveのミラーサイトからパッケージをダウンロードしてきて解凍 # WARNING: このリンクは常に最新版のTexLiveが配信されるのでbuildするごとにバージョンが変わる可能性がある. RUN wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz -O /tmp/install-tl-unx.tar.gz RUN mkdir /tmp/install-tl-unx RUN tar -xvf /tmp/install-tl-unx.tar.gz -C /tmp/install-tl-unx --strip-components=1 # インストールの設定をbasic版に変更 RUN echo "selected_scheme scheme-basic" >> /tmp/install-tl-unx/texlive.profile # TexLiveのインストール開始 RUN /tmp/install-tl-unx/install-tl -profile /tmp/install-tl-unx/texlive.profile # TexLiveのインストールバージョンを調べて,PATHを通せるようにシンボリックリンクを張っておく RUN TEX_LIVE_VERSION=$(/tmp/install-tl-unx/install-tl --version | tail -n +2 | awk '{print $5}'); \ ln -s "/usr/local/texlive/${TEX_LIVE_VERSION}" /usr/local/texlive/latest ENV PATH="/usr/local/texlive/latest/bin/x86_64-linux:${PATH}" # Install Packages RUN tlmgr install latexmk COPY ./app/config/.latexmkrc /root/.latexmkrc # 2カラムの設定に必要なパッケージのインストール RUN tlmgr install multirow # 日本語対応パッケージのインストール RUN tlmgr install collection-langjapanese # フォントパッケージのインストール RUN tlmgr install collection-fontsrecommended RUN tlmgr install collection-fontutils # References # - https://github.com/blang/latex-docker # - https://github.com/Paperist/docker-alpine-texlive-ja/blob/master/Dockerfileここで,先程のように
fontawesome
をインストールしておくには,RUN tlmgr install fontawesome
を追加します.RUN tlmgr install collection-fontutils # 下の行を追加 RUN tlmgr install fontawesomedocker build
DockerfileからDockerイメージをビルドするには,
docker build -t [IMAGE NAME] [Dockerfileのパス]
コマンドを用います.$ docker build -t mylatexlive .Dockerイメージのビルドが終わったら,
docker images
コマンドでDockerイメージが追加されているのがわかります.$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mylatexlive latest 0bbb5bed8ce1 7 minutes ago 1.45GB
当然,このDockerイメージからDockerコンテナを作成すると,fontawesomeのパッケージがインストールされていることがわかります.
// コンテナを立てるとともにbashを起動してコンテナ内に入る $ docker run -it mytexlive bash // fontawesomeがインストールされているか調べる root@59b145c7371a:~/work# tlmgr search fontawesome fontawesome - Font containing web-related icons root@59b145c7371a:~/work# exit exitdocker-composeの基本的な使い方
ここまででDockerの基本的な使い方を学びましたが,実際にDockerを用いて環境構築を行おうと考えると,複数のコンテナで様々なDockerイメージやオプションを追加しなければならなく非効率です.
そこで,複数のコンテナを効率的に管理するためにdokcer-composeを紹介します.
docker-compose.yml
docker-composeは
docker-compose.yml
に記述したDockerコンテナの構成をdocker-compose up
コマンドやdocker-compose down
コマンドなどで手軽に展開できるツールです.ここでは,上の過程で
git clone
したdocker-compose.yml
を見てみましょう.docker-compose.ymlversion: "3.1" services: texlive: # build: . # image: nontan18/texlive image: texlive volumes: - ./sample:/root/work command: latexmk --pvc /root/work/sample.tex nginx: # /root/public以下のファイルをホスティングするnginxベースのイメージ image: nontan18/stable-file-host ports: # "ホストのポート:コンテナのポート" - "8080:80" volumes: # 生成されるsample.pdfを公開ディレクトリにマウント - ./sample/sample.pdf:/root/public/sample.pdf上記の
docker-compose.yml
ではtexliveコンテナによって出力されたsample.pdf
がnginxコンテナの/root/public/sample.yml
にマウントされるようになっています.nginxコンテナのイメージであるnontan18/stable-file-host
は/root/public/
以下のファイルをホスティングしているため,nginxコンテナの80番ポートにアクセスすることができれば,ブラウザ上でsample.pdf
を閲覧することができます.ここでは
ports
でホストの8080番ポートをnginxコンテナ内の80番ポートに転送しているので,このコンテナがたつと,ブラウザからhttp://localhost:8080/sample.pdf
にアクセスすることで出力されたPDFを閲覧することが可能になります.docker-compose up
上記の
docker-compose.yml
のあるディレクトリでdocker-compose up
コマンドを実行すると下記のようにdocker-compose.ymlに記述されたすべてのコンテナが起動します.$ docker-compose up Starting texlive_nginx_1 ... Starting texlive_nginx_1 ... done Attaching to texlive_texlive_1, texlive_nginx_1上記の通り,
http://localhost:8080/sample.pdf
にアクセスすると出力されたPDFが確認できるはずです.docker-compose ps
docker-compose up
した状態でdocker-compose ps
コマンドを実行すると,docker-compose.ymlで定義された各コンテナが確認できます.$ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------- texlive_nginx_1 nginx -g daemon off; Up 0.0.0.0:8080->80/tcp texlive_texlive_1 latexmk --pvc /root/work/s ... Updocker-compose down
docker-compose up
をした状態でCtrl + C
で各コンテナを停止させることもできますが,別のターミナルのセッションからdocker-compose down
を用いることで起動したすべてのDockerコンテナを停止することができます.$ docker-compose down
docker-compose down
には,マウントしたDockerボリューム(本稿では解説していませんが,ホストの特定ディレクトリをマウントする以外のコンテナのデータを永続化させる方法)をすべて削除する-v
オプションや使用しているイメージを削除する--rmi
オプションなどが存在します.MySQL+Django+Angularのようなサーバークライアントモデルの開発環境を構築する際には,このdocker-composeは非常に便利です.
おわりに
最後に,今回,無造作に建てたDockerコンテナとイメージを削除してクリーンな状態に戻しましょう.
docker container rm [CONTAINER ID]
コマンドやdocker image rm [IMAGE NAME]
コマンドでもDockerコンテナやDockerイメージの削除は可能ですが,ここではdocker container prune
とdocker image prune
を紹介します.docker container prune
docker container prune
コマンドは停止しているDockerコンテナをすべて削除するコマンドです.
docker ps
コマンドで起動中のコンテナを確認し,不必要なコンテナをdocker stop [CONTAINER ID]
で停止させたのち,docker container prune
コマンドを実行しましょう.$ docker container prune
docker image prune
docker container prune
と同様にdocker image prune
は起動中のコンテナに使用されていないDockerイメージを全て削除します.(なぜだかは知りませんが削除するイメージの数が多いとだいぶ長く時間がかかることがあります)$ docker image prune
これで本稿で作成したコンテナもイメージも綺麗さっぱりホストから削除することができました.
従来の仮想化技術より軽量なコンテナ仮想化技術は,複雑な環境ごとパッケージ化したアプリケーションを気軽に展開したり削除したりできて非常に便利です.
本稿で紹介したのはDockerコマンドの一部に過ぎず,DockerはCIツールやクラスターにコンテナによるオーケストレーションを展開するkubernetes,アプリケーションコンテナの依存関係を整理しパッケージ管理するHelm,Docker環境にkubernetesクラスターを瞬時に展開しHelmを用いてアプリケーションを展開するRancherなどDockerの世界は非常に広大です.
本稿が皆様の
Hello Docker World
のきっかけになれば幸いです.注意事項
上記では何の躊躇もせずに筆者がビルドしたDockerイメージを使用していますが,信頼できない他人の作ったDockerイメージを安易に使用するのには注意が必要です.
たとえDockerfileが公開されていたとしても,Dockerレジストリに公開されているDockerイメージが悪意の無いものとは限りません.
Dockerfileを精査したのち,自身でdocker build
を行って使用することを推奨します.
特にホストのボリュームをマウントする場合や,--privileged
オプションを必要とするものには注意しましょう.参考
- 投稿日:2019-05-23T14:33:25+09:00
【Docker超入門】DockerでつくるLaTeX環境
本稿に関して動作がおかしいところや不明な点,ツッコミなどがあれば適宜コメントいただけるとありがたいです.
はじめに
大学の研究会で講義を1コマ持つことになったため,弊研究会では必須なLaTeX環境をDockerで作る方法を解説することにしました.
読者としてはDockerの知識が一切ない人を想定しています.
なお,本稿ではLaTeX自体の使い方に関してはあまり触れません.
LaTeXとは?
LateXとは,Donald E. Knuth氏が開発したレイアウトシステムのTexをLeslie Lamport氏が文書作成のために改良したものだそうです.主に学術論文を書く際に使用されており,数式を綺麗にレイアウトしてくれます.
例えば,世界一美しいとされるオイラーの等式でさえ,テキストで表現すると美しくないですが,
e^{iπ} + 1 = 0
TeXを用いてコンパイルすれば,以下のように美しくレイアウトされます.
$e^{iπ} + 1 = 0$
Dockerとは?
Dockerとはコンテナ仮想化技術のプラットフォームです.
従来の仮想化技術では,ホストOS上の仮想ハードウェアや,Hypervisorを利用してゲストOSを動かしていたのに対し,DockerではDocker EngineがホストOSのカーネルの利用を上手く管理することでプロセスとユーザを隔離しているため,VMに比べて軽量な仮想化環境を実現しています.
事前準備
本稿では,このDockerを用いてLaTeXのディストリビューションであるTeXLiveの環境を行うため,まずはDockerと生成されたPDFの閲覧用にSkimをインストールします,
Dockerのインストール
下記ページからDockerHubのアカウントを作成しdmgをダウンロードしてインストールします.
MAC=> https://docs.docker.com/docker-for-mac/install/
Windows=> https://docs.docker.com/docker-for-mac/install/Mac用Skim(軽量PDFビューワー)のインストール
下記ページよりダウンロードしてインストール
https://skim-app.sourceforge.io/全体像を把握する
今回は下記のような構成でDockerを用いてLaTeX環境を構築します.
とりあえずDockerでLaTex環境を建ててみる
DockerとSkimのインストールが完了したら,筆者が事前に用意したTeXLiveのDockerイメージ(nontan18/texlive)を用いて以下のコマンドでLaTeX環境を実際に構築してみましょう.
// 作業用のworkディレクトリを作成し移動 $ mkdir work && cd work
work
ディレクトリに入ったら下記の内容のファイルを作成します.sample.tex\documentclass[twocolumn, a4j]{article} \usepackage{multirow} \usepackage{amsmath,amssymb} \usepackage[T1]{fontenc} \title{サンプル用のTexファイル} \renewcommand{\thefootnote}{\fnsymbol{footnote}} \author{Nozomu Miyamoto\footnotemark[2] nontan@sfc.wide.ad.jp} \renewcommand{\thefootnote}{\arabic{footnote}} \date{\today} \begin{document} \twocolumn[ \begin{@twocolumnfalse} \maketitle \vspace{-6mm} \begin{abstract} ここに概要を書きましょう. \end{abstract} \vspace{2mm} \end{@twocolumnfalse} ] \renewcommand{\thefootnote}{\fnsymbol{footnote}} \footnotetext[2]{慶應義塾大学 村井研} \renewcommand{\thefootnote}{\arabic{footnote}} \section{はじめに} hoge hoge hoge hoge \renewcommand{\refname}{参考文献} \begin{thebibliography}{数字} \bibitem[opt]{key} 文献情報 \end{thebibliography} \end{document}// 生成したdocument.texをdocument.pdfにコンパイル $ docker run -v $(pwd):/root/work -it nontan18/texlive:stable latexmk --pvc ./sample.texこれでworkディレクトリ内にsample.pdfが出力されますので,SkimなどのPDFビューワーを使って表示してみましょう.
表示できたら,お好きなエディタを用いて,sample.texを編集してみます.
$ vim sample.tex
編集が完了すると自動でコンパルが始まり,document.pdfが更新されるかと思います.
Dockerの基本的な使い方
このセクションでは上記のDockerコマンドで一体何が起きているのかを説明します.
docker run
docker run
はDockerイメージを元にDockerコンテナを起動するコマンドです.
run
コマンドの第1引数で指定したコマンドが起動したコンテナ内で実行されます.上記の
$ docker run -v $(pwd):/root/work -it nontan18/texlive:1.0.0 latexmk --pvc ./sample.texにおいては
latexmk --pvc ./sample.tex
コマンドが実行されています.
(latexmk --pvc ./sample.tex
コマンドは任意のTexファイルを監視して更新されるたびに自動コンパイルするコマンドです.)
-t
オプションでDockerイメージを参照することができます.
上記の例ではDockerHubに登録されているnontan18/texlive
というイメージ(より詳細には,その中でも1.0.0タグがついているイメージ)を参照して,それを元にDockerコンテナを作成しています.
(ちなみに,このDockerHubのようなDockerImageが登録されている場所をDockerRegistryと呼びます.)
-v
オプションはボリュームのマウントオプションで,DockerホストのボリュームをDokcerコンテナ内の任意の場所にマウントすることができます.上記の例では,texの作業用に作った
(-v オプションでは相対リンクでボリュームを指定できないので,pwd
コマンドで現在のディレクトリを取得してそれを引数に取っています.)docker ps
docker run
コマンドで動いているDockerコンテナはdocker ps
コマンドで確認することができます.$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1349e83ba710 nontan18/texlive:1.0.0 "latexmk --pvc ./sam…" 5 seconds ago Up 3 seconds gallant_galileodocker exec
また,
docker exec -it [CONTAINER ID] [COMMAND]
コマンドを使うと,起動中のコンテナ内でコマンドを実行することができます.// $CONTAINER_IDはdocker psで取得したコンテナのIDに変更(example:1349e83ba710) $ docker exec -it $CONTEAINER_ID sh // ここからコンテナ内 ~/work# ls sample.aux sample.dvi sample.fdb_latexmk sample.fls sample.log sample.pdf sample.synctex.gz sample.tex // TeXLiveの絵文字パッケージが入っているか調べる ~/work# tlmgr search fontawesome // コンテナ内にTeXLiveの絵文字パッケージをインストール ~/work# tlmgr install fontawesome //...省略 tlmgr: package repository http://mirror.utexas.edu/ctan/systems/texlive/tlnet (verified) [1/1, ??:??/??:??] install: fontawesome [498k] running mktexlsr ... done running mktexlsr. running updmap-sys ... done running updmap-sys. tlmgr: package log updated: /usr/local/texlive/2019/texmf-var/web2c/tlmgr.log // コンテナから出る ~/work# exit exit // ホストのシェルに戻った $上記の例では先程建てたコンテナ内でshコマンドを実行して,ターミナルからコンテナ内に入り,TeXLiveの絵文字パッケージ(fontawsome)が入っていないことを確認して,TeXLiveパッケージマネージャー(tlmgr)を用いて絵文字パッケージをインストールしました.
docker commit(※あんま使わない)
ただ,これだけではDockerコンテナ内での変更でしか無いため,一度Dockerコンテナを削除し,
docker run
コマンドで再度コンテナを建てると,絵文字パッケージはインストールされていない状態に戻ってしまいます.このDockerコンテナの変更をDockerイメージに反映させるためには
docker commit [CONTAINER ID] [IMAGE NAME]
コマンドを用います.$ docker commit 1349 nontan18/texlive:stable sha256:a64dcff68e35d56082c52817f9432b9a2c1142d32a631f461474188912207341
これでローカルのイメージに変更が反映され,新しいイメージのSHA256ハッシュ値が出力されます.
docker images
ローカルのDockerイメージは
docker images
コマンドで確認することができ,以下の用に,変更したDockerイメージ(nontan18/texlive)のIMAGE ID
が先程のハッシュ値になっていることが確認できます.$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nontan18/texlive stable a64dcff68e35 3 minutes ago 1.48GB
実際に,
docker run -it [IMAGE_NAME] [COMMAND]
コマンドを用いて,更新したDockerイメージからDockerコンテナを作成すると,今度は絵文字パッケージ(fontawesome)がはじめからインストールされていることがわかります.// コンテナを立てるとともにshを起動してコンテナ内に入る $ docker run -it nontan18/texlive:stable sh // fontawesomeがインストールされているか調べる ~/work# tlmgr search fontawesome fontawesome - Font containing web-related icons ~/work# exit exit※ただ,上記の方法でイメージを更新すると,イメージの中身が不透明になりメンテナンスが難しくなるので
docker commit
コマンドの仕様はあまり推奨しません.そこで次にDockerイメージの元となるDockerfileを変更する方法を解説します.
Dockerfile
DockerfileはDockerイメージの作り方が書かれたファイルです.
今回使っているnontan18/texliveのDockerfileはgithubに公開されているので確認してみましょう.// githubからローカルにレポジトリをクローン $ git clone https://github.com/nontan18/texlive.git // クローンしてきたディレクトリに移動 $ cd texlive // ディレクトリ内のファイル一覧を出力 $ ls Dockerfile README.md app docker-compose.yml sample // Dockerfileの中身を出力 $ cat Dockerfile今回使ったDockerイメージ(nontan18/texlive)の元となった以下のようなDockerfileが出力されるかと思います.
# Alpine Linux v3.9.4をベースのイメージとして指定 FROM alpine:3.9.4 # MAINTAINER nontan <nontan@sfc.wide.ad.jp> LABEL maintainer="nontan@sfc.wide.ad.jp" WORKDIR /root/work # パッケージリストの更新 RUN apk update # TeXLiveのインストールに必要なパッケージを取得 RUN apk add perl wget fontconfig-dev # TeXLiveのインストーラーの解凍に必要なパッケージのインストール RUN apk add xz tar # 圧縮されたTeXLiveのインストーラーをダウンロードし,tmpディレクトリに保存 ADD http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz /tmp/install-tl-unx.tar.gz # インストーラーを解凍した際に配置するディレクトリを作成 RUN mkdir /tmp/install-tl-unx # ダウンロードしたinstall-tl-unx.tar.gzを解凍 RUN tar -xvf /tmp/install-tl-unx.tar.gz -C /tmp/install-tl-unx --strip-components=1 # TeXLiveのインストール用の設定ファイルを作成 RUN echo "selected_scheme scheme-basic" >> /tmp/install-tl-unx/texlive.profile # TeXLiveのインストール RUN /tmp/install-tl-unx/install-tl -profile /tmp/install-tl-unx/texlive.profile # TeXLiveのバージョンを取得しインストールディレクトリを特定し,latestの名称でシンボリックリンクを作成 RUN TEX_LIVE_VERSION=$(/tmp/install-tl-unx/install-tl --version | tail -n +2 | awk '{print $5}'); \ ln -s "/usr/local/texlive/${TEX_LIVE_VERSION}" /usr/local/texlive/latest # インストールしたTeXLiveへパスを通す ENV PATH="/usr/local/texlive/latest/bin/x86_64-linuxmusl:${PATH}" # TeXLive Package Managerを使用して必要なパッケージをインストール # texファイルの自動コンパイルパッケージをインストール RUN tlmgr install latexmk # latexmkの設定ファイルをホストからイメージにコピー COPY ./app/config/.latexmkrc /root/.latexmkrc # 2カラムの設定に必要なパッケージのインストール RUN tlmgr install multirow # 日本語対応パッケージのインストール RUN tlmgr install collection-langjapanese # フォントパッケージのインストール RUN tlmgr install collection-fontsrecommended RUN tlmgr install collection-fontutils # 不要なパッケージなどの削除(イメージの容量削減のため) RUN apk del xz tar RUN rm -rf /var/cache/apk/* RUN rm -rf /tmp/* # References # - https://github.com/blang/latex-docker # - https://github.com/Paperist/docker-alpine-texlive-ja/blob/master/Dockerfileここで,先程のように
fontawesome
をインストールしておくには,RUN tlmgr install fontawesome
を追加します.# フォントパッケージのインストール RUN tlmgr install collection-fontsrecommended RUN tlmgr install collection-fontutils # 下の行を追加 RUN tlmgr install fontawesomedocker build
DockerfileからDockerイメージをビルドするには,
docker build -t [IMAGE NAME] .
コマンドを用います.$ docker build -t mylatexlive .Dockerイメージのビルドが終わったら,
docker images
コマンドでDockerイメージが追加されているのがわかります.$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mylatexlive latest 0bbb5bed8ce1 7 minutes ago 1.45GB
当然,このDockerイメージからDockerコンテナを作成すると,fontawesomeのパッケージがインストールされていることがわかります.
// コンテナを立てるとともにshを起動してコンテナ内に入る $ docker run -it mytexlive sh // fontawesomeがインストールされているか調べる ~/work# tlmgr search fontawesome fontawesome - Font containing web-related icons ~/work# exit exitdocker-composeの基本的な使い方
ここまででDockerの基本的な使い方を学びましたが,実際にDockerを用いて環境構築を行おうと考えると,複数のコンテナで様々なDockerイメージやオプションを追加しなければならなく非効率です.
そこで,複数のコンテナを効率的に管理するためにdokcer-composeを紹介します.
docker-compose.yml
docker-composeは
docker-compose.yml
に記述したDockerコンテナの構成をdocker-compose up
コマンドやdocker-compose down
コマンドなどで手軽に展開できるツールです.ここでは,上の過程で
git clone
したdocker-compose.yml
を見てみましょう.docker-compose.ymlversion: "3.1" services: texlive: build: . # image: nontan18/texlive volumes: - ./sample:/root/work command: latexmk --pvc /root/work/sample.tex nginx: # /root/public以下のファイルをホスティングするnginxベースのイメージ image: nontan18/stable-file-host ports: # "ホストのポート:コンテナのポート" - "8080:80" volumes: # 生成されるsample.pdfを公開ディレクトリにマウント - ./sample:/root/public上記の
docker-compose.yml
ではtexliveコンテナでコンパイルされたsample.pdfファイルが入っているsampleディレクトリがnginxコンテナの/root/public/
にマウントされるようになっています.nginxコンテナのイメージであるnontan18/stable-file-host
は/root/public/
以下のファイルをホスティングしているため,nginxコンテナの80番ポートにアクセスすることができれば,ブラウザ上でsample.pdf
を閲覧することができます.ここでは
ports
でホストの8080番ポートをnginxコンテナ内の80番ポートに転送しているので,このコンテナがたつと,ブラウザからhttp://localhost:8080/sample.pdf
にアクセスすることで出力されたPDFを閲覧することが可能になります.docker-compose up
上記の
docker-compose.yml
のあるディレクトリでdocker-compose up
コマンドを実行すると下記のようにdocker-compose.ymlに記述されたすべてのコンテナが起動します.$ docker-compose up Starting texlive_nginx_1 ... Starting texlive_nginx_1 ... done Attaching to texlive_texlive_1, texlive_nginx_1上記の通り,
http://localhost:8080/sample.pdf
にアクセスすると出力されたPDFが確認できるはずです.docker-compose ps
docker-compose up
した状態でdocker-compose ps
コマンドを実行すると,docker-compose.ymlで定義された各コンテナが確認できます.$ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------- texlive_nginx_1 nginx -g daemon off; Up 0.0.0.0:8080->80/tcp texlive_texlive_1 latexmk --pvc /root/work/s ... Updocker-compose down
docker-compose up
をした状態でCtrl + C
で各コンテナを停止させることもできますが,別のターミナルのセッションからdocker-compose down
を用いることで起動したすべてのDockerコンテナを停止することができます.$ docker-compose down
docker-compose down
には,マウントしたDockerボリューム(本稿では解説していませんが,ホストの特定ディレクトリをマウントする以外のコンテナのデータを永続化させる方法)をすべて削除する-v
オプションや使用しているイメージを削除する--rmi
オプションなどが存在します.MySQL+Django+Angularのようなサーバークライアントモデルの開発環境を構築する際には,このdocker-composeは非常に便利です.
おわりに
最後に,今回,無造作に建てたDockerコンテナとイメージを削除してクリーンな状態に戻しましょう.
docker container rm [CONTAINER ID]
コマンドやdocker image rm [IMAGE NAME]
コマンドでもDockerコンテナやDockerイメージの削除は可能ですが,ここではdocker container prune
とdocker image prune
を紹介します.docker container prune
docker container prune
コマンドは停止しているDockerコンテナをすべて削除するコマンドです.
docker ps
コマンドで起動中のコンテナを確認し,不必要なコンテナをdocker stop [CONTAINER ID]
で停止させたのち,docker container prune
コマンドを実行しましょう.$ docker container prune
docker image prune
docker container prune
と同様にdocker image prune
は起動中のコンテナに使用されていないDockerイメージを全て削除します.(なぜだかは知りませんが削除するイメージの数が多いとだいぶ長く時間がかかることがあります)$ docker image prune
これで本稿で作成したコンテナもイメージも綺麗さっぱりホストから削除することができました.
従来の仮想化技術より軽量なコンテナ仮想化技術は,複雑な環境ごとパッケージ化したアプリケーションを気軽に展開したり削除したりできて非常に便利です.
本稿で紹介したのはDockerコマンドの一部に過ぎず,DockerはCIツールやクラスターにコンテナによるオーケストレーションを展開するkubernetes,アプリケーションコンテナの依存関係を整理しパッケージ管理するHelm,Docker環境にkubernetesクラスターを瞬時に展開しHelmを用いてアプリケーションを展開するRancherなどDockerの世界は非常に広大です.
本稿が皆様の
Hello Docker World
のきっかけになれば幸いです.注意事項
上記では何の躊躇もせずに筆者がビルドしたDockerイメージを使用していますが,信頼できない他人の作ったDockerイメージを安易に使用するのには注意が必要です.
たとえDockerfileが公開されていたとしても,Dockerレジストリに公開されているDockerイメージが悪意の無いものとは限りません.
Dockerfileを精査したのち,自身でdocker build
を行って使用することを推奨します.
特にホストのボリュームをマウントする場合や,--privileged
オプションを必要とするものには注意しましょう.参考
- 投稿日:2019-05-23T02:38:46+09:00
Laravelローカル開発環境10分でセットアップ手順(Laradock)
Webアプリケーション開発で、Laravel利用、スピード重視な方、バックエンドメインでインフラ経験がない方向けの記事になります。
触れる技術、サービスのリストはこちら
- Laravel
- Laradock
- Docker for Mac
- docker-composeローカル開発環境設定
Laravel
まずはローカルでLaravelアプリケーションの作成。
% composer create-project --prefer-dist laravel/laravel yourappnameまたは
% laravel new yourappnameLaradock
次にLaradockでLaravel用Docker環境を作ります。
*Docker for Macがない方は、ここでインストールしておいてください。
*docker-composeコマンドがない方は、ここでインストールしておいてください。Laradock(laravel用docker環境)をローカルに落としてきます。
自分はアプリケーション作成したディレクトリと同じ階層にcloneしています。% git clone https://github.com/Laradock/laradock.git % ls yourappname laradockという感じで。次はlaradockとアプリケーションをつないでいきます。
% cd laradock % cp env-example .env.env設定@laradock
.envを編集
.env APP_CODE_PATH_HOST=../yourappname DATA_PATH_HOST=.laradock/yourappname_data # MYSQLの項目を探す MYSQL_VERSION=5.7 # 推奨 MYSQL_DATABASE=任意 MYSQL_USER=任意 MYSQL_PASSWORD=任意nginx設定@laradock
laradock/nginx/sites/の下にアプリケーション用の設定ファイル(下記ではyourapp.conf)を作成します。
yourapp.conf server { listen 80; #listen [::]:80; # For https # listen 443 ssl default_server; # listen [::]:443 ssl default_server ipv6only=on; # ssl_certificate /etc/nginx/ssl/default.crt; # ssl_certificate_key /etc/nginx/ssl/default.key; server_name yourapp.test; root /var/www/yourappname/public; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri /index.php =404; fastcgi_pass php-upstream; fastcgi_index index.php; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #fixes timeouts fastcgi_read_timeout 600; include fastcgi_params; } location ~ /\.ht { deny all; } location /.well-known/acme-challenge/ { root /var/www/letsencrypt/; log_not_found off; } }後少しです。
.env@laravel
今度は、
yourappname
のディレクトリに移動して、アプリケーションの.env
ファイルを修正します# .env DB_HOST=mysql REDIS_HOST=redis QUEUE_HOST=beanstalkdhostsファイル編集
今、nginxの項で設定したyourapp.testにアクセスできないのでアクセスできるようにします(
hosts
ファイルをいじります)% sudo vim /etc/hosts 127.0.0.1 yourapp.test #追加Dockerコンテナ立ち上げ
いよいよです。
Dockerが立ち上がっていることを確認して、% docker-compose up nginx mysql php-fpm redisでコンテナを立ち上げます
ブラウザで
yourapp.test
にアクセスできることを確認。
php artisan migrate
する時は、workspaceコンテナに入ります。# laradock % docker-compose exec --user=laradock workspace bash laradock####:/var/www$ cd yourappname laradock####:/var/www$ php artisan migrate簡単にローカル開発環境がセットアップできました。
続き
次は下記に関して書いて、通しでローカル開発環境、ステージング環境を作れるよう記事を書きたいと思います。
laravelステージング環境設定について
利用するサービスリスト
- Amazon Web Service
- Elasticbeanstalk
- Amazon RDS