20210606のdockerに関する記事は17件です。

Djangoの環境をDokcerで作る【メモ】

Pythonを普段から触っているため、何かしらWebアプリのフレームワークなどを使ってみようと思い、Djangoを軽くどんな感じか触ってみる。 手順を適当に書いていく。 目次 DockerでDjangoの環境を適当に作成 VSCodeでDockerの環境にアクセスする 雛形?を作る とりまえずここまでやってみる DockerでDjangoの環境作る DockerHubには、すでにDjangoのイメージがあるみたいですが、練習がてらUbuntuから作ってみる。 RUN apt update && apt upgrade -y && apt install -y tzdata ENV TZ Asia/Tokyo 自分の買った書籍にPostgreSQLを使ってるみたいなので、タイムゾーン用の設定をする RUN apt install -y wget postgresql python3 python3-pip && pip install django これ書いてて思ったけど、wgetいらないですね…(今のところ) PythonとDjangoをインストールします これをビルドして一応DockerHubにあげてあります。 https://hub.docker.com/repository/docker/sugimochi/django_env VSCodeでアクセスする 今まではやる機会がなかったんですが、これを機に使ってみようかと。 とは言っても簡単で、Dockerの拡張機能を入れて、Docker-compose使ってUPする。 version: '3' services: django: image: sugimochi/django_env volumes: - './work:/work' ports: - '8000:8000' tty: true stdin_open: true Docker-composeはこのように記述。ポートはとりあえずの番号。 この画面から これを選ぶ。 そうすると、Dockerコンテナの環境でVScodeを開くことができる。 雛形を作る まず、マウントしてるディレクトリに移動する。 $ cd ../work そこでプロジェクト作成のコマンドをうつ。 work$ django-admin startproject private_diary 次にこれをうつ(まだこれを打つ理由はよくわかってない) private_diary$ python3 manage.py startapp diary 以上! 今後の展望 今回は時間がないのでこれくらいで… 色々なサンプルとか見ながら触ってみようと思います… 参考文献 動かして学ぶ!Python Django開発入門 米国AI開発者がゼロから教えるDocker講座 Docker for Visual Studio Codeでコンテナ操作 はじめての Django アプリ作成、その 1 | Django ドキュメント | Django GitHub Dockerfile等
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP × Xdebug × Docker × VSCodeで快適な開発環境をつくってみた

はじめに Rails でポートフォリオを作成してエンジニア転職をしたすずです。 現在は Laravel を主に使用していますがデバッグが捗らない...。 PHP でも Rails の pry-rails みたいに簡単にデバッグをしたかったので Xdebug を導入しました。 目次 はじめに 目次 環境 前提条件 ディレクトリ構成 準備 プロジェクト作成 必要ファイル作成 拡張機能 Docker環境構築 docker-compose.yml Dockerfile コンテナ接続 設定ファイル php.ini xdebug.ini devcontainer.json launch.json 使い方 おわりに 参考文献 環境 macOS Catalina 10.15.7 windows10 pro docker Xdebug 3系 前提条件 Docker 環境 docker-compose.yml Dockerfile ディレクトリ構成 このような構成を想定 . ├── .devcontainer │ └── devcontainer.json ├── app │      ├── .vscode │      │ └── launch.json // 後述しますが、VSCodeの左のバーにある虫マークをクリックすると生成されます。 │      └── addNum.php // デバッグテスト用のファイル ├── docker │ └── php │ ├── Dockerfile │ ├── xdebug.ini │ └── php.ini └── docker-compose.yml 準備 プロジェクト作成 プロジェクトを作成していきます。プロジェクト名はお好きな名前で大丈夫です。ここでは 「php_xdebug_app」 という名前で進めていきます。 ターミナル mkdir php_xdebug_app cd php_xdebug_app 必要ファイル作成 全体の見通しを良くするためファイルを始めに作成していきます。 作成ははじめに載せたディレクトリ構成に沿った形で作成しています。 ターミナル touch docker-compose.yml mkdir docker/php touch docker/php/Dockerfile touch docker/php/php.ini touch docker/php/xdebug.ini touch .devcontainer/devcontainer.json # プロジェクトパス(デバッグしていきたいファイルなどを格納します。) mkdir app 拡張機能 以下の VSCode の拡張機能が必要になりますのでインストールをしてください。 PHPでデバッグをするのに必要になります。 コンテナ内に入るのに必要になります。 Docker環境構築 docker-compose.yml docker-compose.yml version: "3.8" services: php: build: context: . dockerfile: docker/php/Dockerfile volumes: - ./app:/var/www/html ports: - "8000:80" Dockerfile docker/php/Dockerfile FROM php:7.4-fpm WORKDIR /var/www/html RUN apt-get update \ && apt-get install -y libonig-dev libzip-dev unzip \ # xdebug install && pecl install xdebug \ && docker-php-ext-enable xdebug # composer (今回は使用しませんが。。) COPY --from=composer:2 /usr/bin/composer /usr/bin/composer # docker-compose.ymlで指定した volumes と同じように書いてください。 # COPY [コピーする(ローカル)] [コピー先(コンテナ内)] (詳しくは参考文献をご覧ください。) COPY ./app /var/www/html COPY ./docker/php/php.ini /usr/local/etc/php/php.ini COPY ./docker/php/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini 設定ファイル php.ini PHP の設定ファイル。 docker/php/php.ini display_errors = On display_startup_errors = On max_execution_time = 30 session.gc_divisor = 1000 session.sid_bits_per_character = 5 output_buffering = 4096 memory_limit = 128M upload_max_filesize = 64M post_max_size = 64M max_input_vars = 1000 log_errors = On error_log = /dev/stderr error_reporting = E_ALL expose_php = On zend.exception_ignore_args = Off xdebug.ini xdebug の設定ファイル。 docker/php/xdebug.ini xdebug.client_host = host.docker.internal xdebug.start_with_request = yes xdebug.mode = debug # port 番号はデフォルトで9003番ですがわかりやすいように明示的に書いています。9003ではなくても空いているポートなら大丈夫です。 # 後述する .devcontainer/devcontainer.json に書く port と同じにしてください。 xdebug.client_port = 9003 xdebug.log = /var/log/xdebug.log devcontainer.json VSCodeがDockerコンテナに接続するための設定ファイル。 .devcontainer/devcontainer.json { "name": "php_xdebug_app", // お好きな名前 "dockerComposeFile": [ // docker-compose.ymlのパスを記載 "../docker-compose.yml", ], "service": "php", // docker-compose.yml に記載しているサービス名で起動したいコンテナ "workspaceFolder": "/var/www/html", // 作業するパス "forwardPorts": [ // xdebug.iniに書いたport番号と同じにする 9003 ], "extensions": [ // コンテナ内で使用したい拡張機能、お好みに合わせて設定してください。 "felixfbecker.php-debug", "coenraads.bracket-pair-colorizer-2", "oderwat.indent-rainbow", "streetsidesoftware.code-spell-checker", "mosapride.zenkaku" ] } コンテナ接続 Docker環境を構築し、設定ファイルも作成したのでいよいよデバッグ機能を使用する環境(PHPコンテナ内)に入ります。 その前にコンテナをビルドして立ち上げておきましょう。以下のコマンドを叩いてください。 ターミナル # build docker-compose build # コンテナ立ち上げ docker-compose up 以下のような手順でコンテナ接続していきます。文字だけですと伝わらない部分あるかと思いますので Gif を作成しました。ぜひご覧ください。 (※ お使いの環境によって青い表示といっている部分が青くなかったらすみません。適宜対応していただけると助かります。) 1. VSCode画面左下にある青いマークをクリック 2. Reopen in Container をクリック  3. しばらく立ったら画面遷移して左下の青い表示が devcontainer.json で設定した name と同じになっていたらコンテナと接続できています。 launch.json デバッグするのにも設定ファイルが必要になります。 launch.json作成していきます。 VSCode の左側のパネルに虫マーク (実行とデバッグ) があります。これをクリックすると launch.json の作成を求められるかと思うので作成を押してください。わかりにくい場合はディレクトリ構成に合わせてファイルを作成していただいても大丈夫だと思います。 app/.vscode/launch.json { "version": "0.2.0", "configurations": [ { "name": "XDebug on docker", // お好きな名前 "type": "php", // 今回はPHPなので "request": "launch", "port": 9003, // portはxdebug.iniで設定したportと一緒にする "stopOnEntry": true, // デバッグが有効なときにプログラムを中断する } ] } 以上でデバッグができるようになります。 使い方 言葉だけでは伝わらない部分があると思いますのでこちらも Gif を載せておきますので参考にしていただけたら幸いです。 変数など値を確認したいところにブレークポイント(赤ポチ)を置く 左のバーにある虫マークをクリック 左上に再生ボタンが現れるのでクリック(下のバーがオレンジ色に切り替わる) テストなどで動作を確認してみる。 簡単なプログラムを作成したので動作確認などでお使いください。 数字を足して出力するだけのプログラムです。このファイルを実行していきます。 addNum.php <?php function addNum(int $num1, int $num2): int { return $num1 + $num2; } $num1 = 1; $num2 = 2; $result = addNum($num1, $num2); print_r($result); 横のバーに変数名と値など表示されますが、デバッグコンソールに変数名など入力することでも値をみることができます。 おわりに var_dump() などで値を見るよりも簡単に確認することができるようになりました。 まだ使いこなせていませんが、開発をしていって慣れていきたいと思います。 参考までに今回のソースコードをこちらにまとめさせていただきました。 お役に立つことができましたら幸いです。 参考文献 Docker VSCode PHP デバッグ 設定 xdebug vscodeでxdebug3のdocker環境を作る WSL2+Docker+VSCode+PHPでXdebugを使用する際のホストにhost.docker.internalは使えない vscode↔Docker内PHPでリモートデバッグしたときにハマったこと PHPの開発効率化!VSCode+DockerでXdebugを使ってみよう Visual Studio CodeのRemote DevelopmentとDockerで快適な開発環境をゲット 今回作成したプロジェクトのソースコード
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【rails】docker + rails + heroku メールでユーザー認証をしようとした時にhttp://localhost:3000/~からメールが届く

1.起きている問題やエラーメッセージ 備忘録として残しておきます。 チームメンバーと開発したポートフォリオの一つをherokuでデプロイしました。 アプリへサインインした際、ユーザー認証メールが届き、URLをクリックするとアプリのドメイン名に遷移させたいという話です。 docker+rails環境でアプリを作成し、本番環境にデプロイしました。 サインアップにgem deviseを使用しているため、サインアップすると ユーザー認証メールが届きますが、記載のURLをクリックすると、localhost形式のURLからメールが届いてしまい、ユーザー認証ができませんでした。 2. 関連していそうなソースコードの見直し config/environments/production.rb Rails.application.configure do # 本番環境用 config.file_watcher = ActiveSupport::EventedFileUpdateChecker config.action_mailer.default_url_options = { host: 'サブドメイン名(アプリ名).herokuapp.com', protocol: 'https' } config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, user_name: ENV['USER_EMAIL'], password: ENV['EMAIL_PASSWORD'], authentication: 'plain', enable_starttls_auto: true } end production.rbの設定に間違いはなさそうなのに、なぜかlocalhostへ遷移される状態になってしまっておりました。 3. 問題にぶつかる前に、アプリをどうやってデプロイしたのか heroku container:login heroku container:push web -a アプリ名 heroku addons:attach postgresql名 -a アプリ名 heroku run rake db:migrate -a アプリ名 heroku open -a アプリ名 https://qiita.com/NA_simple/items/57ad10717568fea2160b こちらの記事を参考にデプロイを実行。 サインインをトライして到着したメールに記載のURLをクリックすると、 http://localhost:3000/users/confirmation?confirmation_token=.... に遷移されてユーザー認証ができませんでした。 実際に「メールアドレス確認」をクリックして認証を完了させようとすると、 http://localhost:3000/users/confirmation?confirmation_token=.... というURLに飛ばされてしまいました。 しかしそれでは実際にアプリが使えないので、 http://アプリドメイン名/users/confirmation?confirmation_token=.... になることを望んでいました。 4.解決方法 そもそもdockerfileの設定に間違いの原因がありました。 FROM ruby:2.6.5 RUN apt-get update -qq && apt-get install -y nodejs postgresql-client RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 ENV LANG C.UTF-8 # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"] 最後のCMD ["rails", "server", "-b", "0.0.0.0"]が原因でした。 デプロイする際、このコマンドは開発環境を実行するという意味になっており、開発環境をデプロイしてしまっている。ということがわかりました。何を意味するのかというと、production.rbをいくら編集しても、本番環境をデプロイしていないため何の意味もなさなかったということになります。 今回の場合はdevelopments.rbを編集してやり過ごすことにしました。 deveopment.rb Rails.application.configure do # 本番環境用 config.file_watcher = ActiveSupport::EventedFileUpdateChecker #編集前 #config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } #編集後 config.action_mailer.default_url_options = { host: 'サブドメイン名(アプリ名).herokuapp.com', protocol: 'https' } config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, user_name: ENV['USER_EMAIL'], password: ENV['EMAIL_PASSWORD'], authentication: 'plain', enable_starttls_auto: true } end 上記development.rbの config.action_mailer.default_url_optionsを本番用のものに編集し直しました。 その場凌ぎにはなりますが、メイラーを送信するデフォルトのドメインをlocalhostから本番環境のドメイン名に変更しました。 このように修正して再度デプロイをし直し、ユーザー認証メールのURLをクリックしたら無事に本番環境のドメインに遷移されてユーザー認証を成功させることができました。 デプロイはエラーが付きまとうので大変と感じる人も多いと思います。 私も久しぶりにデプロイし、今回のエラーにぶつかってしまいました。実際skypeを繋ぎながら記事を参考に試しましたがなかなかうまくいかず、現場のエンジニアの知り合いに知恵を貸していただいて解決しました。正直dockerもherokuもrailsも知識が足りておらず、まだまだ勉強不足だなと痛感しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPとVue.jsを使って「本のレンタルアプリ」を作成した話

