20201015のdockerに関する記事は10件です。

Cloud RunとCloud Build で激安超簡単、月額10円・10分で出来るSSL/TLS独自ドメインWebサーバー構築

概要

Google Cloud Platform(以下GCP)のCloud Runを使って、独自ドメイン https:// 付きWebサーバを立てます。
Cloud Runは従量課金のPaaSで、無料枠もあり、アクセスの少ないサイトなら無料で公開できます。さらにManaged SSL証明書も無料で使えます。
HTML/CSSソースはGitHubに保存し、Commitをトリガーに自動デプロイを仕掛けます。
Cloud Run(フルマネージド)の料金

用意するもの

  • クレジットカード - ドメインを購入したりGCPの課金を有効化する際に使います。
  • Google Account - gmailアカウントでOK
  • GitHub Account

手順

ドメイン取得

お名前.comにて、.workドメインが1円セールだったので、foobarbar.work ドメインを取得しました。
image.png

GitHubリポジトリ初期化

取得したドメインと同じリポジトリを初期化。.gitingore とかはお使いの言語に合わせて適宜追加してください。
image.png

local Git 初期化

というかクローン。

PS D:\Projects> git clone git@github.com:standardsystem/foobarbar.work.git
Cloning into 'foobarbar.work'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
PS D:\Projects> cd .\foobarbar.work\
PS D:\Projects\foobarbar.work> ls

    Directory: D:\Projects\foobarbar.work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2020/10/15    21:36             40 README.md

PS D:\Projects\foobarbar.work> git branch
* main
PS D:\Projects\foobarbar.work>             

HTML投入

こちらからテンプレート頂きました。
https://colorlib.com/wp/template/mosh/

Dockerfile 追加

Cloud Run>ドキュメント>クイックスタート: ビルドとデプロイ から、Dockerfileのサンプルを持ってきます。COPYの所だけ、index.php から . へ変更。

Dockerfile
# Use the official PHP 7.3 image.
# https://hub.docker.com/_/php
FROM php:7.3-apache

# Copy local code to the container image.
COPY . /var/www/html/

# Use the PORT environment variable in Apache configuration files.
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf

# Configure PHP for development.
# Switch to the production php.ini for production operations.
# RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# https://hub.docker.com/_/php#configuration
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

.dockerignoreも追加。

.dockerignore
Dockerfile
README.md
vendor

Commit & Push

git add .
git commit -m 'First commit'
git push origin main

GCP Project 作成

https://console.cloud.google.com/ で新しいプロジェクトを作成します。
image.png

Cloud Run サービスの作成とCloud Buildの構成

メニューからCloud Runを選択、サービスの作成をクリックします。
image.png
フルマネージド、リージョンはTokyo。サービス名を入力し、未認証許可を選択。
image.png
「ソース リポジトリから新しいリビジョンを継続的にデプロイする」を選択。
image.png
「SET UP WITH CLOUD BUILD」をクリックし、2つのAPIを有効化します。
image.png

リポジトリを選択。
image.png
ブランチとビルド方法を選択。「作成」ボタンをクリックすると、Cloud Buildによりビルドが開始します。
image.png
image.png

テスト

Cloud Run機能に戻るとサービスができてます。
image.png
サービス名をクリックして詳細を表示するとURLが記載されているのでクリックします。
image.png
サイトができました。
image.png

独自ドメインの設定

カスタムドメインを管理。
image.png
マッピングを追加。
image.png
サービスを選択し、verify a new domain... で取得したドメインを入力。
image.png

image.png
ウェブマスターセントラルの指示に従い、TXTレコードをDNSに追加します。
image.png
追加したら数分待ち、ウェブマスターセントラルに戻って「確認」をクリックします。
image.png
マッピングの追加に戻り、ドメインを選択します。
image.png
表示されたDNSレコードを対象ドメインのゾーンレコードに追加します。
image.png
ドメインマッピングに戻り、ホスト名をクリックします。DNS浸透まで相応の時間がかかります。のんびり待ちましょう。
image.png

https://foobarbar.work/ が公開されました。
ソース
https://github.com/standardsystem/foobarbar.work

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Neo4jをAPOC付きで配備するdocker-compose

はじめに

Neo4jを利用する人が増えてきたとはいえ、まだまだ認知されていない状況。WindowsではNeo4j Desktopがあるので利用には不便しないのだけど、簡単なアプリケーションを作成して、それをチームに配布するとなると、イメージを作るには容量が大きくなるので、Dockerにすると楽。特に今のようなリモートワークをやっていたりするとなおさら。そこで、docker-composeでアプリとセットで配布しようと思ったところ、neo4jのdocker情報があまりなかったので、調べてみたいろいろやって動いたものを備忘として載せる。

フォルダ構成

https://github.com/MichitoIchimaru/neo4j_docker-compose

Folder
│  docker-compose.yml
├─ docker
│   └─neo4j
│      Dockerfile
│      background.sh
│      init.sh
│      init.cypher
└─volumes
   └─neo4j
      └─plugins
         apoc.jar

docker-compose.yml

docker-compose.yml
version: "3"

networks:
  app_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/24

services:
  neo4j:
    container_name: neo4j
    build: ./docker/neo4j
    volumes:
      - ./volumes/neo4j/data:/data
      - ./volumes/neo4j/plugins:/plugins
      - ./volumes/neo4j/logs:/logs
      - ./volumes/neo4j/import:/import
      - ./volumes/neo4j/init:/init
    ports:
      - "7474:7474"
      - "7687:7687"
    environment:
#      - NEO4JLABS_PLUGINS=["apoc"]
      - NEO4J_apoc_export_file_enabled=true
      - NEO4J_apoc_import_file_enabled=true
      - NEO4J_apoc_uuid_enabled=true
      - NEO4J_dbms_security_procedures_unrestricted=apoc.*
      - NEO4J_dbms_security_procedures_whitelist=apoc.*
      - NEO4J_dbms_memory_heap_initial__size=512m
      - NEO4J_dbms_memory_heap_max__size=2G
      - NEO4J_dbms_default__listen__address=0.0.0.0
      - NEO4J_dbms_connector_bolt_listen__address=:7687
      - NEO4J_dbms_connector_http_listen__address=:7474
      - NEO4J_dbms_connector_bolt_advertised__address=:7687
      - NEO4J_dbms_connector_http_advertised__address=:7474
      - NEO4J_dbms_allow__upgrade=true
      - NEO4J_dbms_default__database=neo4j
      - NEO4J_AUTH=neo4j/p@ssw0rd
      - EXTENSION_SCRIPT=/tmp/background.sh
    restart: unless-stopped
    networks:
      app_net:
        ipv4_address: 172.30.0.3
解説
#      - NEO4JLABS_PLUGINS=["apoc"]