はじめに PHPとVue.jsを使った「本のレンタルアプリケーション」を作成した時の話や、構成をまとめてみました。 Web系のプログラミングを大方学んでみて、実際に何か作ってみようと考えている人や、複数のプログラミングや技術を合わせて使ったことのない人に参考にしていただければと思います。 PHPとVue.jsでなくても、RubyやjQueryなどでも代用はできますし、どちらかといえば環境構築やデータベースの構成のほうをメインに書いています。 図書レンタルアプリを作った理由 今回この図書レンタルアプリを作ろうと思ったのは、一から一人だけで、サービスを作る経験を積んでおきたかったからです。 業務では基本的に分業が多く、フロントエンドとバックエンドで別れてサービスを構築するのが基本で、新しくサービスを一から作る機会自体少ないです。 基本は現状あるサービスの改修や、修正がメインのため、一からサービスをコンスタントに作って、場数を踏みたいと思ったのがきっかけです。 そして何を作ろうかと考えたときに、会社の本棚の本の管理ができていなかったので、誰が何をいつまで借りているのかや、本のレンタル履歴を管理できるアプリケーションを作ってみようと思ったのがきっかけです。 使用した技術 使用した技術 PHP Vue.js MySQL Docker アプリを作り始めた時の自分のスキルレベル javascript javascriptは実務でもメインで使っているため、問題なくかけるレベルです。 ライブラリーやフレームワークにつては、jQueryとVue.jsが使えました。 jQueryは結構知識はありましたが、Vue.jsの経験は少なめでした。 Vue.js Vue-CLI、vue-router、VueXの基礎知識をudemyの動画を通して学んだくらいです。 仕事ではVueファイル形式で書いたことはなく、今回Vueファイル形式で、ビルドする書き方ははじめてでした。 PHP PHPも実務での経験は少なく、PHPで一からサービスを作ったことはありませんでした。 実務で、今あるサービスの改修や修正、機能追加などでPHPを触るくらいの経験しか有りませんでした。 Docker Docker関しては、完全に初めてで、素人でした。 それまではVirtualBoxでlinuxの環境を作って、開発を行っていました。 なのでlinuxコマンドなどの知識はある前提です。 スキルレベルのまとめ 一応現役のエンジニアではありますが、基本的に一からのサービス構築の経験は少なく、あってもメインで携わって来たのはフロント側のみで、バックエンドやインフラはすでに構築されているものを少し触るくらいの経験しか積んできませんでした。 キャリア的にももっと経験を積まないとまずいと思い、ここらで一気に経験を積みたいと思い、とりあえず「PHP」「Vue.js」「MySQL」「Docker」この辺の技術を使って、一人で一から簡単なサービスを作るところから始めようと思いました。 図書レンタルアプリの機能 バックエンドとユーザー登録、ログインのページはPHP それ以外のフロントエンドはVue.jsで作成しました。 実装する機能のリスト ・ユーザー登録機能 ・ログイン機能 ・ログアウト機能 ・レンタル機能 ・レンタル状況確認機能 ・返却機能 ・返却期限編集機能 ・ユーザー情報編集機能 ・ランキング機能 ・本の登録機能 アプリのデザインについて 普段の業務で自分であまり使わないのですが、デザインを作成するのにXDを使い、簡単にデザインを作成しました。 今回はXDのスキルではなく、Web開発のエンジニアスキルを高めたかったので、デザインはなるべくシンプルにしました。 もともとミニマムなデザインが好きなので、色もモノトーンベースにしています。 PHPで作成した「ユーザー登録ページ」と「ログインページ」     Vue.jsで作成したシングルページアプリケーション(SPA)      データベースについて データベースはMySQLを使用しました。 MySQLにlibraryというデータベースを作成し、その中に「members」「book」というテーブルを作成しました。 データベースの構成と役割 データベース:library   テーブル   └book   └members book bookには本の情報を保存します。 book_id:本を識別するID title:本のタイトル status:本がレンタル中or在庫あるか rental_id:レンタルされている場合はmemberのid、レンタルされていない場合はNULL date_rimit:レンタルされている場合はレンタル期限、レンタルされていない場合はNULL category:本のカテゴリー tag:本の検索に使うtag count:レンタルされた回数 created_at:本が登録された日付 members membersにはアプリを使用する人のログイン情報や、レンタルしている本のidのリストを保存します。 id:ユーザーを識別するID name:ユーザーの名前 mail:ユーザーのメールアドレス password:ログインするためのパスワード created:ユーザー登録した日付 rental_list:現在レンタルしている本のbook_idのリスト 各ファイルの役割 PHPについて PHPでCRUD機能を実装しました。 ユーザーの登録機能(Create) ユーザのログイン機能(Read) ユーザー、本の管理機能(Read) ユーザー、本の情報書き換え(Update) ※Dleteに当たる機能は今回有りませんでした。 Vue.jsで作成したSPAから、本を検索したり、レンタルしたりするときにPHPを動かす必要がありますが、axiosを使い通信を行いました。 Vue.jsについて ※この話はVue.jsを学んでいる人ならわかると思いますが、Vue.jsに興味がない場合は飛ばしてください Vuejsで作成したSPAのページはタブ構成になっており、タブの切替はVue-routerを使って、urlを切り替えてタブ機能を実装しています。 各タブの中のページの切り替え(例えば、レンタルタブの中で、本を検索したり、本をレンタルする際にページの切り替え)は、動的コンポーネントで表示を切り替えています。 レンタルタブ      状況タブ(レンタル状況と返却) Dockerでの環境構築 今回は開発環境としてはDockerでLAMP環境を構築することにしました。 Docker-composeを使って、複数のコンテナをたててLAMPを構築しました。 参考までにymlファイルと、dockerファイルを公開しておきます。 yml version: "3.7" services: mysql: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: "password" phpmyadmin: depends_on: - mysql image: phpmyadmin/phpmyadmin environment: PMA_HOST: mysql restart: always ports: - "8080:80" php-apache: build: ./php volumes: - ./htdocs:/var/www/html restart: always ports: - "80:80" depends_on: - mysql volumes: db_data: {} ./phpの直下に書きを保存 dockerfile FROM php:7.3-apache COPY ./php.ini /usr/local/etc/php/ COPY ./apache2.conf /etc/apache2/ COPY ./sites/*.conf /etc/apache2/sites-available/ RUN apt-get update \ && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev \ && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv 上記のファイルで下記のコマンドを実行すれば、LAMP環境が立ち上がります。 terminal docker-compose up -d Dockerでの環境構築で困ったこと 今回一番困ったのがDockerで作ったapacheの設定です。 私も初めて知ったのですが、公式で公開されている「php:7.3-apache」などのApacheは、あくまでphpが動くだけのapacheの環境しか用意していないため、普通のapacheの環境でデフォルトで設定されているようなものは、デフォルトで入っていないことがあります。 今回ハマったのが、Rewriteのモジュールです。 Vue-routerを使った時に、historyモードを使用していると、リロードした時に404エラーが出てしまいます。これはVueの公式にも記載されています。 それを回避するために、apacheの設定ファイルか、.htaccessでRewriteの設定をする必要があるのですが、そのためのモジュールがapacheにはありませんでした。 それに気づかずに、設定ファイルにRewriteの記述を書いても問題が解決せずにいました。 今回の場合は、それをphp:7.3-apacheに入り、インストールして解決しましたが、本来であれば、Dockerfileにそれを記載しておく必要があります。 そうしないと次回コンテナを新しく立ち上げた時に、また、同じことをしないといけないからです。 かなり勉強になりました。 アプリケーションを作ってみた感想 今回一番新しい試みだったのが、Vue.js(Vuex、Vue-router)とDockerでの開発でしたが、初めてだったので、ディレクトリ構造などが少し納得できるくらい整理ができず、本当は記事にして、詳細まで説明しようと思っていたのですが、できませんでした。 ただ、一度作ってみることで、ディレクトリ構造以外にも、設計やデータベースの構成など、ワンストップで開発しないと経験できないことを多く学ぶことができました。 やはり部分的に開発しているだけでは、見えていないことや、自分のスキルとして足りていないことが多くあることを発見でき、やってみてよかったと思いました。 AWSの使用について(余談) ちょっと今回の話に関係ないののですが、少し話をさせてください。 このアプリを作る際に、本番のアップロード先について最初はAWSで、VPCとEC2を使ってネットワークとサーバーを立てて、そこで公開しようと思っていました。 ですが、この手のアプリケーションを作る時に、流行っているからというだけでAWSを使うのはちょっと違うと考えました。 特に初学者の人は手を出しやすい場所だと思うのですが、AWSは基本的に従量課金のため、サーバーが動いている分だけ料金が課金されていきます。 lamdaなどを使って、アプリケーションが動くときだけ稼働させるなどの工夫をすればいいのですが、割と初学者にとってはハードルが高いため、最初はおすすめしません。 もちろんAWSの技術をみにつける目的があるのであれば、試すのもありですが、今回はインフラ周りというよりも動くものを作るのが目的だったので、さくらサーバーなどのレンタルサーバーを使用しました。 というのも会社で使うアプリケーションのため、サーバーやAWSは会社のものを使うので、コストは最小限に抑える必要があったからです。 プログラミングを学ぶときにはこういったコストのことも考えながら作ると、より実践向きのエンジニアに成長できると思うので、今回関係ないですが、この話をはさみました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-ceをRHEL8へインストール

docker-ceをインストールしたのでメモ OSバージョン確認 # cat /etc/redhat-release Red Hat Enterprise Linux release 8.3 (Ootpa) リポジトリを追加 # dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo Updating Subscription Management repositories. repo の追加: https://download.docker.com/linux/centos/docker-ce.repo リポジトリの有効を確認 # dnf repolist -v ロードされたプラグイン: builddep, changelog, config-manager, copr, debug, debuginfo-install, download, generate_completion_cache, needs-restarting, playground, product-id, repoclosure, repodiff, repograph, repomanage, reposync, subscription-manager, uploadprofile Updating Subscription Management repositories. DNF version: 4.2.23 cachedir: /var/cache/dnf Docker CE Stable - x86_64 9.1 kB/s | 14 kB 00:01 Repo-id : docker-ce-stable Repo-name : Docker CE Stable - x86_64 Repo-revision : 1622662057 Repo-updated : 2021年06月03日 04時27分37秒 Repo-pkgs : 38 Repo-available-pkgs: 38 Repo-size : 937 M Repo-baseurl : https://download.docker.com/linux/centos/8.3/x86_64/stable Repo-expire : 172,800 秒 (最終: 2021年06月06日 18時05分46秒) Repo-filename : /etc/yum.repos.d/docker-ce.repo Repo-id : rhel-8-for-x86_64-appstream-rpms Repo-name : Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs) Repo-revision : 1620325306 Repo-updated : 2021年05月07日 03時21分46秒 Repo-pkgs : 15,987 Repo-available-pkgs: 14,123 Repo-size : 38 G Repo-baseurl : https://cdn.redhat.com/content/dist/rhel8/8.3/x86_64/appstream/os Repo-expire : 86,400 秒 (最終: 2021年06月06日 15時11分00秒) Repo-filename : /etc/yum.repos.d/redhat.repo Repo-id : rhel-8-for-x86_64-baseos-rpms Repo-name : Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs) Repo-revision : 1620884120 Repo-updated : 2021年05月13日 14時35分17秒 Repo-pkgs : 6,704 Repo-available-pkgs: 6,285 Repo-size : 9.8 G Repo-baseurl : https://cdn.redhat.com/content/dist/rhel8/8.3/x86_64/baseos/os Repo-expire : 86,400 秒 (最終: 2021年06月06日 15時11分01秒) Repo-filename : /etc/yum.repos.d/redhat.repo 総パッケージ: 22,729 docker-ceのパッケージを確認 # dnf list docker-ce --showduplicates | sort -r 利用可能なパッケージ メタデータの期限切れの最終確認: 0:03:35 時間前の 2021年06月06日 18時05分46秒 に実施しました。 docker-ce.x86_64 3:20.10.7-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.6-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.5-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.4-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.3-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.2-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.1-3.el8 docker-ce-stable docker-ce.x86_64 3:20.10.0-3.el8 docker-ce-stable docker-ce.x86_64 3:19.03.15-3.el8 docker-ce-stable docker-ce.x86_64 3:19.03.14-3.el8 docker-ce-stable docker-ce.x86_64 3:19.03.13-3.el8 docker-ce-stable Updating Subscription Management repositories. docker-ceをインストール # dnf install docker-ce-3:20.10.7-3.el8 Updating Subscription Management repositories. メタデータの期限切れの最終確認: 0:01:03 時間前の 2021年06月06日 18時11分12秒 に実施しました。 依存関係が解決しました。 ============================================================================================================================================================================================= パッケージ アーキテクチャー バージョン リポジトリー サイズ ============================================================================================================================================================================================= インストール: docker-ce x86_64 3:20.10.7-3.el8 docker-ce-stable 27 M 依存関係のインストール: container-selinux noarch 2:2.155.0-1.module+el8.3.1+9857+68fb1526 rhel-8-for-x86_64-appstream-rpms 51 k containerd.io x86_64 1.4.6-3.1.el8 docker-ce-stable 34 M docker-ce-cli x86_64 1:20.10.7-3.el8 docker-ce-stable 33 M docker-ce-rootless-extras x86_64 20.10.7-3.el8 docker-ce-stable 9.2 M docker-scan-plugin x86_64 0.8.0-3.el8 docker-ce-stable 4.2 M fuse-overlayfs x86_64 1.3.0-2.module+el8.3.1+9857+68fb1526 rhel-8-for-x86_64-appstream-rpms 72 k fuse3 x86_64 3.2.1-12.el8 rhel-8-for-x86_64-baseos-rpms 50 k fuse3-libs x86_64 3.2.1-12.el8 rhel-8-for-x86_64-baseos-rpms 94 k libslirp x86_64 4.3.1-1.module+el8.3.1+9803+64eb0fd6 rhel-8-for-x86_64-appstream-rpms 69 k slirp4netns x86_64 1.1.8-1.module+el8.3.1+9857+68fb1526 rhel-8-for-x86_64-appstream-rpms 51 k モジュールストリームの有効化中: container-tools rhel8 トランザクションの概要 ============================================================================================================================================================================================= インストール 11 パッケージ ダウンロードサイズの合計: 107 M インストール済みのサイズ: 438 M これでよろしいですか? [y/N]: y パッケージのダウンロード: (1/11): containerd.io-1.4.6-3.1.el8.x86_64.rpm 4.4 MB/s | 34 MB 00:07 (2/11): docker-ce-cli-20.10.7-3.el8.x86_64.rpm 4.0 MB/s | 33 MB 00:08 (3/11): docker-scan-plugin-0.8.0-3.el8.x86_64.rpm 2.4 MB/s | 4.2 MB 00:01 (4/11): docker-ce-rootless-extras-20.10.7-3.el8.x86_64.rpm 3.2 MB/s | 9.2 MB 00:02 (5/11): fuse-overlayfs-1.3.0-2.module+el8.3.1+9857+68fb1526.x86_64.rpm 231 kB/s | 72 kB 00:00 (6/11): slirp4netns-1.1.8-1.module+el8.3.1+9857+68fb1526.x86_64.rpm 267 kB/s | 51 kB 00:00 (7/11): container-selinux-2.155.0-1.module+el8.3.1+9857+68fb1526.noarch.rpm 227 kB/s | 51 kB 00:00 (8/11): libslirp-4.3.1-1.module+el8.3.1+9803+64eb0fd6.x86_64.rpm 378 kB/s | 69 kB 00:00 (9/11): fuse3-libs-3.2.1-12.el8.x86_64.rpm 472 kB/s | 94 kB 00:00 (10/11): fuse3-3.2.1-12.el8.x86_64.rpm 299 kB/s | 50 kB 00:00 (11/11): docker-ce-20.10.7-3.el8.x86_64.rpm 1.8 MB/s | 27 MB 00:14 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 合計 7.1 MB/s | 107 MB 00:14 警告: /var/cache/dnf/docker-ce-stable-97480ff917a24d63/packages/containerd.io-1.4.6-3.1.el8.x86_64.rpm: ヘッダー V4 RSA/SHA512 Signature、鍵 ID 621e9f35: NOKEY Docker CE Stable - x86_64 29 kB/s | 1.6 kB 00:00 GPG 鍵 0x621E9F35 をインポート中: Userid : "Docker Release (CE rpm) <docker@docker.com>" Fingerprint: 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35 From : https://download.docker.com/linux/centos/gpg これでよろしいですか? [y/N]: y 鍵のインポートに成功しました トランザクションの確認を実行中 トランザクションの確認に成功しました。 トランザクションのテストを実行中 トランザクションのテストに成功しました。 トランザクションを実行中 準備 : 1/1 インストール : docker-scan-plugin-0.8.0-3.el8.x86_64 1/11 scriptletの実行中: docker-scan-plugin-0.8.0-3.el8.x86_64 1/11 インストール : docker-ce-cli-1:20.10.7-3.el8.x86_64 2/11 scriptletの実行中: docker-ce-cli-1:20.10.7-3.el8.x86_64 2/11 scriptletの実行中: container-selinux-2:2.155.0-1.module+el8.3.1+9857+68fb1526.noarch 3/11 インストール : container-selinux-2:2.155.0-1.module+el8.3.1+9857+68fb1526.noarch 3/11 scriptletの実行中: container-selinux-2:2.155.0-1.module+el8.3.1+9857+68fb1526.noarch 3/11 インストール : containerd.io-1.4.6-3.1.el8.x86_64 4/11 scriptletの実行中: containerd.io-1.4.6-3.1.el8.x86_64 4/11 インストール : fuse3-3.2.1-12.el8.x86_64 5/11 インストール : fuse3-libs-3.2.1-12.el8.x86_64 6/11 scriptletの実行中: fuse3-libs-3.2.1-12.el8.x86_64 6/11 インストール : fuse-overlayfs-1.3.0-2.module+el8.3.1+9857+68fb1526.x86_64 7/11 scriptletの実行中: fuse-overlayfs-1.3.0-2.module+el8.3.1+9857+68fb1526.x86_64 7/11 インストール : libslirp-4.3.1-1.module+el8.3.1+9803+64eb0fd6.x86_64 8/11 インストール : slirp4netns-1.1.8-1.module+el8.3.1+9857+68fb1526.x86_64 9/11 インストール : docker-ce-rootless-extras-20.10.7-3.el8.x86_64 10/11 scriptletの実行中: docker-ce-rootless-extras-20.10.7-3.el8.x86_64 10/11 インストール : docker-ce-3:20.10.7-3.el8.x86_64 11/11 scriptletの実行中: docker-ce-3:20.10.7-3.el8.x86_64 11/11 scriptletの実行中: container-selinux-2:2.155.0-1.module+el8.3.1+9857+68fb1526.noarch 11/11 scriptletの実行中: docker-ce-3:20.10.7-3.el8.x86_64 11/11 検証 : containerd.io-1.4.6-3.1.el8.x86_64 1/11 検証 : docker-ce-3:20.10.7-3.el8.x86_64 2/11 検証 : docker-ce-cli-1:20.10.7-3.el8.x86_64 3/11 検証 : docker-ce-rootless-extras-20.10.7-3.el8.x86_64 4/11 検証 : docker-scan-plugin-0.8.0-3.el8.x86_64 5/11 検証 : fuse-overlayfs-1.3.0-2.module+el8.3.1+9857+68fb1526.x86_64 6/11 検証 : container-selinux-2:2.155.0-1.module+el8.3.1+9857+68fb1526.noarch 7/11 検証 : slirp4netns-1.1.8-1.module+el8.3.1+9857+68fb1526.x86_64 8/11 検証 : libslirp-4.3.1-1.module+el8.3.1+9803+64eb0fd6.x86_64 9/11 検証 : fuse3-libs-3.2.1-12.el8.x86_64 10/11 検証 : fuse3-3.2.1-12.el8.x86_64 11/11 Installed products updated. インストール済み: container-selinux-2:2.155.0-1.module+el8.3.1+9857+68fb1526.noarch containerd.io-1.4.6-3.1.el8.x86_64 docker-ce-3:20.10.7-3.el8.x86_64 docker-ce-cli-1:20.10.7-3.el8.x86_64 docker-ce-rootless-extras-20.10.7-3.el8.x86_64 docker-scan-plugin-0.8.0-3.el8.x86_64 fuse-overlayfs-1.3.0-2.module+el8.3.1+9857+68fb1526.x86_64 fuse3-3.2.1-12.el8.x86_64 fuse3-libs-3.2.1-12.el8.x86_64 libslirp-4.3.1-1.module+el8.3.1+9803+64eb0fd6.x86_64 slirp4netns-1.1.8-1.module+el8.3.1+9857+68fb1526.x86_64 完了しました! containerd.ioパッケージがインストールされていることを確認 # rpm -qa containerd.io* containerd.io-1.4.6-3.1.el8.x86_64 firewallは無効であることを確認 # systemctl status firewalld.service ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1) Dockerデーモンを起動して有効にする # systemctl enable --now docker Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service. # systemctl status docker.service ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2021-06-06 18:25:54 JST; 1min 38s ago Docs: https://docs.docker.com Main PID: 6220 (dockerd) Tasks: 10 Memory: 50.7M CGroup: /system.slice/docker.service mq6220 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock dockerのバージョンを確認 # docker --version Docker version 20.10.7, build f0df350 Dockerインストールのテスト # docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world b8dfde127a29: Pull complete Digest: sha256:5122f6204b6a3596e048758cabba3c46b1c937a46b5be6225b835d091b90e46c Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ マシン上にダウンロードしたhello-worldイメージが一覧にあるかどうか確認 # docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest d1165f221234 3 months ago 13.3kB メッセージを表示して終了したhello-worldコンテナ(イメージから生成)が一覧にあるかを確認 # docker ps --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2983356c7a93 hello-world "/hello" 15 minutes ago Exited (0) 7 minutes ago loving_curie 作成したコンテナを削除 # docker rm loving_curie loving_curie # docker images REPOSITORY TAG IMAGE ID CREATED SIZE 以上ここまで 参考 ・RHEL 8 / CentOS 8にDocker CEをインストールする方法 https://goto-linux.com/ja/2020/3/20/rhel-8-/-centos-8%E3%81%ABdocker-ce%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/ ・Docker-docs-ja http://docs.docker.jp/get-started/index.html
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Deskopを使ってGitLabを立ててみた

はじめに はじめてDockerに触れてみます。Docker Desktopを使ってGitLabを構築してみました。 今回は初めてなので、違いを知るためにコンテナ単体とcomposeと2パターンで試してみましたが 複数のコンテナを連携できて便利なので、今後はcomposeを使っていこうと思っています。 環境 Windowsのバージョン エディション:Windows 10 Home バージョン :20H2 OSビルド  :19042.928 Dockerのバージョン PS C:\Users\xxx> docker version Client: Cloud integration: 1.0.14 Version: 20.10.6 API version: 1.41 Go version: go1.16.3 Git commit: 370c289 Built: Fri Apr 9 22:49:36 2021 OS/Arch: windows/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.6 API version: 1.41 (minimum version 1.12) Go version: go1.13.15 Git commit: 8728dd2 Built: Fri Apr 9 22:44:56 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.4 GitCommit: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e runc: Version: 1.0.0-rc93 GitCommit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec docker-init: Version: 0.19.0 GitCommit: de40ad0 Docker Composeのバージョン PS C:\Users\xxx> docker-compose version docker-compose version 1.29.1, build c34c88b2 docker-py version: 5.0.0 CPython version: 3.9.0 OpenSSL version: OpenSSL 1.1.1g 21 Apr 2020 手順(コンテナ単体版) 流れ gitlab-ceイメージの取得 取得したイメージを使って、コンテナの作成と起動 しばらく待ってから、GitLabへアクセス gitlab-ceイメージの取得 実行するコマンド:docker pull gitlab/gitlab-ce:latest gitlab/gitlab-ceはイメージ名、コロンに続くlatestがタグになります。 どんなタグがあるかというと、「Docker Hub」に載ってます。 PS C:\Users\xxx> docker pull gitlab/gitlab-ce:latest latest: Pulling from gitlab/gitlab-ce 345e3491a907: Pull complete ~~省略~~ a5e82faf9eb6: Pull complete Digest: sha256:3421d0b39f305bacf63176bf73760fe1352f352472c6f02e7a6b4b19365d73d6 Status: Downloaded newer image for gitlab/gitlab-ce:latest docker.io/gitlab/gitlab-ce:latest 取得したイメージを使って、コンテナの作成と起動 フォーマット:docker run [オプション] イメージ名 [コマンド] [引数...] 実行するコマンド:docker run -d -p 8080:80 --name gitlab gitlab/gitlab-ce:latest -dはデタッチ。バックグラウンド起動です。 -p 8080:80でHostの8080ポートを、コンテナの80ポートに割り当てています。 --name gitlabは、起動するコンテナにgitlabという名前をつけています。 PS C:\Users\xxx> docker run -d -p 8080:80 --name gitlab gitlab/gitlab-ce:latest 33a2cdb39603140ac9c0bed339bf500a8063a1edad483d5e794a1f1adad73ea7 コンテナのステータスを確認すると、Hostの8080ポートがコンテナの80ポートに割り当たっていることや NAMESがgitlabになっていることが確認できます。 PS C:\Users\xxx> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 33a2cdb39603 gitlab/gitlab-ce:latest "/assets/wrapper" 19 seconds ago Up 17 seconds (health: starting) 22/tcp, 443/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp gitlab P 手順(docker compose版) 次はdocker composeを使った手順です。 docker composeとは docker composeとは、複数のコンテナからなるサービスを構築をする機能です。 docker-compose.ymlというファイルを用意して、コンテナごとに定義を用意してやり docker-compose up -dを実行するだけで起動できます。 今回はgitlabの単一コンテナを例にした手順ですが、ゆくゆくgitlab runnerコンテナと連携して CI/CDできる環境を構築するつもりなので、そういった時にdocker composeは便利になります。 流れ docker-compose.ymlの用意 イメージの取得と、コンテナの作成と起動 ブラウザでアクセス docker-compose.ymlの用意 docker-compose.ymlは、「ここ」に用意されています。 ほぼそのままですが、portを変更しています。 web: image: 'gitlab/gitlab-ce:latest' restart: always hostname: 'gitlab.example.com' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'https://gitlab.example.com' ports: - '8080:80' - '443:443' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab' ディレクトリ構成はこんな感じ PS D:\xxx\docker\gitlab> ls ディレクトリ: D:\xxx\docker\gitlab Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 2021/05/16 15:48 368 docker-compose.yml DockerComposeの状態確認 docker-compose psを実行して確認します。 まだ作成も起動もしていないので、何も現れません。 PS D:\xxx\docker\gitlab> docker-compose ps -a Name Command State Ports ------------------------------ コンテナの作成と起動 docker-compose up -dを実行します。 もし、イメージを取得してなければ、自動で取得してくれます。 (実行例) docker-compose up -d Docker Compose is now in the Docker CLI, try `docker compose up` Pulling web (gitlab/gitlab-ce:latest)... latest: Pulling from gitlab/gitlab-ce a70d879fa598: Pull complete (中略) f02a0cd519df: Pull complete Digest: sha256:526e5d4da70f1b19ca4b95e431b8383d42c1cae21af0a002331cbf3650a2e8d9 Status: Downloaded newer image for gitlab/gitlab-ce:latest Creating docker_web_1 ... done DockerComposeの状態確認 起動したコンテナが現れました。 (実行例) docker-compose ps -a Name Command State Ports ----------------------------------------------------------------------------------------------------------------------- docker_web_1 /assets/wrapper Up (health: starting) 0.0.0.0:22->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8080->80/tcp ブラウザでアクセス 数分待ってから、localhostにアクセス どういうわけか443ポートだと接続できるんですが 8080ポートだとERR_EMPTY_RESPONSEとなって接続できない。 気が向いたら後日調べてみようと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(こんな原因も) vagrant@127.0.0.1: permission denied (publickey)の解決方法

はじめに 普段はDocker Desktopを利用している私ですが、久しぶりにVagrantを利用して環境構築を行いました。 Vagrant+VirtualBoxでUbuntuの環境を構築して、vagrant sshで仮想環境に入ったところエラーに遭遇しました。 色々調べたところ、解決方法がなく自力で解決してこういう原因もあるなと感じ、まとめます。 該当する人はかなり少ないかと思いますが、助かる人がいれば幸いです。 環境 VirtualBox 6.1 Vagrant 2.2.16 Vscode 問題 以下の記事通りに環境構築を行いました。 その後、vagrant up、vagrant sshをしたところ以下のエラーが発生しました。 vagrant@127.0.0.1: permission denied (publickey) そして以下の記事など確認して対処していましたが、どうも違いました。 解決方法 VirtualBoxやVagrantをインストールした場所とVagrantfileのディレクトリの場所が違うことが原因でした。 具体的には私のPCはドライブが2つあり、 VirtualBoxとVagrantはCドライブにインストール vagrantfileはDドライブ この状況が、権限のエラーにつながっていました。 ですので、Cドライブにvagrantfileを移動して、vagrant upとvagrant sshをすることでssh接続することに成功しました。 おわりに 設定すればドライブが異なっても大丈夫かと思われます。 今回はそこまでは試していませんが、 この記事でうまく設定すればできるかと思います。 珍しいパターンでしたので今回はまとめてみました。 このパターンだったという人がもしいたらコメントやLGTMお願いします! 参考記事 vagrant@127.0.0.1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic). Vagrant up/sshに失敗したときの対処法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails6】DockerでRails6の開発環境構築【ゼロからデプロイまで】

概要 Dockerでrails6の開発環境を作成し、簡単なCRUD機能を実装してからHerokuへとデプロイするまでの手順を紹介します。 前提条件 Dockerの各コマンドを利用できる状態になっている。 Herokuのユーザー登録が完了し、ブラウザでログインすることができる。 HerokuCLIを利用できる状態になっている。 【1】 環境構築編 必要ファイルのセットアップ 本記事ではdocker-qiita-onikiという名前でRailsアプリケーションを設定しますが、この部分はお好きなアプリケーションの名前に書き換えてください。 まずは下記のようにアプリケーションの名前でディレクトリを用意し、各種ファイルを作成します。 $ mkdir docker-qiita-oniki $ cd docker-qiita-oniki $ touch Dockerfile Gemfile Gemfile.lock docker-compose.yml entrypoint.sh 各種ファイルをテキストエディタで開いて下記のように記載してください。 ※ docker-qiita-onikiはお好きなアプリケーション名に書き換えです! 1. Dockerfile Dockerfile FROM ruby:2.7.3 ENV LANG C.UTF-8 ENV DEBCONF_NOWARNINGS yes ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE yes EXPOSE 3000 RUN apt-get update -qq && apt-get install -y build-essential postgresql-client libpq-dev RUN apt-get update && apt-get install -y curl apt-transport-https wget && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -y yarn RUN mkdir /docker-qiita-oniki WORKDIR /docker-qiita-oniki COPY Gemfile /docker-qiita-oniki/Gemfile COPY Gemfile.lock /docker-qiita-oniki/Gemfile.lock RUN bundle install COPY . /docker-qiita-oniki COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 CMD ["rails", "server", "-b", "0.0.0.0"] 2. docker-compose.yml docker-compose.yml version: '3' services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: POSTGRES_HOST_AUTH_METHOD: 'trust' web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/docker-qiita-oniki ports: - "3000:3000" depends_on: - db 3. entrypoint.sh entrypoint.sh #!/bin/bash set -e rm -f /docker-qiita-oniki/tmp/pids/server.pid exec "$@" 4. Gemfile Gemfile source "https://rubygems.org" gem "rails", "~>6.1.3" ※ Gemfile.lockは記載の必要なし(空のまま) 5. 確認 これでDockerにRails環境を構築するために必要な設定は揃いました。下記のようなディレクトリ構成になったことを確認してください。 docker-qiita-oniki ├── Dockerfile ├── docker-compose.yml ├── entrypoint.sh ├── Gemfile └── Gemfile.lock コンテナのビルド 必要ファイルを用意したディレクトリでコンテナの起動準備に必要なコマンドを実行していきます。 まずはRailsの新規作成をします。 $ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle お馴染みのRailsファイル達が作成されたことを確認してください。 docker-qiita-oniki ├── app ├── bin ├── config ├── db ├── lib ├── log ├── public ├── storage ├── test ├── tmp ├── vendor ├── .gitattributes ├── .gitignore ├── .ruby-version ├── config.ru ├── docker-compose.yml ├── Dockerfile ├── entrypoint.sh ├── Gemfile ├── Gemfile.lock ├── package.json ├── Rakefile └── README.md 必要なファイルが揃ったことを確認したらビルドします。(時間がかかります) $ docker-compose build DBの作成 config/database.ymlにPostgreSQLに接続するための設定を追記します。 config/database.yml ~ ~ default: &default adapter: postgresql encoding: unicode # For details on connection pooling, see Rails configuration guide # https://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> ### 下記を追記 host: db username: postgres passowrd: ### 上記を追記 development: <<: *default database: docker_qiita_oniki_development ~ ~ 以下のコマンドでDBを作成します。 $ docker-compose run web rake db:create Webpackerインストール Rails6から標準装備となったWebpackerを下記のコマンドによりインストールします(時間がかかります)。 $ docker-compose run web rails webpacker:install コンテナの起動 必要な準備が揃ったので いよいよコンテナを起動してRailsのスタートページを表示していきましょう。 docker-compose up ブラウザからhttp://localhost:3000/にアクセスしてみましょう、無事にRailsのスタートページ「Yay! You’re on Rails!」が表示されましたでしょうか?確認後、起動したコンテナを停止するときは[Ctrl] + [C]を押してください。 ここまでで【1】環境構築編は終了です。お疲れ様でした。 【2】 CRUDアプリケーション作成編 せっかくRailsの環境構築をしたので簡単なCRUDアプリケーションを作成しましょう。 と言っても、本記事はあくまでDockerの環境構築とHeorkuへのデプロイがメインなのでここはRailsの便利機能scaffoldを使ってサクッと進めてしまいます。 停止している場合は、再度コンテナを起動します。 docker-compose up Rails開発を進めるためにDocker環境でRailsコマンドを入力する方法はいくつかあるのですが、今回はDocker起動用のターミナル1つ残しておき、もう一つターミナルを立ち上げるスタイルで進めたいと思います。 ターミナル上で[command] + [T]を押して2つ目のターミナルを開いてください。 この状態で、コマンド入力可能な方のターミナルで下記の2つのコマンドを入力すると、タイトル(titile)と本文(body)の要素を持つタスク(Task)を投稿できるRailsアプリケーションが出来上がります。 $ docker-compose exec web rails g scaffold Task title:string body:text $ docker-compose exec web rails db:migrate DBのマイグレーションを行なったため、一度コンテナを再起動したいと思います。 Docker起動用のターミナルの方で[Command]+[C]で停止、docker-compose upで起動、という手順で再起動をかけたあと、http://localhost:3000/tasksにアクセスしましょう。Taskを作成/編集/削除/閲覧できる機能が実装されていることが確認できるはずです。 ただし、このままだとRailsのroot(http://localhost:3000で表示されるページ)が「Yay! You’re on Rails!」のままですので、これもタスクの一覧ページにしてしましょう。 config/routes.rbを開くとscaffoldによりresources :tasksの記載があるはずなので、その上にroot 'tasks#index'を追加してください。 config/routes.rb Rails.application.routes.draw do root 'tasks#index' resources :tasks end これにより、http://localhost:3000にアクセスしてもタスク一覧のページが表示されるようになります。 ここまでで【2】CRUDアプリケーション作成編は終了です。次はいよいよHerokuへのデプロイを行っていきます。ここから先の内容に入る前にコンテナを起動している方は停止を忘れずにお願いします。 【3】 Herokuデプロイ編 それではいよいよここまで作成してきたRailsアプリケーションをHerokuへデプロイしていきます。本記事での内容は全て無料枠でできることになりますので、課金はされることはありません。 1. HerokuコンソールでCreate new app https://jp.heroku.com/にアクセスし、ご自身のHerokuコンソールへとログインしてください。画面右上の[New]というタブで[Create new app]を選択します。 お好きな名前(https://XXXXXXXXXX.herokuapp.com/←XXXXXXXXXXの部分に反映されます!)を入力し、RegionはUnited Statesを選択したまま[Create App]ボタンをクリックしてください。これでアプリケーションのデプロイ先が作成されました。 2. Postgreコンテナのアドオンを追加 作成したアプリのページでConfigure Add-onsをクリックします heroku postgresで検索し、 無料オプション(Hobby Dev - Free)でPostgreコンテナを作成します。[Submit Order Form]をクリックすると即時に作成されます。 アプリケーションのページに戻るとpostgresql-abcdef-12345(postgresql-#{数文字のアルファベット}-#{数文字の数字}の組み合わせ)というようなPostgreコンテナの識別番号が付与されているはずです。以降の作業でコマンドで使用するタイミングがありますのでどこかにメモをしておいてください。 3. HerokuにデプロイできるようにRailsの設定を編集 Heroku上でRailsが作動するようにconfig/environments/development.rbにconfig.hosts << "[Herokuに作成したAppName].herokuapp.com"という一行を加えます。 ※ hogeはご自身が作成したHerokuの名称に書き換えてください config/environments/development.rb require "active_support/core_ext/integer/time" Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. ~ ~ ~ ### 下記の一文を追加 config.hosts << "hoge.herokuapp.com" end 4. ターミナルからHerokuログイン ターミナル経由でHeroku環境に操作をできるように下記のコマンドを入力します。 $ heroku login $ heroku container:login 5. Heroku上にコンテナをPUSHする $ heroku container:push web -a hoge[※ご自身の設定したHerokuアプリ名] $ heroku container:release web -a hoge[※ご自身の設定したHerokuアプリ名] 6. Heroku上のDBを設定しマイグレーションを実行 $ heroku addons:attach postgresql-abcdef-12345 -a hoge[※Herokuアプリ名] $ heroku run rake db:migrate -a hoge[※Herokuアプリ名] ※ postgresql-abcdef-12345には「2. Postgreコンテナのアドオンを追加」でメモしたPostgreコンテナの識別番号を入れてください 7. ブラウザでデプロイしたHerokuアプリケーションを開く heroku open -a hoge[※Herokuアプリ名] ここまで問題なく作業ができていれば、開発環境と同様にタスクの閲覧・追加ができるアプリケーションがHeroku上にデプロイされているはずです、お疲れ様でした! 注意事項 無事にDockerでの開発環境作成からHerokuへのデプロイまで一気に駆け抜けることはできたでしょうか?2点だけ注意事項を書かせてください。 今回のデプロイでは、一応Herokuの無料枠に収まる設定しかしていないはずですが不安な方はデプロイの確認後、削除をお願いします。 今回のデプロイに関してはセキュリティ的な観点での考慮は一切行えておりません。実サービスとして運用される場合はよりセキュアな構成となるように設定面での見直しが必要になると思いますので、ご認識よろしくお願い致します。 最後に いかがでしたでしょうか?私自身、Webエンジニア歴が1年に満たない新参者なので技術的に至らぬ点もあるかもしれません。気になった点・ご指摘事項・ご質問など、お気軽にコメントしていただければ幸いです! 参考記事一覧 https://qiita.com/NA_simple/items/57ad10717568fea2160b https://qiita.com/kodai_0122/items/67c6d390f18698950440
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

M1 Mac で Docker mysql イメージをビルドする

M1 Mac で Docker の mysql イメージをビルドするには linux/amd64 を明示的に指定する必要がある。 Dockerfile Dockerfile を利用している場合は FROM にオプションを渡すことができる。 FROM --platform=linux/amd64 mysql:5.7 docker-compose.yaml docker-compose.yaml を利用している場合は platform を設定する。 services: db: image: mysql platform: linux/amd64
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Prometheus MySQL Exporter with Docker

概要 Prometheusでの、MySQLのメトリクス収集用のMySQL ExporterのDocker環境構築手順。 前提条件 以下の手順でPrometheus環境を構築していることを前提とする。 https://qiita.com/Esfahan/items/0feaedfd771f49ac7ee4 Prometheus公式のexporter 環境 mysqld_exporter v0.13.0 MySQL 5.7(監視対象) 注意 MySQLのperformance_schemaから情報を収集する。 performance_schemaはMySQL 5.5.3から導入されたパフォーマンスをモニタリングするためのスキーマ。 MySQL 5.6以降ではデフォルトでONになっているが、それ以前のバージョンではOFFになっている可能性があるので注意。 監視対象のMySQLの設定 監視対象のMySQLに以下のユーザーを追加。 MySQL Exporterから監視対象のperformance_schemaにアクセスできるようになっている必要がある。 CREATE USER 'exporter'@'%' IDENTIFIED BY 'XXXXXXXXX' WITH MAX_USER_CONNECTIONS 3; GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'exporter'@'%'; GRANT SELECT ON performance_schema.* TO 'exporter'@'%'; MySQL Exporterの環境構築 docker-compose.yaml version: '3' services: mysqld-exporter: container_name: mysqld-exporter image: prom/mysqld-exporter env_file: - .env ports: - 9104:9104 .env DATA_SOURCE_NAME=exporter:XXXXXXXXX@tcp(your_db_name:3306)/performance_schema $ docker-compose up -d --build Prometheusの設定 こちらの記事で構築したPrometheus環境の設定ファイルを編集する。 監視対象を追加 prometheus/node.yaml - labels: env: development targets: # 監視対象のMySQLのホスト名:9104を追記する - your-mysql-exporter-hostname:9104 ルールを追加 /etc/prometheus/alert.rules groups: - name: sample001 rules: # MySQL用のルールを追記 - alert: mysql_down # MySQLが起動しているかのPromQL。 expr: mysql_up == 0 # 5分間応答がなければアラートを飛ばす for: 5m labels: severity: critical # エラー文言 annotations: summary: "MySQL {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." UI確認 http://your_prometeus.com:9090/graph mysql_upで検索すると、正常時は 1 となっている。 監視対象のMySQLをダウンさせると、 0 として検出される。 Slackへの通知 異常時にはSlackに通知される。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker×nginx×php-fpmでwordpress複数台を負荷分散させつつ動かしてみました。

特別Wordpressでブログを出しているような身ではないのですが、少し変わった環境を構築してみたいかもという興味本位でやってみました。 Wordpressサイト運用でプラグイン入れたりバージョン上げたりしたら動かないなんてことも聞くので、こうやって仮想環境を導入してローカル検証の手段を確保したり、将来的にそのままECSなどクラウドコンテナ管理サービスにデプロイして運用したりするといいのかもと思ってる最近です。 いくつかヒットした日本語サイトの情報が古いもので参考にできなかったので、公式ドキュメントのみ参照して2021年最新のもののみで作成しました。将来のバージョンアップも考慮して使用バージョンも残してまとめています。 同じようなことをしたい方に参考にしていただければ幸いです。 環境 Windows 10 (Docker Desktopインストール済) ディレクトリ構成 project/ ├ .docker/ │ ├ env_files/ │ │ ├ mysql.env │ │ └ wordpress.env │ └ nginx/ │ └ default.conf └ docker-compose.yml 使用したdockerイメージ パッチバージョンまで指定すると後で使えなくなった時に困るので、マイナーバージョンまでの指定でイメージを使用するのをお勧めします。バージョン違いで動かないことも稀にあるので指定は必ず行いましょう。 以下に使用したイメージと特記事項を残しています。 nginx:1.21-alpine 特記事項なし wordpress:5.7-php7.4-fpm-alpine 7.4-fpmを土台にしたphpイメージのため、9000番ポートがデフォルトでexportされている(参考ページ) mysql:8.0 デフォルトで3306番ポート、33060番ポートがexportされている MySQL8.0以上ではデフォルトの認証方式が5.7以前と異なるため注意 具体的な実装方法 コード project/docker-compose.yml version: "3.9" services: nginx: image: nginx:1.21-alpine ports: - "3000:80" volumes: - ./.docker/nginx/default.conf:/etc/nginx/conf.d/default.conf - ./html:/var/www/html depends_on: - wp_first - wp_second - wp_third wp_first: image: wordpress:5.7-php7.4-fpm-alpine volumes: - ./html:/var/www/html env_file: - ./.docker/env_files/wordpress.env depends_on: - mysql wp_second: image: wordpress:5.7-php7.4-fpm-alpine volumes: - ./html:/var/www/html env_file: - ./.docker/env_files/wordpress.env depends_on: - mysql wp_third: image: wordpress:5.7-php7.4-fpm-alpine volumes: - ./html:/var/www/html env_file: - ./.docker/env_files/wordpress.env depends_on: - mysql mysql: image: mysql:8.0 command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-authentication-plugin=mysql_native_password volumes: - ./.docker/mysql:/var/lib/mysql env_file: - ./.docker/env_files/mysql.env project/.docker/nginx/default.conf upstream wp_fastcgi_passes { least_conn; server wp_first:9000; server wp_second:9000; server wp_third:9000; } server { listen 80; root /var/www/html/; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_pass wp_fastcgi_passes; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; } } project/.docker/env_files/mysql.env MYSQL_ROOT_HOST=% MYSQL_ROOT_USER=root MYSQL_ROOT_PASSWORD=root MYSQL_DATABASE=wordpress project/.docker/env_files/wordpress.env WORDPRESS_DB_HOST=mysql WORDPRESS_DB_USER=root WORDPRESS_DB_PASSWORD=root WORDPRESS_DB_NAME=wordpress docker関連の説明 Wordpressファイルの自動生成場所をマウントしておく 基本的にwordpressコンテナを立ち上げると1分くらいで/var/www/htmlに生成されるので、wordpressコンテナのvolumeに./html:/var/www/htmlを指定しておきます。こうすると、今は無い「html」というディレクトリがいつの間にか出来上がります。 静的ファイルを配信する準備をしておく nginxコンテナのvolumeにも./html:/var/www/htmlを指定しておきます。wordpressを動かしているfpmはphpのみをさばく役割のみ担っているため、cssやjavascript、画像などの静的ファイルはnginxから配信します。 mysql8.0の起動方法に気を付ける 上述した通りで認証方法が変わっているので、mysqlのcommandに--default-authentication-plugin=mysql_native_passwordを指定しておきましょう。 nginx関連の説明 rootとindexのphpファイルを指定する nginxにドキュメントがどこにあるのか、「/」のリクエスト(=index)が飛んできたときに見に行くファイルがindex.htmlでなくindex.phpのリクエストであると指定しておきましょう。何も指定していないとphpファイルを探してくれません。 phpファイルが来た時の流し方を指定する location ~ \.php$で、phpファイルへのリクエストの時にはfastcgiに処理を流すように指定してください。こうすることでwordpressコンテナにphpの処理を任せられるので、nginxは静的ファイルの配信とphpリクエストの誘導のみ行うようになります。 複数台構成のfastcgiへの負荷分散を指定する upstreamで(コンテナ名):(exposeしているポート番号)を複数指定すれば、あとはnginxの方で勝手に負荷分散(ロードバランシング)してくれます。これをfastcgi_passに使うことでnginx1台でfpm複数台へ処理を流す設定完了です。 実際にやってみる mysqlの初期化 最初はデータベースの初期化(1~2分)が必要なので、進捗確認目的もかねてバックグラウンド実行はせずに立ち上げてください。終わったらCtrl+Cを2回くらい押すと停止します。 $ docker-compose up mysql Wordpressファイルの生成 いきなりWordpress複数台立ち上げるとそれぞれのコンテナでWordpressファイルを生成し始めちゃうので、最初は必ず1つだけ立ち上げてください。こちらは進捗がコマンドに出ないので、wp-admin, wp-content, wp-includesが出そろってしばらくファイル生成がなければ停止してください。 $ docker-compose up wp_first 一気に全部立ち上げましょう 負荷分散を実感するため、今回はdocker-compose up -dを使用していません。wp_firstやwp_second、wp_thirdそれぞれにリクエストの処理が割り振られているのを確認できると思います。 $ docker-compose up ブラウザで確認 localhost:3000へアクセス。以上! 参考 wordpress - Docker Hub wordpress/Dockerfile at 1d90641dc2075168fe59df2f02502df068cc5531 · docker-library/wordpress · GitHub php/Dockerfile at 368453e2918b0a4a5ce488cc987c59c30e4ae4be · docker-library/php · GitHub Nginx upstream module - Nginx.org
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Prometheus, Grafana, AlertMamager, Exporter with Docker

概要 Prometheus, Grafana, AlertMamager, Exporterを使って監視、アラート通知システムを作る。 ツール名 役割 Prometheus メトリクス収集 grafana メトリクス可視化 AlertMamager アラート通知 Exporter 次項を参照 Exporterとは Exporterとは監視サーバーのサーバーのメトリクスを収集、出力するツールで、Prometheusがこれを回収する。メトリクスはPrometheusで保存される。 Exporterには、Officialで用意されているものや、Third-partyのものなど、監視する対象ごとに色々用意されている。詳しくは以下を参照。 https://prometheus.io/docs/instrumenting/exporters/ この記事では、サーバーのUp/Downを監視する仕組みを作るので、Node exporterを使う。 構成 監視サーバーにPrometheus, Grafana, AlertMamagerの3つをインストールする。 監視対象のサーバーにExporterをインストールする。 Prometheus, Grafana, AlertMamagerの環境構築 これら3つを監視サーバーにインストールする。Dockerイメージが用意されているのでこちらを使う。 ディレクトリ構造 ├── alertmanager │   └── config.yaml ├── docker-compose.yaml ├── grafana │   └── grafana.env └── prometheus    ├── alert.rules    ├── node.yaml    └── prometheus.yaml docker-compose.yaml Prometheus, Grafana, AlertMamager docker-compose.yaml version: '3' services: prometheus: image: prom/prometheus container_name: prometheus volumes: - ./prometheus:/etc/prometheus command: "--config.file=/etc/prometheus/prometheus.yaml" ports: - 9090:9090 restart: always grafana: image: grafana/grafana container_name: grafana ports: - 3000:3000 env_file: - ./grafana/grafana.env restart: always alertmanager: image: prom/alertmanager container_name: alertmanager volumes: - ./alertmanager:/etc/alertmanager command: "--config.file=/etc/alertmanager/config.yaml" ports: - 9093:9093 restart: always prometheus.yaml メトリクス収集の設定 prometheus.yaml global: # メトリクスを収集する感覚 scrape_interval: 15s # 監視ルールを評価する感覚 evaluation_interval: 15s # メトリクス収集のタイムアウト値 scrape_timeout: 10s external_labels: # アラート通知に使われるAlertManagerの名前 monitor: 'sample-monitor' # 監視ルール設定ファイルのパス rule_files: - /etc/prometheus/alert.rules # AlertManagerの設定 alerting: alertmanagers: - scheme: http static_configs: - targets: # AlertManagerのHost名:Port番号 - alertmanager:9093 # メトリクス収集の設定 scrape_configs: - job_name: prometheus metrics_path: /metrics static_configs: - targets: # prometheusサーバーのホスト - your_prometeus.com:9090 - file_sd_configs: - files: # メトリクス収集の対象を記述するファイルのパス - /etc/prometheus/node.yaml job_name: node node.yaml メトリクス収集の対象を列挙する。Node Exporterのポートはデフォルトで9100。 node.yaml - labels: env: development targets: - example01.com:9100 - example02.com:9100 alert.rules アラートのルール設定。 5分応答がなければアラートを上げる。 alert.rules - name: example.com rules: - alert: instance_down # PromQLを記述。起動していないインスタンスを検出するPromQL。 expr: up == 0 # 5分間応答がない場合アラートを上げる for: 5m labels: severity: critical # エラー文言 annotations: summary: "Instance {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." config.yaml アラートの通知先などの設定。Slackとメールに通知してみる。 config.yaml global: # Slack の webhook URL の指定 slack_api_url: 'https://hooks.slack.com/************' # SMTP 接続先 smtp_smarthost: 'localhost:25' smtp_require_tls: false # アラート通知主の指定 smtp_from: 'Alertmanager <alert_from@example.com>' route: receiver: 'sample-route' # 同一アラート名、インスタンス名、エラーレベルでグループ化、アラートを同じ種類とみなす条件 group_by: ['alertname', 'instance', 'severity'] # 同じ種類のアラートを1つのアラート群としてにまとめる時間 group_wait: 30s # 同じ種類のアラートが発生した時に次回通知するまでの時間 group_interval: 5m # 一度通知したアラートは10分おきに再通知 repeat_interval: 10m receivers: - name: 'sample-route' slack_configs: # Slack のチャンネル名 - channel: '#alert' email_configs: # メールの宛先 - to: "alert_to@example.com" grafana.env Grafanaのサーバー設定。とりあえずこれでOK。 GF_SERVER_DOMAIN=localhost GF_SERVER_HTTP_PORT=3000 GF_SERVER_PROTOCOL=http Exporter 監視対象のサーバーにNode Exporterをインストールする。 docker-compose.yaml docker-compose.yaml version: '3' services: node-exporter: image: quay.io/prometheus/node-exporter container_name: node-exporter ports: - 9100:9100 volumes: - /proc:/host/proc - /sys:/host/sys - /:/rootfs docker-compose up $ docker-compose up -d --build UI確認 Prometheus メトリクス http://your_prometeus.com:9090/graph 入力フォームにPromQLを入れることでメトリクスを確認できる。以下の例では、alert.rulesで設定した up を入力している。インスタンスが起動しているので、 1 となっている。 (1 = 正常、0 = 異常) 試しに監視対象をダウンさせてみる。 その後でalert.rulesで設定したPromQLを入れると、該当のnodeが検出される。値は 0 となっている。 監視対象一覧 https://your_prometeus.com:9090/targets node-exporterをDownさせるとStateが Down になる。 AlertManager https://your_prometeus.com:9093 監視対象をDownさせるとアラートが検出される。(今回の例では5分間応答がないとアラートが上がる。) アラート通知 Slackにアラートが通知される。 Grafana https://your_prometeus.com:3000 初期アカウントはadmin:admin Datasourceを追加 Add Datasourceをクリック PrometheusをSelect 必要情報を入力して「Save&Test」 「Data source is working」と表示されればOK。 Dashbordタブをクリックして、importするものを選択 名前の部分をクリック Dashboardが表示される。 Grafanaの詳しい使い方は省略。 その他Exporterの利用手順 Prometheus MySQL Exporter with Docker 参考 DockerでPrometheus, Grafana, Alertmanagerを動かす Prometheusのクエリ機能とアラート機能
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ubuntu20.04でgpuをつかうdockerイメージを走らせるまで

はじめに ubuntu 20.04 desktop + nvidia gpu + docker で環境構築したときのメモ やることは以下の3つだ。 nvidiaドライバーのインストール dockerのインストール nvidia container toolkitのインストール このリンク役に立つ。 nvidiaドライバーのインストール 初期状態だとnouveauというドライバーが入っているので、nvidiaのドライバをインストールする。 ソフトウェアとアップデートを起動 追加のドライバー タブを選択 nvidia...を使用します。をチェック mokがなんたらかんたらでパスワードを作れと言われるのでパスワード作成 再起動 再起動するとなんか選択肢が現れるので「Enroll MOK」を選択 さっき作ったパスワードを入力 これで完成。MOKのところがよくわからんかったが、以下の記事を読んで解決した。 dockerのインストール ここに従ってやれ。 nvidia container toolkitのインストール ここに従ってやれ。 実行例 sudo docker run -it --gpus all --name study-ai -v ~/notebooks:/tf/notebooks -p 8888:8888 tensorflow/tensorflow:latest-jupyter 終わり。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ラズパイZeroでTensorFlow Liteに挑戦

M5StackのUnitV2をみて、手元のラズパイZeroでも何かできないかと思って調整してみました。 調べてみるとTensorflow Liteが動くようなので、サンプルの画像分類を試してみました。 ※ラズパイZero(ARMv6)向けのWheelパッケージは用意されていませんので、自前で作成する必要があります。手順は後ろに載せています サンプルプログラムの実行 RaspberryPiZero git clone https://github.com/tensorflow/examples --depth 1 cd examples/lite/examples/image_classification/raspberry_pi/ bash download.sh /tmp python3 classify_picamera.py --model /tmp/mobilenet_v1_1.0_224_quant.tflite --labels /tmp/labels_mobilenet_quant_v1_224.txt 結果1(Mobilenet_V1_1.0_224_quant) 動作はするのですが、1回の推論に10秒近くかかります。。遅い。。 使用するモデルを軽いものに変えてみます。 ここの中からMobilenet_V1_1.0_128_quantに変更してみます。 RaspberryPiZero cd /tmp/ wget https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_128_quant.tgz tar zxvf mobilenet_v1_1.0_128_quant.tgz ラベルは見つからなかったのでサンプルに含まれるものを使いまわしましょう RaspberryPiZero python3 classify_picamera.py --model /tmp/mobilenet_v1_1.0_128_quant.tflite --labels /tmp/labels_mobilenet_quant_v1_224.txt 結果2(Mobilenet_V1_1.0_128_quant) 3.5秒ぐらいなので、まあまあ早くなりました。 ラズパイZero向けのPython Wheelパッケージを作成する 残念ながらラズパイZero(ARMv6)向けのWheelパッケージは用意されていません。 ラズパイ2以降のARMv7用は用意されています。 https://www.tensorflow.org/lite/guide/python ただ、自分でビルドする手順は用意されていましたので、それに沿ってやってみました。 VSCodeでDocker in Dockerコンテナを起動 ここは好みですが、ホスト環境を汚さずビルドしたかったので、Docker内で行おうと思いました。 ただ、ビルドにDokcerを使用する仕組みだったので、Dockerの中でDockerが起動可能な「Docker in Docker」の形で行いました。 vscodeを起動し、左下の「リモートウィンドウを開きます」ボタンから始めます 「Add Development Container Configuration Files...」を選択 「Show All Definitions...」を選択 「Docker in Docker」を選択 これで設定ファイルができました 「Reopen in Container」を選択 ここから先はコンテナ内での作業になります。 Python Wheelパッケージの作成 公式の手順はこちらです。 https://www.tensorflow.org/lite/guide/build_cmake https://www.tensorflow.org/lite/guide/build_cmake_pip Docker-in-Docker cd # 作業は/root配下で行いました sudo apt-get update sudo apt-get install cmake -y git clone https://github.com/tensorflow/tensorflow.git tensorflow_src cd tensorflow_src/ tensorflow/tools/ci_build/ci_build.sh PI-PYTHON37 tensorflow/lite/tools/pip_package/build_pip_package_with_cmake.sh rpi0 # 最後のrpi0が重要です これでWheelパッケージが作成されます 出力先はこちらです Docker-in-Docker ~/tensorflow_src $ ls -l tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.7/dist/ total 2776 -rw-r--r-- 1 vscode vscode 1414958 Jun 6 05:39 tflite_runtime-2.6.0-cp37-cp37m-linux_armv6l.whl -rw-r--r-- 1 vscode vscode 1422521 Jun 6 05:39 tflite-runtime-2.6.0.linux_armv6l.tar.gz ~/tensorflow_src $ ラズパイZeroにTensorFlow Liteをインストールする RaspberryPiZero sudo apt-get update sudo apt install libatlas-base-dev -y pip install tflite_runtime-2.6.0-cp37-cp37m-linux_armv6l.whl
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【docker-compose】docker-registryを導入する ~https接続編~

はじめに https接続でdocker-registryに接続します。 リバースプロキシを経由するパターン、しないパターンをそれぞれ紹介します。 docker-composeを使用します。 前編はこちら https://qiita.com/not75743/items/2358229fc6f83718e7bf 対象読者 docker-registryにhttps接続でpush,pullしたい人 docker-registryにリバースプロキシ(nginx)経由でpush,pullしたい人 自己証明書を使用してdocker-registryにhttps接続したい人 前提 https接続のための証明書が取得済みであること。 docker,docker-composeが使える環境であること 環境 client $ cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) $ docker --version Docker version 20.10.3, build 48d30b5 host AWSのEC2 使ったAMIはamzn2-ami-hvm-2.0.20210126.0-x86_64-gp2 $ docker --version Docker version 20.10.4, build d3cb89e $ docker-compose --version docker-compose version 1.27.4, build 40524192 構成図 ① リバースプロキシ(nginx)を経由するパターン ディレクトリ構成 ディレクトリ構成 . |-- cert | |-- fullchain.pem | `-- privkey.pem |-- data |-- docker-compose.yaml |-- registry | `-- config.yml `-- reverseproxy |-- htpasswd `-- nginx.conf docker-compose.yaml 以下を使用しました。 docker-compose.yaml version: "3.9" services: reverse-proxy: image: nginx:1.20 ports: - 5043:443 volumes: - ./cert/fullchain.pem:/etc/nginx/conf.d/fullchain.pem:ro - ./cert/privkey.pem:/etc/nginx/conf.d/privkey.pem:ro - ./reverseproxy/nginx.conf:/etc/nginx/nginx.conf:ro - ./reverseproxy/.htpasswd:/etc/nginx/htpasswd:ro registry: image: registry:2 volumes: - ./data:/var/lib/registry - ./registry/config.yml:/etc/docker/registry/config.yml 直接のアクセスを防ぐため、registryのポートは記載していません。 コンフィグや証明書については適切なパスを指定しましょう。 nginx.conf 以下を使用しました。 ドキュメントに記載のコメントも残しています。 nginx.conf events { worker_connections 1024; } http { upstream docker-registry { server registry:5000; } ## Set a variable to help us decide if we need to add the ## 'Docker-Distribution-Api-Version' header. ## The registry always sets this header. ## In the case of nginx performing auth, the header is unset ## since nginx is auth-ing before proxying. map $upstream_http_docker_distribution_api_version $docker_distribution_api_version { '' 'registry/2.0'; } server { listen 443 ssl; server_name example.test; # SSL ssl_certificate /etc/nginx/conf.d/fullchain.pem; ssl_certificate_key /etc/nginx/conf.d/privkey.pem; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # ※① # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486) chunked_transfer_encoding on; location / { # Do not allow connections from docker 1.5 and earlier # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } # To add basic authentication to v2 use auth_basic setting. auth_basic "Registry realm"; auth_basic_user_file /etc/nginx/htpasswd; # ※② ## If $docker_distribution_api_version is empty, the header is not added. ## See the map directive above where this variable is defined. add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always; proxy_pass http://docker-registry; proxy_set_header Host $http_host; # required for docker client's sake proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 900; } } } 以下でポイントについて説明します。 ① client_max_body_size 0 詳しくはここを参照 HTTPボディの大きさを制限するパラメータです。 docker-registryには大きめのイメージをpushする場合もあり、このパラメータが設定されている場合、引っかかる場合があります。 引っかかった場合は以下の様に出力されます。 クライアント側 イメージpush時のログ確認 $ docker push example.test:5043/centos:test The push refers to repository [example.test/centos] 174f56854903: Pushing [==================================================>] 203.9MB/203.9MB error parsing HTTP 413 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>413 Request Entity Too Large</title></head>\r\n<body>\r\n<center><h1>413 Request Entity Too Large</h1></center>\r\n<hr><center>nginx/1.20.0</center>\r\n</body>\r\n</html>\r\n" docker-compose側 docker-compose.yaml registry_1 | time="2021-05-30T05:38:32.00570856Z" level=error msg="response completed with error" err.code="blob unknown" err.detail=sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc err.message="blob unknown to registry" go.version=go1.11.2 http.request.host="example.test" http.request.id=d62a7937-e2bf-4b68-9e62-96f9fe7721f9 http.request.method=HEAD http.request.remoteaddr=<クライアントIP> http.request.uri="/v2/centos/blobs/sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc" http.request.useragent="docker/20.10.3 go/go1.13.15 git-commit/46229ca kernel/3.10.0-1160.15.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.3 \(linux\))" http.response.contenttype="application/json; charset=utf-8" http.response.duration=1.422727ms http.response.status=404 http.response.written=157 vars.digest="sha256:2d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc" vars.name=centos reverse-proxy_1 | 2021/05/30 05:38:37 [error] 30#30: *9 client intended to send too large chunked body: 1048576+32768 bytes, client: <クライアントIP>, server: example.test, request: "PATCH /v2/centos/blobs/uploads/617a6324-7a93-4212-987e-a48eb501f34d?_state=k8ymp1axNemJM79Vg5G-pRgHuZW_UkkYGREuBH29q5d7Ik5hbWUiOiJjZW50b3MiLCJVVUlEIjoiNjE3YTYzMjQtN2E5My00MjEyLTk4N2UtYTQ4ZWI1MDFmMzRkIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIxLTA1LTMwVDA1OjM4OjMyLjQ3NTA4Njg2MVoifQ%3D%3D HTTP/1.1", host: "example.test" ドキュメントでは client_max_body_size 0; として制限を無効にしていました。 デフォルトのnginx.conf設定は1Mのため、忘れずに適用しましょう。 ② 認証ファイルのフォーマット 詳しくはここを参照 nginxが参照できるパスワードフォーマットはRFC 2307に記載のあるものとのことです。その中にbcryptはなく、対応してないため注意しましょう。 今回は以下の様にMD5でパスワードファイルを作っています。 htpasswd作成 $ htpasswd -b -c -m htpasswd test test ちなみに-mオプションはhtpasswdのデフォルトなのであってもなくてもいいです。 コンテナ立ち上げ 起動します。 $ docker-compose up -d $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------- registry-nginx_registry_1 /entrypoint.sh /etc/docker ... Up 5000/tcp registry-nginx_reverse-proxy_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:5043->443/tcp, 80/tcp OK イメージpush,pull レジストリにログインします。 $ docker login example.test:5043 Username: test Password: WARNING! Your password will be stored unencrypted in /home/test/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded イメージをpushします $ docker image tag nginx:alpine example.test:5043/test-nginx:alpine $ docker push example.test:5043/test-nginx:alpine The push refers to repository [example.test:5043/test-nginx] 4689e8eca613: Pushed 3480549413ea: Pushed 3c369314e003: Pushed 4531e200ac8d: Pushed ed3fe3f2b59f: Pushed b2d5eeeaba3a: Pushed alpine: digest: sha256:480395b7be07df06368c93469df41343c1e6285f5b37d387b5a17f2e8708a2a3 size: 1568 $ curl -u test:test https://example.test:5043/v2/_catalog {"repositories":["test-nginx"]} OKです。 次はpullします ### 確認のために既存のイメージを削除 $ docker rmi -f nginx:alpine $ docker rmi -f example.test:5043/test-nginx:alpine ### pullする $ docker pull example.test:5043/test-nginx:alpine alpine: Pulling from test-nginx Digest: sha256:480395b7be07df06368c93469df41343c1e6285f5b37d387b5a17f2e8708a2a3 Status: Downloaded newer image for example.test:5043/test-nginx:alpine example.test:5043/test-nginx:alpine OKです。 では次のパターン...の前に忘れずにコンテナを落としておきましょう。 $ docker-compose down $ docker-compose ps Name Command State Ports ------------------------------ $ リバースプロキシ(nginx)を経由しないパターン ディレクトリ構成 ディレクトリ構成は以下 ディレクトリ構成 . |-- cert | |-- fullchain.pem | `-- privkey.pem |-- data |-- docker-compose.yaml `-- registry |-- htpasswd `-- no-nginx-config.yml config.ymlは区別のために名前を変えています。 docker-compose.yaml docker-compose.yaml version: "3.9" services: only-registry: image: registry:2 ports: - 5000:5000 volumes: - ./data:/var/lib/registry - ./registry/no-nginx-config.yml:/etc/docker/registry/config.yml - ./registry/htpasswd:/auth/htpasswd:ro - ./cert/fullchain.pem:/certs/fullchain.pem:ro - ./cert/privkey.pem:/certs/privkey.pem:ro no-nginx-config.yml no-nginx-config.yml version: 0.1 log: accesslog: disabled: false level: warn formatter: text fields: environment: test storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry http: addr: :5000 tls: # ※① certificate: /certs/fullchain.pem key: /certs/privkey.pem auth: htpasswd: # ※② realm: basic-realm path: /auth/htpasswd 以下でポイントについて説明します。 ①tls 詳しくはここを参照 http: addr: :5000 tls: certificate: /certs/fullchain.pem key: /certs/privkey.pem docker-registryに直接証明書設定を入れる場合はtlsオプションを設定します。 秘密鍵、証明書のパスを指定します。ホストのパスとごっちゃにならないように注意しましょう ②認証ファイルのフォーマット 詳しくはここを参照 以下の通りbcryptフォーマットしかサポートしていないため、上述したnginxの場合とは異なります。 The htpasswd authentication backed allows you to configure basic authentication using an Apache htpasswd file. The only supported password format is bcrypt. Entries with other hash types are ignored. 以下の様にhtpasswdファイルを作成しましょう。 $ htpasswd -b -B -c test.htpasswd test test コンテナ立ち上げ 起動します。 $ docker-compose up -d $ docker-compose ps Name Command State Ports ----------------------------------------------------------------------------------------------- registry-only_only-registry_1 /entrypoint.sh /etc/docker ... Up 0.0.0.0:5000->5000/tcp OK イメージpush,pull ログインします。 $ docker login example.test:5000 Username: test Password: WARNING! Your password will be stored unencrypted in /home/test/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded pushします $ docker pull nginx:alpine $ docker image tag nginx:alpine example.test:5000/test-nginx:alpine $ docker push example.test:5000/test-nginx:alpine The push refers to repository [example.test:5000/test-nginx] 058eb06e0efd: Pushed 2f2df3ae0cad: Pushed 2b60f0243825: Pushed 96131b349b16: Pushed a42a23cd7b07: Pushed b2d5eeeaba3a: Pushed alpine: digest: sha256:2e76f4d4e21bae1d012267cff67e032bb006a2cff5c00afa5d4ad011c1855128 size: 1568 $ curl -u test:test https://example.test:5000/v2/_catalog {"repositories":["test-nginx"]} OK。pullします。 $ docker pull example.test:5000/test-nginx:alpine alpine: Pulling from test-nginx 540db60ca938: Already exists 0ae30075c5da: Pull complete 9da81141e74e: Pull complete b2e41dd2ded0: Pull complete 7f40e809fb2d: Pull complete 758848c48411: Pull complete Digest: sha256:2e76f4d4e21bae1d012267cff67e032bb006a2cff5c00afa5d4ad011c1855128 Status: Downloaded newer image for example.test:5000/test-nginx:alpine example.test:5000/test-nginx:alpine OK! どちらのパターンでもpush,pullできていますね。 それでは落としておきましょう $ docker-compose down $ docker-compose ps Name Command State Ports ------------------------------ $ 自己証明書を使用する 詳しくはここを参照 nginxを経由するしないにかかわらず、自己証明書を使用した場合は以下の様に出力され、registryへログインできません。 $ docker login example.test:5043 Authenticating with existing credentials... Login did not succeed, error: Error response from daemon: Get https://example.test:5043/v2/: x509: certificate signed by unknown authority その場合、以下の様に対処します。 ### 移動 $ cd /etc/docker/certs.d/ ### ディレクトリ作成 $ sudo mkdir example.test:5043 ### 証明書ファイル配置 $ ll example.test\:5043/ 合計 12 -rw-r--r-- 1 root root 1172 6月 6 14:00 ca.crt -rw-r--r-- 1 root root 1155 6月 6 14:00 client.cert -rw-r--r-- 1 root root 1679 6月 6 14:01 client.key ### 接続 $ docker login example.test:5043 Authenticating with existing credentials... WARNING! Your password will be stored unencrypted in /home/test/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded 無事接続できました。 接続先FQDN + ポート番号でディレクトリを作り、そこに各ファイルを格納しています。 各種ファイルは自己証明書作成時にできたものを持ってきましょう。 ちなみにファイル名が上記以外だとログインに失敗します。ドキュメントに従いましょう $ sudo mv ca.crt ca.cr $ sudo mv client.cert client.cet $ sudo mv client.key client.ky $ docker login example.test:5043 Authenticating with existing credentials... Login did not succeed, error: Error response from daemon: Get https://example.test:5043/v2/: x509: certificate signed by unknown authority 終わりに 無事https接続できてよかったです。 次回はhttp APIを叩いてイメージをいろいろ見てみたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでDjango+Vue+NginxのSPAを作る

Docker composeの復習がてらSPAサイトの雛形コンテナ構成を最速ビルドしてみる 可能な限り初期ファイル構成はシンプルかつ最小限で。 ディレクトリ&コンテナ構成 docker_spa/ ┣━ back/ ┃ ┣━ scripts/ ┃ ┃ ┣━ django-appstart.sh # Django新規アプリ作成用スクリプト ┃ ┃ ┣━ django-settings.sh # Djangoセットアップ用スクリプト ┃ ┃ ┗━ start.sh # コンテナ起動関連スクリプト ┃ ┣━ Dockerfile # バックエンド用Dockerfile ┃ ┗━ requirements.txt # pythonパッケージ一覧 ┣━ front/ ┃ ┣━ scripts/ ┃ ┃ ┣━ start.sh # 「settings.py」修正用スクリプト ┃ ┃ ┗━ vue-settings.sh # vue用スクリプト ┃ ┗━ Dockerfile # フロントエンド用Dockerfile ┣━ web/ ┃ ┣━ conf/ ┃ ┃ ┗━ app_nginx.conf # アプリ用Nginx設定ファイル ┃ ┣━ logs/nginx ┃ ┃ ┗━ access.log # アクセスログ ┃ ┃ ┗━ error.log # エラーログ ┃ ┣━ Dockerfile # webサーバー用Dockerfile ┃ ┗━ uwsgi_params # アプリサーバー設定ファイル ┃ ┗━ docker-compose.yml docker-compose.yml docker-compose.yml version: '3.7' services: web: container_name: web-container build: context: ./ dockerfile: ./web/Dockerfile restart: unless-stopped # コンテナが異常停止した場合は再起動する ports: - "8000:8000" environment: TZ: "Asia/Tokyo" volumes: - ./web/conf:/etc/nginx/conf.d - ./web/logs/nginx/:/var/log/nginx/ - ./web/uwsgi_params:/etc/nginx/uwsgi_params - ./web/static:/static - django_statics:/var/www/vhosts/localhost/static:ro networks: - django_net depends_on: - back back: container_name: back-container build: context: ./back dockerfile: ./Dockerfile command: 'sh /code/scripts/start.sh' restart: unless-stopped volumes: - ./back:/code - ./back/app/static:/static expose: - "8001" networks: - django_net front: container_name: front-container build: context: ./front dockerfile: ./Dockerfile # ./front/Dockerfileを参照 ports: - 8080:8080 expose: - "3000" command: 'sh /code/scripts/start.sh' volumes: - ./front:/code - ./static:/static networks: - django_net depends_on: - back networks: django_net: driver: bridge volumes: django_statics: driver: local 詳細な導線は異なるところはあると思いますが、上記がComposeのコンテナ構成イメージです。 ページアクセスのリクエストをwebサーバーコンテナ内のNginxがプロキシサーバーとして中継 バックエンドコンテナ内のアプリサーバーのuWSGIでバックエンドとNginxとの疎通 POSTリクエストをAPIサーバーとしてDjango(REST Framework)で処理 Vueのaxiosのプロキシサーバーと連結してレスポンスオブジェクトをVueの非同期で受け取る こんな流れで最小限のSPA環境をビルドします。 今回はwebアプリとしてVueからしか繋いでないのに無駄に複雑な構成になってますが、専用コンテナをcomposeに追加してそこからのリクエストをAPIサーバーに処理してもらってNginx経由でアクセスを振り分けてもらえば将来的にネイティブアプリやデスクトップアプリなどクロスプラットフォーム対応した際にもコンテナ同士の構造を意識しなくても良くなる・・・ハズ・・・。 バックエンド側 APIサーバー処理用のバックエンド側のコンテナ構成 FROM python:3.8 ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 EXPOSE 8000 # 開発ディレクトリ設定 ENV WORKDIR /code WORKDIR ${WORKDIR} COPY ./scripts/ ${WORKDIR}/ # コンテナ内でパッケージを一括インストール COPY requirements.txt ${WORKDIR} RUN pip install --upgrade pip && pip install -r requirements.txt && \ pip install coreapi django-cors-headers python-jose COPY . ${WORKDIR}/ コンテナ起動関連スクリプト 初回ビルド時にappフォルダ&新規プロジェクトを作成 同時に各種セットアップのスクリプトを実行 migrationとuWSGIサーバーを起動(※2回目以降はここのみ実行) back/scripts/start.sh #!/bin/bash set 'echo -e -o pipefail' unix_today=$(date +'%s') unix_today=$((unix_today+32400)) jst_ymd_today=$(date '+%Y/%m/%d %H:%M:%S' --date "@$unix_today") # メインプロジェクトフォルダが無ければセットアップ実行 if [ ! -d /code/app ]; then mkdir app && cd app django-admin startproject config . bash /code/scripts/django-settings.sh bash /code/scripts/django-appstart.sh main fi cd app python manage.py makemigrations python manage.py migrate # python manage.py collectstatic # 静的ファイルディレクトリをstatic指定ディレクトリに集約コピー(--noinputで対話プロンプトを無視) python manage.py collectstatic --noinput # configアプリuWSGIに接続。「--py-autoreload 1」でファイル等に変更があった際は自動リロード uwsgi --socket :8001 --module config.wsgi --py-autoreload 1 --logto /tmp/uwsgi.log Djangoセットアップ用スクリプト 「config/settings.py」の各種セットアップ タイムゾーンと言語を日本語対応 REST Framework設定を追記 staticディレクトリ設定 「config/url.py」のセットアップ 静的ファイル用「template」ディレクトリ作成 back/scripts/django-appstart.sh #!/bin/sh # シェル実行が失敗したら終了してエラー出力 set 'echo -e -o pipefail' # ルートディレクトリ取得 ROOT_DIR=$(cd $(dirname $0)/..;pwd) echo ${ROOT_DIR} # 各種モジュールインポートを追記 if ! grep -q "import os" "${ROOT_DIR}/app/config/settings.py" ;then sed -i -e "s/from pathlib import Path/from pathlib import Path \nimport os\nimport json\nfrom six.moves.urllib import request\nfrom cryptography.x509 import load_pem_x509_certificate\nfrom cryptography.hazmat.backends import default_backend/" ${ROOT_DIR}/app/config/settings.py fi # BASE_DIR変更 sed -i -e "s/BASE_DIR = Path(__file__).resolve().parent.parent/BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))/" ${ROOT_DIR}/app/config/settings.py # INSTALLED_APPSにrest_frameworkとrest_framework_jwtとcorsheadersを追加 if ! grep -q "'rest_framework'," "${ROOT_DIR}/app/config/settings.py" ;then sed -i -e "s/'django.contrib.staticfiles',/'django.contrib.staticfiles',\n 'rest_framework', \n 'rest_framework_jwt', \n 'corsheaders',/" ${ROOT_DIR}/app/config/settings.py fi # MIDDLEWAREにcorsheadersミドルウェアを追記 if ! grep -q "'corsheaders.middleware.CorsMiddleware'," "${ROOT_DIR}/app/config/settings.py" ;then sed -i -e "s/'django.middleware.common.CommonMiddleware',/'corsheaders.middleware.CorsMiddleware', \n 'django.middleware.common.CommonMiddleware', \n/" ${ROOT_DIR}/app/config/settings.py fi # テンプレートディレクトリ設定 sed -i -e "s/'DIRS': \[\],/'DIRS': \[os.path.join(BASE_DIR, \"app\/templates\")\],/" ${ROOT_DIR}/app/config/settings.py # 言語をjaに変更 sed -i -e "s/LANGUAGE_CODE = 'en-us'/LANGUAGE_CODE = 'ja'/" ${ROOT_DIR}/app/config/settings.py # タイムゾーンをAsia/Tokyoに変更 sed -i -e "s/TIME_ZONE = 'UTC'/TIME_ZONE = 'Asia\/Tokyo'/" ${ROOT_DIR}/app/config/settings.py # DATEBASEパス変更 sed -i -e "s/'NAME': BASE_DIR \/ 'db.sqlite3',/'NAME': BASE_DIR+'\/app\/db.sqlite3',/" ${ROOT_DIR}/app/config/settings.py # ALLOWED_HOSTSにlocalhostと127.0.0.1追加 sed -i -e "s/ALLOWED_HOSTS = \[\]/ALLOWED_HOSTS = \[\n '127.0.0.1', \n 'localhost', \]/" ${ROOT_DIR}/app/config/settings.py # STATIC_ROOT追記 sed -i -e "s/STATIC_URL = '\/static\/'/STATIC_URL = '\/static\/'\nSTATIC_ROOT = os.path.join(BASE_DIR, 'static')/" ${ROOT_DIR}/app/config/settings.py # REST_FRAMEWORK設定追記 if ! grep -q "REST_FRAMEWORK = {" "${ROOT_DIR}/app/config/settings.py" ;then echo "# REST_FRAMEWORK設定 REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), } # クロスオリジン許可 CORS_ORIGIN_WHITELIST = ( 'http://localhost:8080', ) " >> ${ROOT_DIR}/app/config/settings.py fi # importにincludeモジュールを追加&napp_name設定 sed -i -e "s/from django.urls import path/from django.urls import path, include \nfrom rest_framework.documentation import include_docs_urls\n/" ${ROOT_DIR}/app/config/urls.py # APIドキュメントルート追加 sed -i -e "s/path('admin\/', admin.site.urls),/path('admin\/', admin.site.urls),\n path('docs\/', include_docs_urls(title='API Document')),\n/" ${ROOT_DIR}/app/urls.py # templates&staticフォルダ階層作成 mkdir ${ROOT_DIR}/app/templates mkdir ${ROOT_DIR}/app/static && mkdir ${ROOT_DIR}/app/static/css ${ROOT_DIR}/app/static/js ${ROOT_DIR}/app/static/images # base.html作成 cat > ${ROOT_DIR}/app/templates/base.html << "EOF" <!DOCTYPE html> {% load tz %} {% load static %} <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{% block title %}{% endblock %}</title> {% block style %}{% endblock %} </head> <body> {% if messages %} <ul class="pl-0 ml-3"> {% for message in messages %} <li class="alert alert-{{ message.tags }}">{{ message }}<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <span aria-hidden="true">×</span> </button></li> {% endfor %} </ul> {% endif %} {% block content %} {% endblock %} {% block script %}{% endblock %} </body> </html> EOF # index.html作成 cat > ${ROOT_DIR}/app/templates/index.html << "EOF" {% extends "base.html" %} {% load static %} {% block title %}ページタイトル{% endblock %} {% block style %} {% endblock %} {% block breadcrumb %} {% endblock %} {% block content %} インデックスページのコンテンツを表示中 {% endblock %} {% block script %} {% endblock %} EOF # template.html作成 cat > ${ROOT_DIR}/app/templates/template.html << EOF {% extends "base.html" %} {% load static %} {% block title %}ページタイトル{% endblock %} {% block style %} {% endblock %} {% block breadcrumb %} {% endblock %} {% block content %} コンテンツテンプレートです {% endblock %} {% block script %} {% endblock %} EOF pythonパッケージ一覧 back/requirements.txt Django==3.2 psycopg2-binary>=2.8 scrapy-djangoitem==1.1.1 scrapy==2.4 scrapyd==1.2.0 djangorestframework==3.12.4 djangorestframework-jwt==1.11.0 django-cors-headers==3.7.0 django-webpack-loader==1.0.0 uwsgi==2.0.19.1 markdown==3.3.4 django-filter==2.4.0 Pygments==2.9.0 新規アプリ作成用スクリプト back/scripts/django-appstart.sh #!/bin/sh # シェル実行が失敗したら終了してエラー出力 set -e -o pipefail # 実行ディレクトリ取得 ROOT_DIR=$(cd $(dirname $0)/..;pwd) echo $ROOT_DIR # "新規アプリ作成" # 新規ディレクトリ&アプリ作成 mkdir $ROOT_DIR/app/${1} django-admin startapp ${1} $ROOT_DIR/app/${1} # INSTALLED_APPSに新規アプリを追加 sed -i -e "s/'rest_framework',/'rest_framework', \n '${1}', /" ${ROOT_DIR}/app/config/settings.py # websiteルーティング追加 sed -i -e "s/\]/ path('${1}\/', include('${1}.urls')),\n\]/" ${ROOT_DIR}/app/config/urls.py # APP_NAME/urls.py作成 cat > $ROOT_DIR/app/${1}/urls.py << EOF from django.urls import include, path # from . import views from .views import * app_name = '${1}' urlpatterns = [ path('api/jp', JPTestAPI.as_view()), path('api/us', USTestAPI.as_view()), path('api/br', BRTestAPI.as_view()), path('', index, name='index'), ] EOF # APP_NAME/views.py修正 cat > $ROOT_DIR/app/${1}/views.py << "EOF" from uuid import uuid4 from urllib.parse import urlparse from django.core.validators import URLValidator from django.core.exceptions import ValidationError from django.views.decorators.http import require_POST, require_http_methods from django.shortcuts import render from django.utils import timezone from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.views.generic import ListView, TemplateView, DetailView from django.shortcuts import render from rest_framework.views import APIView from rest_framework import authentication, permissions from rest_framework import status, viewsets, filters from rest_framework import permissions from rest_framework.response import Response # from django.db.models import Q import pytz from datetime import datetime # REST API 通信テスト用 class JPTestAPI(APIView): permission_classes = (permissions.AllowAny,) def get(self, request, format=None): # return Response(data={'status': dt_now}, status=status.HTTP_200_OK) jp = pytz.timezone('Asia/Tokyo') return JsonResponse(data={'status': datetime.now(tz=jp)}, status=status.HTTP_200_OK) class USTestAPI(APIView): permission_classes = (permissions.AllowAny,) def get(self, request, format=None): us = pytz.timezone('US/Eastern') return JsonResponse(data={'status': datetime.now(tz=us)}, status=status.HTTP_200_OK) class BRTestAPI(APIView): permission_classes = (permissions.AllowAny,) def get(self, request, format=None): br = pytz.timezone('Brazil/East') return JsonResponse(data={'status': datetime.now(tz=br)}, status=status.HTTP_200_OK) def index(request): return render(request, 'index.html' EOF # "テンプレート作成" # templates&staticフォルダ階層作成 mkdir $ROOT_DIR/app/templates/${1} # "「config/urls.py」にルーティングを追加" sed -i -e "s/]/ path('${1}', include('${1}.urls')),\n]/" $ROOT_DIR/config/urls.py 初回実行時に「main」ディレクトリを作成するスクリプトですが、他にも新規でアプリディレクトリを追加したい場合は以下のコマンドで APPNAME を好きなアプリ名で実行するとスクリプトが実行され、新規ディレクトリが作成されます $ docker-compose run back bash /code/scripts/django-appstart.sh APPNAME 新規ディレクトリにアプリファイル一覧を作成 「app/config/settings.py」にアプリ名設定追記 「app/config/urls.py」にアプリルーティング追記 「app/templates/」に新規アプリ名ディレクトリを作成 「views.py」と「urls.py」に設定追記 フロントエンド側 webアプリとしてのフロントエンド側のコンテナ構成 FROM node:16.2.0 # 開発ディレクトリ設定 ENV WORKDIR /code WORKDIR ${WORKDIR} COPY ./scripts/ ${WORKDIR}/ # コンテナ内でパッケージを一括インストール RUN npm update npm && npm install -g @vue/cli && \ npm install -g @vue/cli-init && npm install -S axios COPY . ${WORKDIR}/ コンテナ起動関連スクリプト 初回ビルド時は新規Vueプロジェクト作成コマンドを催促 初回以降にappディレクトリ作成済の場合は各種スクリプト実行 front/scripts/start.sh #!/bin/bash set 'echo -e -o pipefail' unix_today=$(date +'%s') unix_today=$((unix_today+32400)) jst_ymd_today=$(date '+%Y/%m/%d %H:%M:%S' --date "@$unix_today") app_name='app' # プロジェクトディレクトリが存在していればサーバー起動 if [ -d /code/${app_name} ]; then # vueプロジェクト設定済みではなかったら if [ ! -f /code/${app_name}/vue.config.js ]; then echo "${jst_ymd_today} | Vue directory set up" # vueテンプレート作成 bash /code/scripts/vue-settings.sh else echo "${jst_ymd_today} | Start the project server" # プロジェクトディレクトリに移動してサーバー起動 cd ${app_name} npm run serve fi else echo "「${jst_ymd_today}」|Create a new project" #*********************************************************************** echo "Vue axios設定ファイル作成" #*********************************************************************** mkdir /code/${app_name} if [ ! -f /code/${app_name}/vue.config.js ]; then cat > /core/${app_name}/vue.config.js << "EOF" module.exports = { devServer: { proxy: { '^/api/': { target: 'http://localhost:8000', logLevel: 'debug', pathRewrite: { "^/api/": "/api/" } } } } } EOF fi echo "-----------------------------------------------------------" echo "Run the command 'docker-compose run front vue create ${app_name} .' on the host machine" echo "------------------------------------------------------------" fi Vue.js設定用スクリプト 「HelloWorld.vue」にテスト用コード追記 「main.js」にaxiosとrourer設定追記 「router.js」作成 「components」内にルーティングテンプレートファイル作成 front/scripts/vue-settings.sh #!/bin/bash set 'echo -e -o pipefail' # ルートディレクトリ取得 ROOT_DIR=$(cd $(dirname $0)/..;pwd) app_name='app' #************************************************************************************************ echo "「HelloWorld.vue」修正" #************************************************************************************************ sed -i -e "s/<h1>{{ msg }}<\/h1>/<h1>{{ msg }}<\/h1>\n<h2>現在の時間:{{ result }}<\/h2>\n<button @click=\"getAPI()\">クリック!<\/button>/" ${ROOT_DIR}/${app_name}/src/components/HelloWorld.vue sed -i -e "N;s/}\n<\/script>/, data () {\n return {\n result: 'No Result',\n url: 'http:\/\/localhost:8000\/api\/'\n }\n },\n methods: {\n getAPI () {\n this.\$axios.get(this.url).then(response => {\n this.result = response.data.status\n })\n }\n }\n}\n<\/script>/" ${ROOT_DIR}/${app_name}/src/components/HelloWorld.vue #************************************************************************************************ echo "main.js修正" #************************************************************************************************ cat > ${ROOT_DIR}/${app_name}/src/main.js << "EOF" import Vue from 'vue' import App from './App.vue' import axios from 'axios' import router from './router.js' Vue.config.productionTip = false Vue.prototype.$axios = axios new Vue({ router, render: h => h(App), }).$mount('#app') EOF #*********************************************************** echo "コンテンツテンプレート作成" #********************************************************** cat > ${ROOT_DIR}/${app_name}/src/router.js << "EOF" import Vue from 'vue' import Router from 'vue-router' import top from '@/components/top' import page2 from '@/components/page2' import page3 from '@/components/page3' Vue.use(Router) export default new Router({ mode: 'history', routes: [ { path: '/', component: top }, { path: '/page2', component: page2 }, { path: '/page3', component: page3 } ] }) EOF cat > ${ROOT_DIR}/${app_name}/src/components/top.vue << "EOF" <template> <div> <p>ここはトップページです。</p> <h2>現在の日本時間:{{ result }}</h2> <button @click="getAPI()">クリック!</button> </div> </template> <script> export default { name: 'jp-time', props: { msg: String }, data () { return { result: '不明', url: 'http://localhost:8000/api/jp' } }, methods: { getAPI () { this.$axios.get(this.url).then(response => { this.result = response.data.status }) } } } </script> <style> </style> EOF cat > ${ROOT_DIR}/${app_name}/src/components/page2.vue << "EOF" <template> <div> <p>ここは2ページ目です。</p> <h2>現在のアメリカ時間:{{ result }}</h2> <button @click="getAPI()">クリック!</button> </div> </template> <script> export default { name: 'us-time', props: { msg: String }, data () { return { result: '不明', url: 'http://localhost:8000/api/us' } }, methods: { getAPI () { this.$axios.get(this.url).then(response => { this.result = response.data.status }) } } } </script> EOF cat > ${ROOT_DIR}/${app_name}/src/components/page3.vue << "EOF" <template> <div> <p>ここは3ページ目です。</p> <h2>現在のブラジル時間:{{ result }}</h2> <button @click="getAPI()">クリック!</button> </div> </template> <script> export default { name: 'br-time', props: { msg: String }, data () { return { result: '不明', url: 'http://localhost:8000/api/br' } }, methods: { getAPI () { this.$axios.get(this.url).then(response => { this.result = response.data.status }) } } } </script> EOF #********************************************************* # "「App.vue」修正" #********************************************************* cat <<EOF > ${ROOT_DIR}/${app_name}/src/App.vue <template> <div id="app"> <div id="header"> <!--リンクタグを生成します。--> <router-link to="/">top</router-link>41 <router-link to="/page2">2</router-link> <router-link to="/page3">3</router-link> </div> <router-view></router-view> </div> </template> <!--コンポーネントの名前を定義します。--> <script> export default { name: 'App' } </script> <!--スタイルの指定をします--> <style> body { margin: 0; } #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } #header { height: 40px; background: white; box-shadow: 0px 3px 3px rgba(0,0,0,0.1); display: flex; justify-content: center; align-items: center; } #header a { text-decoration: none; color: #2c3e50; margin: 0 10px; padding: 3px 10px; background: #5ccebf; } </style> EOF Webサーバー すべてのアクセスをさばくプロキシサーバー役のコンテナ構成 ROM nginx:1.11.7 RUN mkdir /var/www RUN mkdir /var/www/app RUN mkdir /var/www/static アプリ用Nginxファイル web/conf/app_nginx.conf upstream back { ip_hash; server back:8001; # uWSGIでDjangoとnginxとが通信するためのポート server front:3000; # Vueとnginxとが通信するためのポート } server { listen 8000; # 待ち受けポート server_name 127.0.0.1; charset utf-8; client_header_buffer_size 1k; large_client_header_buffers 8 32k; add_header Strict-Transport-Security 'max-age=31536000'; add_header X-Frame-Options DENY; add_header X-XSS-Protection "1; mode=block"; error_page 500 502 503 504 /50x.html; location /static { alias /var/www/static; } # バックエンドサーバー location / { include /etc/nginx/uwsgi_params; uwsgi_pass back; # バックエンド proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } # バックエンド adminサーバー location /admin/ { include /etc/nginx/uwsgi_params; uwsgi_pass back; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } location = /50x.html { root /usr/share/nginx/html; } client_max_body_size 75M; } server_tokens off; uWSGI設定ファイル uwsgi_param QUERY_STRING $query_string; uwsgi_param REQUEST_METHOD $request_method; uwsgi_param CONTENT_TYPE $content_type; uwsgi_param CONTENT_LENGTH $content_length; uwsgi_param REQUEST_URI $request_uri; uwsgi_param PATH_INFO $document_uri; uwsgi_param DOCUMENT_ROOT $document_root; uwsgi_param SERVER_PROTOCOL $server_protocol; uwsgi_param REQUEST_SCHEME $scheme; uwsgi_param HTTPS $https if_not_empty; uwsgi_param REMOTE_ADDR $remote_addr; uwsgi_param REMOTE_PORT $remote_port; uwsgi_param SERVER_PORT $server_port; uwsgi_param SERVER_NAME $server_name; コンテナ起動 まずコンテナ全体を起動。 $ cd docker_spa $ docker-compose -d バックエンドにappディレクトリが作成&Djangoアプリ全体の設定ディレクトリ「config」とメインアプリディレクトリの「main」が作成されます。 webサーバー側のNginxも立ち上がるので http:localhost:8000 にアクセスで「インデックスページのコンテンツを表示中」のテキストが表示されていればDjangoとNginxの疎通はOK $ docker-compose run front vue create app . ? Please pick a preset: Default (Vue 2) ([Vue 2] babel, eslint) ? Pick the package manager to use when installing dependencies: NPM 続いて上記コマンドで新規Vueプロジェクトは初期設定の対話コマンドがあるので「 Vue2 」と「 npm 」を選択してインストールします。 結構時間かかりますがインストールが完了したら再度 docker-compose -d でビルドするとフロント側のセットアップスクリプトが実行されます docker_spa/ ┣━ back/ ┃ ┣━ app/ ┃ ┃ ┣━ config/ ┃ ┃ ┣━ main/ ┃ ┃ ┣━ static/ ┃ ┃ ┣━ templates/ ┃ ┃ ┣━ db.sqlite3 ┃ ┃ ┗━ manage.py ┃ ┣━ scripts/ ┃ ┣━ Dockerfile ┃ ┗━ requirements.txt ┣━ front/ ┃ ┣━ app/ ┃ ┃ ┣━ node_modules ┃ ┃ ┣━ public/ ┃ ┃ ┣━ src/ ┃ ┃ ┣━ babel.config.js ┃ ┃ ┣━ package-lock.json ┃ ┃ ┣━ package.json ┃ ┃ ┗━ vue.config.js # proxy設定ファイル ┃ ┣━ scripts/ ┃ ┣━ Dockerfile ┃ ┣━ package-lock.json ┃ ┗━ package.json ┣━ web/ ┃ ┣━ conf/ ┃ ┃ ┗━ app_nginx.conf ┃ ┣━ logs/nginx ┃ ┃ ┗━ access.log ┃ ┃ ┗━ error.log ┃ ┣━ Dockerfile ┃ ┗━ uwsgi_params ┃ ┗━ docker-compose.yml 上手くいけば上記の構成が出来上がってると思います。 http:localhost:8080 にアクセスするとVueのトップページが表示されます。 「top」「2」「3」でページが切り替わり、「クリック!」ボタンをクリックするとバックエンドとの通信を行い、現在の時刻を表示します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GROWIをオフライン環境で構築する方法

背景 職場のノウハウ共有のため、wikiの導入を検討 GROWIがかっこよかったので導入してみた(docker-compose) オフライン(インターネットにつながっていない)環境での導入に苦労した 同じようにオフラインでの導入で困っている人はご参考まで 環境 Dockerイメージ作成用サーバ CentOS 7.6 docker docker-compose インターネット接続あり GROWI 構築用サーバ CentOS 7.6 docker docker-compose インターネット接続なし 構築 Docker イメージの作成@イメージ作成用サーバ Github から docker-compose.yml を取得(git clone) git clone https://github.com/weseek/growi-docker-compose.git growi Dockerfile を編集し、オフライン用の Docker イメージを指定する ダウンロードしたディレクトリ配下に移動し、Dockerfile編集 cd growi vim Dockerfile Dockerfile(変更部分のみ記載) FROM weseek/growi:4.2.18-nocdn Docker Hub を参照し、"〜nocdn" がついた Tag を検索 今回は、4.2.18 が最新だったので指定("latest-nocdn" で最新バージョン指定するのもいいですね) docker-compose.yml を編集し、environment に "NO_CDN=true" を追記 docker-compose.yml(追記部分のみ記載) ports: - 3000:3000 # 外部からもアクセスできるよう ループバックアドレスを削除し、ポート番号のみ指定 environment: - NO_CDN=true デフォルトでは、127.0.0.1( localhost ) からのアクセスのみ許可するような設定になっているので、アドレス部分を削除し、他のアドレスからでもアクセスできるようにします。 "NO_CDN=true" を追記することにより、CDNを無効化します。 また、インターネットに接続できない環境で構築するので、利用する機能によっては、自前で別途サーバを構築し、対応する環境変数を指定する必要があります。 PlantUML: PLANTUML_URI HackMD: HACKMD_URI、HACKMD_URI_FOR_SERVE draw.io: DRAWIO_URI 私の場合は、draw.io による描画機能を使いたかったので、別途 drawio 用のDockerコンテナを構築し、DRAWIO_URI にコンテナの URI を指定しました。 ( 注意点としては、ブラウザから見た drawio サーバの URI を指定すること) docker-compose.yml(参考:drawioイメージ作成する場合は追記) drawio: image: fjudith/draw.io restart: unless-stopped ports: - 8080:8080 コンテナ起動(docker-compose up -d) docker-compose up -d docker-compose.yml に従い、いいようにベースのイメージの取得からイメージのビルドをしてくれます。 コンテナ起動後、ブラウザから、hostname(or IP address):3000にアクセスするとかっこいい画面が表示されました。 docker-compose.yml で別のポートをマッピングした場合は、そのポートにアクセスしましょう。 動作確認 GROWI を操作してみて、ページ作成や自前 draw.io によるお絵かきができることを確認します。 GROWI にて新規ページを作成し、drawio 起動ボタンをクリック 編集画面が表示されるのを確認し、適当に描いてみる 描いた絵が記事内に表示されました。 GROWI および draw.io のイメージがうまく作成できていることが確認できました。 作成したイメージをファイル出力(docker save) 作成したイメージをオフライン環境に移動させるため、docker save コマンドでファイル出力します。 docker save growi_app > growi_app.tar docker save growi_elasticsearch > growi_elasticsearch.tar docker save mongo > mongo.tar docker save fjudith/draw.io > drawio.tar 今回オフライン環境に持っていく必要があるのは、上記のイメージたちです。 weseek/growi というそれらしいイメージがあると思いますが、こちらは growi_app を作成するためのベースイメージなので、オフライン環境では不要です。 それぞれのイメージ名は、docker images コマンドで確認しましょう。 作成したイメージおよび docker-compose.yml をオフライン環境に展開 まずは作成したイメージをオフライン環境へ移動 USB 等なんらかの方法でファイルを移動する。 この時、docker-compose.yml も一緒に移動しておきます。 イメージファイルをロード(docker load) docker load < growi_app.tar docker load < growi_elasticsearch.tar docker load < mongo.tar docker load < drawio.tar イメージ名は、docker images コマンドで確認しておきましょう。 docker-compose.yml の編集 docker-compose.yml(ポイントのみ記載) services: app: image: growi_app # ロードしたイメージ名を記載 ports: - 3000:3000 environment: - NO_CDN=true - DRAWIO_URI=http://himitsu:8080 # URI はオフライン環境に合わせる mongo: image: mongo:4.4 # ロードしたイメージ名を記載 elasticsearch: image: growi_elasticsearch # ロードしたイメージ名を記載 drawio: image: fjudith/draw.io # ロードしたイメージ名を記載 restart: unless-stopped ports: - 8080:8080 コンテナ起動(docker-compose up -d) docker-compose up -d イメージファイルを読み込み、コンテナが作成されます。 GROWI にアクセスし、動作を確認 イメージ作成時と同様に、GROWI および draw.io がキチンと動いているか確認 無事に機能していれば作業完了 まとめ nocdn というタグがついた、オフライン環境用の Docker イメージを用意してくれているため、オフライン環境へのデプロイが非常にスムーズにできました。 UI もかっこいいですし、GROWI と Docker には感謝です。 わたしの場合は、今回紹介した nocdn イメージを用意してくれているという事実を知るのに少し時間がかかったので、「セキュリティの関係でインターネットに繋がっていない環境で GROWI をつかいたい」という方の一助になればと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む