この部分のコメントを外すと、apoc.jarをインターネットから自動でダウンロードしてくるようになる。今回はvolumes/neo4j/pluginsフォルダに最初からapoc.jarを格納しているので、ダウンロードは必要ないため、コメントアウトしている。
apoc.jarのダウンロードはかなり時間がかかるので、あらかじめダウンロードしておいたものを使う方が起動時間を短縮できる。ただし、この機能を有効化するメリットが1つある。今回はNeo4jのDockerイメージにneo4j:4.1.3(2020/10/15時点の最新は4.1.3)を利用しているが、neo4jのバージョンに対応したapoc.jarのバージョンが存在するため、組み合わせによっては動かない場合がある。このコメントを外すと、利用しているNeo4jのイメージに対応したapoc.jarを自動で判別し、インストールしてくれる。

      - NEO4J_AUTH=neo4j/p@ssw0rd

neo4jのパスワードを設定

      - EXTENSION_SCRIPT=/tmp/background.sh

このEXTENSION_SCRIPTがよく分からなかった。Neo4jのマニュアルでは何をするための用途なのか書いておらず、他者の記事を見るとNeo4j起動後に実行されるスクリプトであると書いてある。実際の挙動を見てみると、Neo4j起動後というよりは起動前に実行されているっぽい。なおかつこのスクリプトが正常に終了しないとNeo4jが起動されない様子。そのため、今回はbackground.shの中でinit.shを(&を付けて)実行するようにした。そうするとNeo4jも無事に起動され、バックグラウンドでinit.shがNeo4jの起動を待ち受けて初期データをセットアップしてくれる。ちなみに、EXTENSION_SCRIPTでinit.shを&付きで実行してもうまくいかなかった。

Dockerfile

FROM neo4j:4.1.3

RUN apt-get update
RUN apt-get install -y curl
COPY init.cypher /tmp/init.cypher
COPY background.sh /tmp/background.sh
COPY init.sh /tmp/init.sh
RUN chmod -v +x /tmp/background.sh
RUN chmod -v +x /tmp/init.sh

neo4jのイメージを配備すると、apt-getのパッケージリストが空なので、一旦apt-get updateを実行しないと、パッケージがインストールできない。ここでは、Neo4jの起動をチェック(Cypherを実行可能かを確認)するためにcurlをインストールするようにしている。
Proxy環境下の場合はここでENV http_proxy http://hogehogeなどを追加すると動くはず。

background.sh

background.sh
#!/bin/bash

/tmp/init.sh &

上でも解説しているが、EXTENSION_SCRIPTに指定して、init.shをバックグラウンド実行したいだけのシェル。こちらがinit.shで後述のinit.shがbackground.shの方が正しいんじゃないかという気が...。

init.sh

init.sh
#!/bin/bash

if [ -f /init/done ]; then
    echo "The initialization process is already completed." >> /init/setup.log
    exit 1
fi

COUNT=1

while [ $COUNT -lt 20 ]; do

  status_code=$(curl --write-out %{http_code} --silent --output /dev/null localhost:7474)
  if [[ "$status_code" = 200 ]] ; then
    touch /init/done
    cypher-shell -u neo4j -p p@ssw0rd -f /tmp/init.cypher
    echo "The initialization process is complete." >> /init/setup.log
    exit 1
  else
    echo "The neo4j service has not started yet. [$COUNT]" >> /init/setup.log
  fi

  COUNT=$(expr $COUNT + 1)
  sleep 10s

done

exit 0

このシェルは、起動したNeo4jに初期データを投入したいためのスクリプト。ただし、docker-composeを実行するとどうしてもこのスクリプトが毎回実行してしまうため、初回実行した際に/init/doneというファイルを作成し、そのファイルが存在すると何もせずに終了するようにしている。

解説
if [ -f /init/done ]; then
    echo "The initialization process is already completed." >> /init/setup.log
    exit 1
fi

この部分で/init/doneの存在チェックをして、あれば終了、なければ後続処理を実施。

while [ $COUNT -lt 20 ]; do

Neo4jが起動してくるまで20回(厳密にこのコードだと19回)リトライする。

  status_code=$(curl --write-out %{http_code} --silent --output /dev/null localhost:7474)

curlでhttp://localhost:7474 にアクセスし、HTTPレスポンスコードを取得。

  if [[ "$status_code" = 200 ]] ; then
    touch /init/done
    cypher-shell -u neo4j -p p@ssw0rd -f /tmp/init.cypher
    echo "The initialization process is complete." >> /init/setup.log
    exit 1
  else
    echo "The neo4j service has not started yet. [$COUNT]" >> /init/setup.log
  fi

curlの結果が200の場合、/init/doneを作成し、/tmp/init.cypherをcypher-shellコマンドで実行する。200でない場合、何もせずリトライする。

  COUNT=$(expr $COUNT + 1)
  sleep 10s

カウントアップと10秒スリープ。ちなみに、Neo4jイメージではカウントアップに(( COUNT++ ))は利用できなかった。

init.cypher

MATCH (n) return n;

初期セットアップCypher。ここではサンプルとして全ノード取得を書いているが、実際はCREATE文などを書く。

このinit.shがうまく実行されると、/init(volumes/neo4j/init)配下のsetup.logに下記のようなログが出力され、同様にdoneファイルも生成されるはず。

setup.log
The neo4j service has not started yet. [1]
The neo4j service has not started yet. [2]
The neo4j service has not started yet. [3]
The initialization process is complete.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker 初心者が Mattermost を docker-compose で立ち上げる話

はじめに

オンプレ型チャットツール「Mattermost」のプラグインを開発するために、
Mattermost サーバーを立てようとしていたのですが、

  • 初心者だけど Docker で楽に構築したい
  • Enterprise Edition を試したい
  • バージョン(5.27.0)を指定したい

という条件下でかなり苦戦してしまいました。
自分のために、そして同じ状況下で困っている方(がいるかわかりませんが)のために、
他に参考にした記事を引用しつつ、どんな流れで構築したかを記録しておきます。

前提

目指す環境

  • Mattermost Enterprise Edition(5.27.0)が動作する
  • Mattermost の DB には MySQL(8.0)を使用する
  • Mattermost まわりのあれこれを Docker で起動する
  • (おまけ)Mattermost のプラグインがファイルでアップロードできる

自分の環境

  • macOS Catalina 10.15.6
  • Docker
    • Desktop 2.3.0.4
    • Server Engine 19.03.12
    • Client Engine 19.03.12
  • Git 2.24.3 (Apple Git-128)

わたし

タイトルにもある通り、Docker ド初心者 です。

  • かろうじて自分のMacにDockerが入っている
  • docker run docker stop docker rm はとりあえず使える
  • めっちゃ頑張ったら起動中のコンテナのシェルに入れる
  • Docker イメージはなんとなくわかる
  • Dockerfile を雰囲気で読みながら生きてきた
  • docker-compose ってなんなん?

というレベルです。優しくしてください。

構築

というわけで、やってみましょう。

1. Mattermost-docker を用意する

今回は、Mattermost サーバーの設定を Docker で行うために、
以下のリポジトリをローカルにcloneします。

git clone https://github.com/mattermost/mattermost-docker.git

README を読んでみると、
「これ使うと、Mattermost サーバーを Docker 使って簡単にデプロイできるよ(意訳)」と。
なるほど...

2. docker-compose.yml を読んでみる

こちらの記事(Mattermost+MySQLのセットアップ (Docker) - Qiita)を参考に、
docker-compose.yml とやらを書き換えてみたいんですが、
その前に「そもそもこれなんやねん」ということで、ちょっと中身を覗いてみます。

docker-compose.yml
version: "3"

services:

  db:
    build: db
    read_only: true
    restart: unless-stopped
    volumes:
      - ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      - POSTGRES_USER=mmuser
      - POSTGRES_PASSWORD=mmuser_password
      - POSTGRES_DB=mattermost
    # uncomment the following to enable backup
    #  - AWS_ACCESS_KEY_ID=XXXX
    #  - AWS_SECRET_ACCESS_KEY=XXXX
    #  - WALE_S3_PREFIX=s3://BUCKET_NAME/PATH
    #  - AWS_REGION=us-east-1

  app:
    build:
      context: app
      # uncomment following lines for team edition or change UID/GID
      # args:
      #   - edition=team
      #   - PUID=1000
      #   - PGID=1000
    restart: unless-stopped
    volumes:
      - ./volumes/app/mattermost/config:/mattermost/config:rw
      - ./volumes/app/mattermost/data:/mattermost/data:rw
      - ./volumes/app/mattermost/logs:/mattermost/logs:rw
      - ./volumes/app/mattermost/plugins:/mattermost/plugins:rw
      - ./volumes/app/mattermost/client-plugins:/mattermost/client/plugins:rw
      - /etc/localtime:/etc/localtime:ro
      # When you want to use SSO with GitLab, you have to add the cert pki chain of GitLab inside Alpine
      # to avoid Token request failed: certificate signed by unknown authority (link: https://github.com/mattermost/mattermost-server/issues/13059)
      # - <path_to_your_gitlab_pki>/pki_chain.pem:/etc/ssl/certs/pki_chain.pem:ro
    environment:
      # set same as db credentials and dbname
      - MM_USERNAME=mmuser
      - MM_PASSWORD=mmuser_password
      - MM_DBNAME=mattermost

      # use the credentials you've set above, in the format:
      # MM_SQLSETTINGS_DATASOURCE=postgres://${MM_USERNAME}:${MM_PASSWORD}@db:5432/${MM_DBNAME}?sslmode=disable&connect_timeout=10
      - MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10

      # in case your config is not in default location
      #- MM_CONFIG=/mattermost/config/config.json

  web:
    build: web
    ports:
      - "80:80"
      - "443:443"
    read_only: true
    restart: unless-stopped
    volumes:
      # This directory must have cert files if you want to enable SSL
      - ./volumes/web/cert:/cert:ro
      - /etc/localtime:/etc/localtime:ro

どうやらdb app web の三層構造になってるようです。
この三層構造は別に Mattermost 特有の何かとかではなく、
一般的な Web三層アーキテクチャです。
その構造に沿って docker-compose.yml が記述されていると。

これまで docker run するたびに Apache だの SQL だの一個ずつ起動してたけど、
どうやら階層構造をちゃんと決めて、
アプリケーションに関連するものをまとめて起動してくれそうだぞ、という雰囲気がします。

3. docker-compose.yml を書き換える

なんとなく構成がわかったところで、目指す環境にあうように中身を書き換えていきます。
手っ取り早く進めたい方は以下のソースコードをコピペして、次のステップへ進んでください。

docker-compose.yml
docker-compose.yml
version: "3"

services:

  db:
    image: mysql/mysql-server:8.0
    # read_only: true
    restart: unless-stopped
    volumes:
      # - ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
      - ./volumes/db/var/lib/mysql:/var/lib/mysql
      - ./volumes/db/etc/my.cnf.d:/etc/my.cnf.d
      # - /etc/localtime:/etc/localtime:ro
    environment:
       - MYSQL_ROOT_PASSWORD=password
       - MYSQL_USER=mmuser
       - MYSQL_PASSWORD=password
       - MYSQL_DATABASE=mattermost
       - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`
    ports:
       - "33306:3306"
    # uncomment the following to enable backup
    #  - AWS_ACCESS_KEY_ID=XXXX
    #  - AWS_SECRET_ACCESS_KEY=XXXX
    #  - WALE_S3_PREFIX=s3://BUCKET_NAME/PATH
    #  - AWS_REGION=us-east-1

  app:
    build:
      context: app
      # uncomment following lines for team edition or change UID/GID
      args:
         - edition!=team
      #   - PUID=1000
      #   - PGID=1000
    restart: unless-stopped
    volumes:
      - ./volumes/app/mattermost/config:/mattermost/config:rw
      - ./volumes/app/mattermost/data:/mattermost/data:rw
      - ./volumes/app/mattermost/logs:/mattermost/logs:rw
      - ./volumes/app/mattermost/plugins:/mattermost/plugins:rw
      - ./volumes/app/mattermost/client-plugins:/mattermost/client/plugins:rw
      # - /etc/localtime:/etc/localtime:ro
      # When you want to use SSO with GitLab, you have to add the cert pki chain of GitLab inside Alpine
      # to avoid Token request failed: certificate signed by unknown authority (link: https://github.com/mattermost/mattermost-server/issues/13059)
      # - <path_to_your_gitlab_pki>/pki_chain.pem:/etc/ssl/certs/pki_chain.pem:ro
    environment:
      # set same as db credentials and dbname
      - MM_USERNAME=mmuser
      - MM_PASSWORD=mmuser_password
      - MM_DBNAME=mattermost
      - DB_PORT_NUMBER=3306
      - MM_SQLSETTINGS_DRIVERNAME=mysql
      - MM_SQLSETTINGS_DATASOURCE=mmuser:password@tcp(db:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s
      - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`
      # use the credentials you've set above, in the format:
      # MM_SQLSETTINGS_DATASOURCE=postgres://${MM_USERNAME}:${MM_PASSWORD}@db:5432/${MM_DBNAME}?sslmode=disable&connect_timeout=10
      # - MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10

      # in case your config is not in default location
      #- MM_CONFIG=/mattermost/config/config.json

  web:
    build: web
    ports:
      - "8080:80"
      - "8443:443"
    read_only: true
    restart: unless-stopped
    volumes:
      # This directory must have cert files if you want to enable SSL
      - ./volumes/web/cert:/cert:ro
      # - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

db

まずは MySQL を使うために、db の部分を書き換えます。

docker-compose.yml
   db:
-    build: db
-    read_only: true
+    image: mysql/mysql-server:8.0
+    # read_only: true
     restart: unless-stopped
     volumes:
-      - ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
+      # - ./volumes/db/var/lib/postgresql/data:/var/lib/postgresql/data
+      - ./volumes/db/var/lib/mysql:/var/lib/mysql
+      - ./volumes/db/etc/my.cnf.d:/etc/my.cnf.d
-      - /etc/localtime:/etc/localtime:ro
+      # - /etc/localtime:/etc/localtime:ro
     environment:
-      - POSTGRES_USER=mmuser
-      - POSTGRES_PASSWORD=mmuser_password
-      - POSTGRES_DB=mattermost
+      - MYSQL_ROOT_PASSWORD=password
+      - MYSQL_USER=mmuser
+      - MYSQL_PASSWORD=password
+      - MYSQL_DATABASE=mattermost
+      - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`
+    ports:
+       - "33306:3306"

なお、DB 関連のパスワードは password に設定しています。
よろしくないパスワードですが、今回はあくまで動作確認用なので目をつむります。
(気になる方はもちろん変更してください)

また、以下の部分は Docker のマウント失敗を回避するためのものです。

     volumes:
               ...(中略)...
-      - /etc/localtime:/etc/localtime:ro
+      # - /etc/localtime:/etc/localtime:ro

     environment:
               ...(中略)...
+      - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

app と web でも同様の設定が必要です。
(参考:Dockerで- /etc/localtime:/etc/localtime:ro がMount Deniedを出すやつ - Steady WorX はてな

app

Enterprise Edition を使うために、edition を設定します。
また、先ほど設定した DB の設定に合うように各種ポート番号などを書き換えます。

docker-compose.yml
  app:
    build:
       context: app
       # uncomment following lines for team edition or change UID/GID
-      # args:
-      #   - edition=team
+      args:
+         - edition!=team
       #   - PUID=1000
       #   - PGID=1000
    restart: unless-stopped
    volumes:
      - ./volumes/app/mattermost/config:/mattermost/config:rw
      - ./volumes/app/mattermost/data:/mattermost/data:rw
      - ./volumes/app/mattermost/logs:/mattermost/logs:rw
      - ./volumes/app/mattermost/plugins:/mattermost/plugins:rw
      - ./volumes/app/mattermost/client-plugins:/mattermost/client/plugins:rw
+      # - /etc/localtime:/etc/localtime:ro
    environment:
      - MM_USERNAME=mmuser
      - MM_PASSWORD=mmuser_password
      - MM_DBNAME=mattermost
+      - DB_PORT_NUMBER=3306
+      - MM_SQLSETTINGS_DRIVERNAME=mysql
+      - MM_SQLSETTINGS_DATASOURCE=mmuser:password@tcp(db:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s
+      - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

       # use the credentials you've set above, in the format:
       # MM_SQLSETTINGS_DATASOURCE=postgres://${MM_USERNAME}:${MM_PASSWORD}@db:5432/${MM_DBNAME}?sslmode=disable&connect_timeout=10
-      - MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10
+      # - MM_SQLSETTINGS_DATASOURCE=postgres://mmuser:mmuser_password@db:5432/mattermost?sslmode=disable&connect_timeout=10

       # in case your config is not in default location
       #- MM_CONFIG=/mattermost/config/config.json

web

最後に web も少しだけ書き換えます。
ポート番号の設定変更くらいですね。

docker-compose.yml
   web:
     build: web
     ports:
-      - "80:80"
-      - "443:443"
+      - "8080:80"
+      - "8443:443"
     read_only: true
     restart: unless-stopped
     volumes:
       # This directory must have cert files if you want to enable SSL
       - ./volumes/web/cert:/cert:ro
-      - /etc/localtime:/etc/localtime:ro
+      # - /etc/localtime:/etc/localtime:ro
+    environment:
+      - TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

4. バージョンを指定する

今回は 5.27.0 のバージョンで動作させたかったので、
バージョンを指定するために環境変数を設定します。
mattermost-server/app/Dockerfile をみてみると、

mattermost-server/app/Dockerfile
# Some ENV variables
ENV PATH="/mattermost/bin:${PATH}"
ENV MM_VERSION=5.27.0
ENV MM_INSTALL_TYPE=docker

バージョン指定のための環境変数があることがわかります。
他のバージョンに変更したい方は、MM_VERSIONの値を好きに変えてください。
デフォルトは 5.27.0 のようです。

5. マウント用ディレクトリの作成

mkdir -pv ./volumes/app/mattermost/{data,logs,config,plugins,client-plugins}

先にマウント用ディレクトリを用意しておきます。
これをすっ飛ばすとあとで怒られます。

6. いざ、docker-compose up!

docker-compose up -d --build

お、なんだかできてそうな出力結果...!

Successfully tagged mattermost-docker_web:latest
Creating mattermost-docker_app_1 ... done
Creating mattermost-docker_db_1  ... done
Creating mattermost-docker_web_1 ... done

先ほど設定したポートは 8080 だったので、
http://localhost:8080 を開いてみましょう。

Screenshot 2020-10-15 21.51.26.png

おおー!ちゃんと表示されました!よかったよかった。

7. 停止

立ち上げたコンテナは止めましょう。ということで

docker-compose stop

すれば、コンテナを止めることができます。

まとめ

というわけで、本記事では、docker-compose.ymlを書き換えながら
Mattermost を三層構造のWebアプリケーションとして立ち上げました。
同じように環境構築で困っている人や、未来の自分に役立つ記事になっていれば嬉しいです。

個人的には、docker-compose.yml まじでわからん、から
何書くもんなんか大体分かったわ、くらいにはなれたのが収穫です。物は試し。

おまけ:プラグイン開発したい人向け

今回はプラグイン開発環境するぞー!ってことでこの環境を作ったわけですが、
プラグインをシステムコンソールからアップロードしようとすると
Screenshot 2020-10-15 21.53.41.png
アップロードボタンが灰色になっている....

というわけで、起動中のコンテナ(app)に入って書き換えました。
私は Docker Desktop から CLI を起動しちゃいましたが、

docker ps

で app の ID を調べて、

docker exec -it <appのID> /bin/sh

としたらコンテナに入れますね。

書き換えが必要なのは以下の部分。

app/config/config.json
   "PluginSettings": {
     "Enable": true,
-    "EnableUploads": false,
+    "EnableUploads": true,
     "Directory": "./plugins",
     "ClientDirectory": "./client/plugins",
     "Plugins": {},

なんでデフォルトは false なんでしょうね...
なにはともあれ、これで解決。

Screenshot 2020-10-15 22.07.20.png

アップロード用のボタンが現れ、アップロードも無事に出来ました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerの概要(初学者向け)

はじめに

Dockerは多くのIT開発企業で導入されている技術です。
エンジニアを目指す方の多くは今後使用することとなるため、学習した内容を簡単にまとめようと思います。

Dockerとは?

一言で言うと、環境構築を楽にさせるものです。
通常、アプリケーションを開発する際は、環境構築から始まります。
環境構築をする時はいくつものパッケージをダウンロードします。
その際、エラーが出て、トラブルシュートしたりと大変な作業となり、
これをチームメンバー全員が行うことになります。
また、開発環境、テスト環境、本番環境でも環境構築を気に掛ける必要があります。
Dockerではコンテナを起動するだけで環境構築が完了するため、環境構築が非常に楽になります。

コンテナとは?

通常、コンテナと言うものは内部にものを入れることができる容器のことです。
Dockerでのコンテナは、自身のPCやサーバーに多数作成でき、開発環境や実行環境、パッケージ、ライブラリをインストールすることができる箱のようなものです。
コンテナの中で作業したり、コンテナを使ってスクリプトを動かすことができます。
一つコンテナを作れば、それを誰かに渡したり、テスト環境や本番環境に渡したりすることができます。

コンテナの作り方

Docker file => Docker image => コンテナ

Docker fileを作成し、そこからDocker imageを作成します。
このDocker imageからコンテナを作成することができます。

Docker Hub

多くのパッケージはDocker Hubの中に用意されています。
Gitで言うGit Hubのようなものです。
Docker imageをpublicで管理する時にDocker Hubを使い、
Docker imageをpullすることで、コンテナを作成することができます。

参考

Udemy

かめれおん講師 「米国AI開発者がゼロから教えるDocker講座」

https://www.udemy.com/share/103aTRAEAdd1pTTHoC/

有料ですが、初学者の私にも非常に理解しやすかったです。

最後に

本投稿が初学者の復習の一助となればと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Hugo] Learn で構築したサイトにページを追加する方法まとめ

概要

Hugo で構築したサイト(テーマ:Learn)にページの追加とレイアウトを適用する手順についてまとめる。

前提

上記に記載の手順環境構築、ページの作成を行っており、「content」 フォルダに以下に posts フォルダがあることを前提として説明する

content
└── posts
    └── my-first-post.md

現時点で完成しているページ
スクリーンショット 2020-09-16 23.06.41.png

ゴール

ページ(子)の追加とインデックスページ(親)の設定を行い、以下のようなサイトを作成することをゴールとする

サイト

スクリーンショット_2020-10-15_15_55_18.png

フォルダ構成

最終的なファイル構成は以下の通り

content
├── _index.md         // baseurl 
└── posts   
    ├── _index.md     // .../post 
    ├── my-first-post.md    // .../post/my-first-post
    └── my-second-post.md   // .../post/my-second-post

サイトのインデックスページ、ページの設定はフォルダ構成に依存する

ページの作成

hugo newコマンドを実行することでページ(子)が作成される。
前回の記事で、以下のコマンドを実行済

hugo new posts/my-first-post.md 

このコマンドを実行することで、「archetypes」フォルダの「default.md」 ファイルに記載している内容が指定した.md ファイルに追加される。

デフォルトで追加される項目は以下の通り

default.md
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

これらのパラメーターを埋めることで、Web サイトを作ることができる。

目次のタイトル名の変更方法

目次のタイトルの変更方法について説明する
スクリーンショット_2020-10-13_15_03_04.png

タイトルは、「my-first-post.md」の「title:」で設定しているため、ここの文字列を変更する

my-first-post.md
---
title: "My First Post" // ここで指定している
date: 2020-XX-XX
draft: true
---

# タイトル
hoge サイトを作成してみる

title: "第1章"に変更すると、以下の 3 箇所が変更される
スクリーンショット_2020-10-13_15_13_24.png

ページ(子)の追加方法

ページの追加方法は、以下の2通り
1.新規でページを作成した時と同様に、hugo new コマンドで実行
2.hugo newコマンドを実行した時に追加される項目を手動で記入

default.md ファイルの中身をコマンドで行うか、手動で入力するかの違いである

ここでは、「my-first-post.md」をコピーして、「my-second-post.md」と名前を変更し、同じ階層に保存し、ページを追加する

my-second-post.md
---
title: "第2章"
date: 2020-XX-XX
draft: true
---

# ページの追加
my-first-post.md をコピーして中身を修正し、my-second.mdファイルとして保存

ページが追加された
スクリーンショット 2020-10-13 15.27.02.png

インデックスページ(親)の追加

「Post」 や「My New Hugo Site」をクリックした時に、表示されるページの設定を行いたい
スクリーンショット_2020-10-13_15_34_02.png
現在のファイル構成をみると、以下の通りになっている。これらは、インデックスページと呼ばれる、親ページである。Learn ガイド:_index.md

content
└── posts
    ├── my-first-post.md
    └── my-second-post.md

デフォルトでは、「Post」 や 「My New Hugo Site」 ページを構成しているファイルがない。それぞれのフォルダに_index.mdを作成することで、ページを構成できる。

content > _index.md の追加
_index.md
---
title: "サイトの案内"
date: 2020-XX-XX
draft: true
---
このサイトでは、Learn のカスタマイズをテストしています。

スクリーンショット 2020-10-13 15.49.22.png

posts > _index.md の追加
_index.md
---
title: "カスタマイズ手順"
date: 2020-XX-XX
draft: true
---
# Learn のカスタマイズ
_index ファイルを作成することで、このページを編集できるようになります。

スクリーンショット 2020-10-13 15.49.13.png

ここまでの操作で、以下のようなファイル構成となった

content
├── _index.md
└── posts
    ├── _index.md
    ├── my-first-post.md
    └── my-second-post.md

ページのレイアウトの適用

Learn では通常のページのレイアウトの他に、チャプターページ用のレイアウトを提供している
Learn ガイド:Create your first chapter page
ヘッダー部分に、chapter: true と追記し、以下のように記載することでレイアウトが適用される

### 小見出し
# タイトル
ここに文章をかく

posts > _index.md ファイルにチャプター用のレイアウトを適用

_index.md
---
title: "カスタマイズ手順"
date: 2020-XX-XX
draft: true
chapter: true // 追記
---
### 初心者向け
# Learn のカスタマイズ
_index ファイルを作成することで、このページを編集できるようになります。

スクリーンショット 2020-10-13 16.01.23.png

参考

Hugo Learn ガイド
Hugo コンテンツ編成

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

The Biostar Handbook が面白すぎる件

これはbiostars とは全く関係のない人が The Biostar Handbook というネットで販売されている本を紹介するページです。
IT技術に関係する記事ですので、問題はないと思いますが、もしもなにかありましたらご一報ください。

Biostars をご存知ですか?

biostarsは、バイオインフォマティックス領域のstackoverflowとでも言うべきQ&Aサイトです。バイオインフォマティックスでは、初心者向けの日本語の資料があまり多くはありません。そのような状況で、biostarsを検索すると親切な回答が掲載されていることが多く、非常に参考になりますね。実際に自分で質問してみたこともありますが、丁寧で良質な回答がつくことが多いのでとても便利です。

そんな biostars が handbook を販売しているということで、購入してみました。

https://biostar.myshopify.com/

価格は非常に安くて、2500円とか、3500円とか、そのぐらいの値段です。学術書の値段を考えると、本当にお買い得の価格だと思います。

image.png

(バイオインフォの本としては驚きの価格だ!)

私はPaypalで支払いをしましたが、日本からでも全く問題なく購入できます。

Biostar handbook は英語が読めなくても大丈夫!

さて、biostar handbook を買ったはいいのですが、私は英語が苦手です。でも、biostars はログインしてウェブサイトで読むことが可能なんです! ということは当然chromiumによるGoogle翻訳が活用できます。

image.png

(日本語で読める、読めるぞ!)

もちろん原文を確認しなければならない箇所もあるでしょうが、通読する分にはこれで十分だろうというかなり高いレベルの日本語で読み進めることができます。そして、質量ともに、これほどまとまったバイオインフォマティックスの初心者向け日本語の資料は地球上に存在しないと言い切ってよいでしょう。

Biostar Handbook のおもしろすぎるところ!

時間を無駄にしない方法が面白すぎる

さて、biostarハンドブックを買って一番おもしろかったのが、「時間を無駄にしない方法」という項目です。あまりにも面白かったので、どっかーの方面からお叱りが入るかも知れませんが引用したいと思います。

Dockerに対する言及

image.png

どうですか?最高じゃないですか?次に、AWSに対する言及を見てみましょう

image.png

解析プラットフォームに対する言及を見てみましょう

image.png

CWLに対する言及を見てみましょう

image.png

この面白さは、なにもCloud業者やDockerに対してだけではありません。
GATKについての言及を見てみましょう

image.png

いやあもう最高だと思います。(気分を悪くされましたか?)日本でこんなことを書かれた本を販売したら、クレームが来るかも知れません。

しかし、全てのツールは誰かの手によって作られたものです。単に盲信するのではなく、どこがダメなのかを知る。愛のある健全な批判的な精神でながめるというのは必要でしょう。

これで興味がわいたらぜひBiostar Handbookを手にとってみてください。

https://www.biostarhandbook.com/

上はあえておもしろい記述をあげましたが、全体的にはとてもわかりやすく書かれた初心者向けの充実した教科書っていう感じです。

バイオインフォマティックス初心者のために、このぐらいわかりやすい初心者向けの日本語の教科書があったらなぁと思います。学力もなく英語もできないので勉強するのが大変です!

最後に、私はbiostarsのお世話になってるユーザーですが、biostarsとは何らの利害関係はありません。Biostar Handbookを宣伝しても私の手元には1円も入りません。でもこの魅力的なハンドブックを見てると宣伝したくなってしまいました。

この記事は以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

The Biostars Handbook が面白すぎる件

これはbiostars とは全く関係のない人が biostars handbook というネットで販売されている本を紹介するページです。
IT技術に関係する記事ですので、問題はないと思いますが、もしもなにかありましたらご一報ください。

Biostars をご存知ですか?

biostarsは、バイオインフォマティックス領域のstackoverflowとでも言うべきQ&Aサイトです。バイオインフォマティックスでは、初心者向けの日本語の資料があまり多くはありません。そのような状況で、biostarsを検索すると親切な回答が掲載されていることが多く、非常に参考になりますね。実際に自分で質問してみたこともありますが、丁寧で良質な回答がつくことが多いのでとても便利です。

そんな biostars が handbook を販売しているということで、購入してみました。

https://biostar.myshopify.com/

価格は非常に安くて、2500円とか、3500円とか、そのぐらいの値段です。学術書の値段を考えると、本当にお買い得の価格だと思います。

image.png

(バイオインフォの本としては驚きの価格だ!)

私はPaypalで支払いをしましたが、日本からでも全く問題なく購入できます。

Biostar handbook は英語が読めなくても大丈夫!

さて、biostar handbook を買ったはいいのですが、私は英語が苦手です。でも、biostars はログインしてウェブサイトで読むことが可能なんです! ということは当然chromiumによるGoogle翻訳が活用できます。

image.png

(日本語で読める、読めるぞ!)

もちろん原文を確認しなければならない箇所もあるでしょうが、通読する分にはこれで十分だろうというかなり高いレベルの日本語で読み進めることができます。そして、質量ともに、これほどまとまったバイオインフォマティックスの初心者向け日本語の資料は地球上に存在しないと言い切ってよいでしょう。

Biostars handbook のおもしろすぎるところ!

時間を無駄にしない方法が面白すぎる

さて、biostarsハンドブックを買って一番おもしろかったのが、「時間を無駄にしない方法」という項目です。あまりにも面白かったので、どっかーの方面からお叱りが入るかも知れませんが引用したいと思います。

Dockerに対する言及

image.png

どうですか?最高じゃないですか?次に、AWSに対する言及を見てみましょう

image.png

解析プラットフォームに対する言及を見てみましょう

image.png

CWLに対する言及を見てみましょう

image.png

この面白さは、なにもCloud業者やDockerに対してだけではありません。
GATKについての言及を見てみましょう

image.png

いやあもう最高だと思います。(気分を悪くされましたか?)日本でこんなことを書かれた本を販売したら、クレームが来るかも知れません。

しかし、全てのツールは誰かの手によって作られたものです。単に盲信するのではなく、どこがダメなのかを知る。愛のある健全な批判的な精神でながめるというのは必要でしょう。

これで興味がわいたらぜひbiostars handbookを手にとってみてください。

https://www.biostarhandbook.com/

上はあえておもしろい記述をあげましたが、全体的にはとてもわかりやすく書かれた初心者向けの充実した教科書っていう感じです。

バイオインフォマティックス初心者のために、このぐらいわかりやすい初心者向けの日本語の教科書があったらなぁと思います。学力もなく英語もできないので勉強するのが大変です!

最後に、私はbiostarsのお世話になってるユーザーですが、biostarsとは何らの利害関係はありません。Biostars handbookを宣伝しても私の手元には1円も入りません。でもこの魅力的なハンドブックを見てると宣伝したくなってしまいました。

この記事は以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナ内のUbuntuではsystemctlは使えない

はじめに

システムやアプリケーションを作るにあたり、Dockerコンテナ上で構築ができれば、開発やメンテの効率に繋がるかと思い色々と試しみたので、その基礎的なことをまとめる。
 ※一番ハマったところをタイトルにした。

前提条件

【ホストOS】
 ・Ubuntu20.04 LTS(GCP上)

【ソフト・イメージ Version】
 ・docker19.03.13
 ・コンテナイメージのOS Ubuntu20.04 LTS

やりたい事

1.dockerのインストールと設定
2.dockerにコンテナ作成
3.コンテナに入ってApache起動
4.イメージファイルを改造して再度イメージ化

1.dockerのインストールと設定

Docker社のリポジトリからインストールする場合は、以下の手順となる。
※バージョン14.04以降、aptコマンドが推奨となっているためapt-getは使用しない。

Dockerがインストールされていない事を確認

$ sudo dpkg -l docker

パッケージ管理ツールのアップデート

$ sudo apt update

dpkg-query: no packages found matching docker と表示されればインストールされていない。

Dockerインストールに必要なソフトインストール

$ sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

Docker公式のGPG公開鍵を追加

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

ちゃんと公開鍵が追加されたか確認

$ sudo apt-key fingerprint

Qiita-no010_img04.jpg

リポジトリの追加

リポジトリにdockerがない事を確認。
 ※以下のコマンドを実行しても、何も表示されないはず。

$ cat /etc/apt/sources.list | grep docker

リポジトリの設定

$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

リポジトリが追加された事を確認

$ cat /etc/apt/sources.list | grep docker
deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable
# deb-src [arch=amd64] https://download.docker.com/linux/ubuntu focal stable

使用可能なバージョンを確認

$ apt-cache madison docker-ce
 docker-ce | 5:19.03.13~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.12~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.11~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.10~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
 docker-ce | 5:19.03.9~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages

dockerのインストール

リポジトリが追加されたため再度updateしてからinstallを実行

$ sudo apt update
$ sudo apt install docker-ce

インストールしたdockerのバージョンを確認

$ sudo docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:02:52 2020
 OS/Arch:           linux/amd64
 Experimental:      false

デーモンが起動されているか確認

$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2020-09-30 00:22:29 UTC; 30min ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 25020 (dockerd)
      Tasks: 9
     Memory: 36.8M
     CGroup: /system.slice/docker.service

dockerの動作確認

Hello world サンプルdockerイメージを取得して実行。

$ sudo docker container run hello-world

現在のイメージとコンテナの一覧を確認

# イメージの一覧表示
$ sudo docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              bf756fb1ae65        9 months ago        13.3kB

# コンテナの一覧表示(停止中を含む)
$ sudo docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS   
            NAMES
e8a73ecd0c16        hello-world         "/hello"            5 minutes ago       Exited (0) 5 minutes ago           
            condescending_diffie

# 起動中のコンテナ表示
$ sudo docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS          
     NAMES

※hello-worldのコンテナはメッセージ出力後にコンテナを停止してしまうので起動中になっていない。

動作確認ができたので一旦コンテナとイメージの削除。

$ sudo docker container rm [コンテナID]
$ sudo docker image rm [イメージID]

dockerの設定

自動起動の設定

$ sudo systemctl unmask docker.service
$ sudo systemctl enable docker
$ sudo systemctl is-enabled docker

sudoなしでdockerコマンド実行するためdockerグループに追加。

# まずは[docker]グループの確認。 ※グループがない場合は自分で作成する必要がある。
$ cat /etc/group | grep docker
docker:x:998:

# [docker]グループにユーザーを追加。
$ sudo usermod -aG docker [ユーザー名]

Ubuntuの再起動後、以下の様にsudoなしでコマンドを実行できれば設定変更はできている。
※再起動はGCP上でVMインスタンスを作成しているため、GCPから実行)

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

2.dockerにコンテナ作成

コンテナはdockerイメージを使って構築するので、まずはdockerイメージを取得する。
dockerのサイトには既にたくさんのイメージが公開されているので、検索コマンドで目的のイメージを探してきて、イメージを取得する

取得するイメージの確認

$ docker search 【任意なキーワード】

イメージの取得

# docker image pull [OPTIONS] NAME[:TAG|@DIGEST]
$ docker image pull  ubuntu:20.04

20.04: Pulling from library/ubuntu
d72e567cc804: Pull complete 
0f3630e5ff08: Pull complete 
b6a83d81d1f4: Pull complete 
Digest: sha256:bc2f7250f69267c9c6b66d7b6a81a54d3878bb85f1ebb5f951c896d13e6ba537
Status: Downloaded newer image for ubuntu:20.04
docker.io/library/ubuntu:20.04

※今回はホストOSがUbuntu20.04の上に、Ubuntu20.04のコンテナを作成。

イメージからコンテナ作成

$ docker container run -it -d --name test-ubuntu20-4 ubuntu:20.04

# ポート番号を紐づけたい時
# docker container run -it -d -p 8080(Ubuntu側のポート):5000(コンテナ側のポート) --name webgis-server ubuntu:20.04

※1).イメージがローカルホストに存在しない場合、docker container run実行時にそのイメージをリポジトリから自動的にpullして、コンテナを作成してくれる。
※2).[オプション]コマンドがない場合、コンテナは起動後すぐに終了してしまう。

起動しているコンテナを確認

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS          
     NAMES
19b7ac7c40ad        ubuntu:20.04        "/bin/bash"         8 seconds ago       Up 7 seconds                       
     test-ubuntu20-4

3.コンテナに入ってApache起動

先程作成したコンテナ(test-ubuntu20-4)に入る

$ docker attach test-ubuntu20-4

※一度 exit で出るとコンテナが停止されるため、再度入る時には docker container start [コンテナ名] で起動させてから。

パッケージ管理ツールのアップデート。

# apt update

Apacheのインストール

# apt install -y apache2

※初めて何かパッケージをインストールすると、途中でエリアやタイムゾーンを聞かれるため、それぞれ以下の様に設定。
  ・Geographic area:6(Asia)
  ・Time Zone:79(Tokyo)

Apacheの起動状態を確認。

# systemctl status apache2
bash: systemctl: command not found

上記の様なメッセージが表示されてオペレートできないため、systemctlを使える様にパッケージのインストール 。(単純な起動などは service apache2 ~~~~のコマンドでできる。)

# apt install -y systemd

再度Apacheの起動状態を確認。

# systemctl status apache2
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

PID1に問題がありそうとのことなので確認してみる。

# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.5  0.1   4240  3384 pts/0    Ss   16:40   0:00 /bin/bash
root           8  0.0  0.1   5888  2912 pts/0    R+   16:40   0:00 ps aux 


実は docker container run -it -d --name ubuntu:20.04コマンドでコンテナを作成すると、コンテナ内Ubuntuの[PID:1]のCOMMANDが/sbin/bash となってしまう。
これだと、systemctl のコマンドが使えない様子。

※試しに最初のコンテナ作成時に、以下のコマンドで初期プロセスを /sbin/init に指定してみたが、イメージに /sbin/init が存在しないと言われる。

# テスト実行のため、今回の一連の作業としては実行不要。
$ docker container run -it -d --privileged --name webgis-server ubuntu:20.04 /sbin/init

docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process c
aused "exec: \"/sbin/init\": stat /sbin/init: no such file or directory": unknown.

/sbin/init が存在する Ubuntuをイメージ化すればできるかも!

4.イメージファイルを改造して再度イメージ化

/sbin/init/usr/lib/systemd/system/ へのシンボリックリンクとして作成。

# ln -s  /usr/lib/systemd/system/ /sbin/init

元のイメージに Apache2とSystemdのインストール 、/sbin/initの作成 をしたコンテナになっているので、一旦コンテナから出て停止したコンテナからイメージを作る。

$ docker commit test-ubuntu20-4 test-ubuntu20-4:add-init
sha256:5f25a8ff7149b22665aeb4d076919ba06d7e5c3f06c77834e60c6a7e042e6bf2

# イメージの一覧を確認
$ $ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
test-ubuntu20-4     add-init            91fffb874bf9        About a minute ago   202MB
ubuntu              20.04               9140108b62dc        2 weeks ago          72.9MB
hello-world         latest              bf756fb1ae65        9 months ago         13.3kB

イメージファイルから再度コンテナ作成

先程作成したイメージからコンテナ作成

$ docker container run -it -d --privileged --name test-ubuntu20-4-2 test-ubuntu2
0-4:add-init /sbin/init

af59767d9b17c60fcb5284ec3669bc61edb5f4a7e5a019b5c572997553d43e9f
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process c
aused "exec: \"/sbin/init\": permission denied": unknown.


今度はアクセス権がないとか言われ、結局[PID1 = /sblin/init]で起動させることは難しそう。
色々と調べてみたが、dockerコンテナ内ではプロセス管理ツールとしてsystemdは基本的に使えない。
(無理矢理やればできない事もないかもしれないが、そこまでするメリットもなさそう。)

 ・参考サイト1
 ・参考サイト2

まとめ

まずはdockerのインストールやコンテナの作成手順を簡単にまとめてみたが、VMとコンテナでは動作に使われるカーネルが異なるため、同じ様にプロセス管理ツールは使えない。
コンテナ内でサービスを作る場合、[PID1=init] が前提でdaemon化するプログラムは動作しない事を理解しておく。
dockerでプロセス管理を行いた場合、Supervisor というのが一般的らしい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker-composeのnode_modules問題にぶちあったたときにやった対処方法

どんな問題?

最近、docker-composenodeの環境を構築するとき、コンテナ内のnode_modulesがどっかに行ってしまうという問題に遭遇した。

いろいろ調べてみると、docker-composeでローカルのディレクトリをコンテナ内にマウントする際に、上書きされてしまい、コンテナ内のnode_modulesが消えてしまっているようだ。

どう解決したの?

https://qiita.com/suin/items/e53eee56da23d476addc の記事などを見ると、volumesを作成し、node_modulesをそこにマウントすることで、回避することができるようだ。
しかし、これだとローカル環境にnode_modulesが生成されないため、TypeScriptでパッケージの型定義を参照できず、TypeScriptを使うことの旨味が薄れてしまう。

この問題を解決するために、docker-composecommandyarn installもすることで、コンテナ内のnode_modulesをローカルにマウントされるようにして、ローカルにnode_modulesを持ってくるようにしている記事を見た。
だが、この方法だとdocker-compose upをするときにyarn installが走ってしまうため、docker-compose upでまあまあな時間がかかってしまった。(ローカルにコンテナ内のnode_modulesを持ってくるのにもめちゃめちゃ時間がかかっているようだった)

そこで、以下のような方法で解決をするようにした。(この解決方法がBadであれば、教えていただけると勉強になります)

.
├── app
│   ├── Dockerfile
│   └── src
│       ├── package.json
│       └── yarn.lock
└── docker-compose.yml
Dockerfile
FROM node
WORKDIR /app
ADD src/package.json /app/
ADD src/yarn.lock /app/
RUN yarn install
docker-compose.yml
volumes: # ←追加
  app_node_modules: # ←追加
services:
  app:
    image: ./app
    volumes:
      - ./app/src:/app/
      - ./app/src/node_modules:/app/node_modules # ←追加
# 以下略

ここまでは https://qiita.com/suin/items/e53eee56da23d476addc の記事と同じだ。
これにプラスで、パッケージを追加したときに以下のスクリプトを実行すること(docker-compose buildの代わり)で、ローカルにもnode_modulesを生成するようにした。

build.sh
docker-compose build
cd app/src && yarn install

とりあえずこれで、node_modulesが消えてしまう問題と型定義がない問題を解決することができた。
しかし、ローカル環境にnodeがあることが前提になってしまっているため、もっといい解決方法があればいいな〜と思っている。(が、わからなかった)

おわりに

いい解決方法があればぜひ教えていただけると嬉しいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker[<none>タグの一括削除]

Dockerのタグを一括削除する!

Dockerを触ってるとこんな感じで不要なimage(noneタグ)がいっぱい溜まりますよね〜

$docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
portfolio_api             latest              9091a77d3e50        3 minutes ago       661MB
<none>                    <none>              bda133c88b3a        3 hours ago         659MB
portfolio_front           latest              206c69e39bc8        5 hours ago         325MB
<none>                    <none>              c9c1cc1f82af        3 days ago          325MB
<none>                    <none>              90b26537b543        3 days ago          659MB
rails_nuxt_docker_front   latest              6a76df1e3e15        8 days ago          652MB
rails_nuxt_docker_api     latest              f81ab2aa1da3        9 days ago          664MB
node                      14.11.0-alpine      b85fc218c00b        4 weeks ago         117MB
ruby                      2.7.1-alpine        b46ea0bc5984        3 months ago        52.3MB
postgres                  12.3-alpine         17150f4321a3        3 months ago        157MB
node                      14.4.0-alpine       3bf5a7d41d77        4 months ago        117MB

こいつらが溜まるとGBが喰われて非常に厄介なのです。

$ docker rmi <IMAGE ID>

でチマチマ消すのも面倒なので一括でnoneタグを取得して削除しましょう!

noneタグのみ抽出

  • $docker images-fオプションをつけると検索フィルターをかけることができます
  • 'dangling=true'でnoneタグ(dangling image)を指定できます
$ docker images -f 'dangling=true'
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
<none>                    <none>              bda133c88b3a        3 hours ago         659MB
<none>                    <none>              c9c1cc1f82af        3 days ago          325MB
<none>                    <none>              90b26537b543        3 days ago          659MB

本題<noneタグ>の一括削除

上記のオプションを$docker rmiにぶち込みましょう!!!

$docker rmi $(docker images -f 'dangling=true')
Deleted: sha256:bda133c88b3a3aca1cdd971ffe23a2bea32295e782d1225b7753151f47c40e3d
Deleted: sha256:99c5e34963f7b0ae63427b9e24b1d66778daeda863c078f46476ea9229f17771
...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む