Dockerの使い方

イントロダクション

ラズパイにRedmineをインストールして使用しようと考えております。
しかし、記事を検索しながら、いろいろとやってみると、どれもこれもエラーがでて使えない。。。結局Dockerをちゃんと学習することにしました。

参考サイト

DockerDocsを参考にします。

タイトルは「Raspberry Pi OS (32 ビット) に Docker エンジンをインストールする」です。

Dockerとは?

いろいろと記事を斜め読みしてみると下のようなものということです。

Dockerはコンテナ仮想化を用いたOSレベルの仮想化によりアプリケーションを開発・実行環境から隔離し、アプリケーションの素早い提供を可能にする。

色々な説明があるけど、結局はこういうことだと思う。

つまり、「コンテナ」にまとめたアプリケーションを仮想マシンを使用して実行できる。ということらしい

Docker事始め

次のコマンドで、不要なもの、古いDockerをアンインストールします。もしかしたらインストールしているかもしれないからです。

よくあるのが、デフォルトインストールしているかもしれません。。。

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

DockerのAPTリポジトリセットアップ

コードを書くと下のようになります。

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Set up Docker's APT repository:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/raspbian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

ラズパイを更新

下のコマンドで、ラズパイの更新します。

sudo apt-get update

コマンドのインストール

下のコマンドをインストールします。既にインストールしているときは「すでに最新バージョン」というメッセージを確認できます。

  • ca-certificates
  • gnupg
  • curl
sudo apt-get install ca-certificates curl gnupg

Dockeraptリポジトリをセットアップ準備

GPGコマンドで暗号化・復号を行えるようにする?

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Dockeraptリポジトリをセットアップ

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/raspbian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

最後に更新

sudo apt-get update

Dockerパッケージインストール

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

インストールできたら、起動確認「ハローワールド」を実行する

sudo service docker start
sudo docker run hello-world

Dockerコマンドを使う

Dockerをコマンドで扱うときの基本構文は下のようになっています。※こちらのページ参照

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

DockerFileを使う

こちらのページを参照しています。※英語だったので翻訳してみました。
下のようなコマンドがあるのでそれを使用するということらしい。。。
Dockerのコマンド入力の基本としてコマンド名は大文字、引数は小文字で書くようです。

docker ADD argument...
コマンド名 意味
ADD ホスト上のソースから、設定された宛先にあるコンテナー独自のファイルシステムにファイルをコピーします。
CMD コンテナー内で特定のコマンドを実行するために使用できます。
ENTRYPOINT は、イメージを使用してコンテナーが作成されるたびに使用されるデフォルトのアプリケーションを設定します。
ENV 環境変数を設定します。
EXPOSE 特定のポートを関連付けて、コンテナと外部の間のネットワークを可能にします。
FROM ビルド プロセスの開始に使用されるベース イメージを定義します。
MAINTAINER イメージ作成者のフルネームと電子メール アドレスを定義します。
RUN Dockerfile の中心的な実行ディレクティブです。
USER コンテナを実行する UID (またはユーザー名) を設定します。
VOLUME コンテナからホスト マシン上のディレクトリへのアクセスを可能にするために使用されます。
WORKDIR CMD で定義されたコマンドが実行されるパスを設定します。
LABEL Docker イメージにラベルを追加できます。

試しにコマンドを実行する

下のようにディレクトリを作成します。作成先は初期ディレクトリ(ユーザーのディレクトリ)から「dockerbuild」というディレクトリを作成しました。

mkdir ~/dockerbuild

Dockerfileを作成します。

nano Dockerfile

下の内容をコピペします。

FROM ubuntu:latest
MAINTAINER NAME EMAIL

RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y build-essential

Where NAME is your full name and EMAIL is your email address.

そして、以下のようにコマンドをたたきます。

docker build -t "NAME:Dockerfile" .


エラーがあるけど、イメージ作製はできているようです。

「NAME」には好きな名前を入れてよいです。最後の「.」を忘れないようにしましょう。

これができたら下のようなコマンドをたたきます。

docker images

使用できるイメージの一覧が表示されます。

Redmineのインストール

こちらのサイトを参考にします。
手順は以下の通りです。

  1. docker-compose.ymlを作成する
  2. docker-composeコマンドを実行する
    docker-compose up -d

しかしうまくいかない。。。

no matching manifest for linux/arm/v7 in the manifest list entries

DBの指定とYMLの作成

結局docker-compose.ymlの記述がまずかったみたいだ。「hypriot/rpi-mysql」を指定してやれば問題なかった。
つまり、下の様に書くとOK
<docker-compose.yml>

version: '3.8'
services:
  redmine:
    image: redmine
    container_name: redmine
    ports:
      - 3000:3000
    volumes:
      - ./data/plugins:/usr/src/redmine/plugins
      - ./data/themes:/usr/src/redmine/public/themes
    environment:
      REDMINE_DB_MYSQL: redmine-db
      REDMINE_DB_PASSWORD: redmine
    depends_on:
      - redmine-db
    restart: always

  redmine-db:
    image: hypriot/rpi-mysql
    container_name: redmine-db
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: redmine
      MYSQL_DATABASE: redmine
    volumes:
      - ./data/db:/var/lib/mysql
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode>
    restart: always

しかしポート番号が。。。

for redmine-db  Cannot start service redmine-db: driver failed programming external connectivity on endpoint redmine-db (af1d40![](http://zenryokuservice.com/wp/wp-content/uploads/2023/11/Docker4.png)9b7e96abcb6b0d803518c400dd6f2bca79ef35fced14fd6a20b3c2b9cf): Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use

つまりは、「DBが使用するポート番号が使用されているため、DBが動かせない」ということでした。

使用ポートを調べる

「ss」コマンドで調べます。実行すると下のような結果が出ました。

pi@raspberrypi:~/dockerbuild/redmine $ ss -atn
State   Recv-Q  Send-Q   Local Address:Port        Peer Address:Port   Process  
LISTEN  0       5              0.0.0.0:5900             0.0.0.0:*               
LISTEN  0       128          127.0.0.1:631              0.0.0.0:*               
LISTEN  0       128            0.0.0.0:22               0.0.0.0:*               
LISTEN  0       80           127.0.0.1:3306             0.0.0.0:*               
ESTAB   0       0            127.0.0.1:60324          127.0.0.1:34449           
ESTAB   0       0            127.0.0.1:34449          127.0.0.1:60324           
ESTAB   0       0        169.254.37.79:5900     169.254.221.230:55375           
LISTEN  0       5                 [::]:5900                [::]:*               
LISTEN  0       511                  *:80                     *:*               
LISTEN  0       128               [::]:22                  [::]:*               
LISTEN  0       128              [::1]:631                 [::]:*  

まずは、使用しているポートが80番で待機(LISTENING)しているサービスと言えば「apache2」があやしい。。。ウェブサーバーは大体80を使っていることが多いので。。。下のコマンドでサービスを確認

service --status-all


そんなわけで、アパッチ(apache2)を停止し用と思ったけど、ポートを変更して対応します。

YMLファイルの編集

ポート番号を3306から3307に変更しました。

  redmine-db:
    image: hypriot/rpi-mysql
    container_name: redmine-db
    ports:
      - 3307:3307
    environment:
      MYSQL_ROOT_PASSWORD: redmine
      MYSQL_DATABASE: redmine
    volumes:
      - ./data/db:/var/lib/mysql
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode>
    restart: always

起動することができました。

しかし、現状では不要なアプリケーションが沢山動いているようなので、ブラウザで開けませんでした。。。
他のサービスなどを停止すればよいのですが、また後日。。。

ラズパイの準備

Redmineが動いたので、今度はラズパイの運用準備を行います。
大まかに行うことは以下の通りです。

  • 使用しないGPUのメモリ割り当てを減らす
  • 使わないアプリの停止

メモリ使用量確認

  • free -hコマンド:メモリの利用状況を確認
  • df -h: ファイル・システム内のフリー・スペースの量を表示する

デーモンを停止する

デーモンとは、画面上に見えないアプリケーションのことです。停止するのは以下のデーモンです。

  • alsa-utils
  • dbus
  • triggerhappy
  • cups
プロセルの確認方法
ps aux

上記のコマンドで確認できます。

サービス一覧を取得する

下のコマンドで一覧できます。

service --status-all

ここで表示されたサービスの名前を停止するのには下のように行います。

[ - ]  alsa-utils
 [ - ]  apache-htcacheclean
 [ + ]  apache2
 [ - ]  apparmor
 [ + ]  avahi-daemon
 [ + ]  binfmt-support
 [ + ]  bluetooth
 [ - ]  cgroupfs-mount
 [ - ]  console-setup.sh
 [ + ]  cron
 [ + ]  cups
 [ + ]  cups-browsed
 [ + ]  dbus
 [ + ]  docker
 [ + ]  dphys-swapfile
 [ + ]  fake-hwclock
 [ - ]  fio
 [ - ]  hwclock.sh
 [ - ]  keyboard-setup.sh
 [ + ]  kmod
 [ + ]  lightdm
 [ + ]  mariadb
 [ + ]  networking
 [ - ]  nfs-common
 [ - ]  paxctld
 [ - ]  plymouth
 [ + ]  plymouth-log
 [ + ]  procps
 [ - ]  pulseaudio-enable-autospawn
 [ + ]  raspi-config
 [ + ]  rng-tools-debian
 [ - ]  rpcbind
 [ - ]  rsync
 [ + ]  rsyslog
 [ - ]  saned
 [ + ]  ssh
 [ - ]  sudo
 [ - ]  triggerhappy
 [ + ]  udev
 [ - ]  x11-common

サービスの停止方法

下記コマンドでサービスの停止

sudo systemctl サービス名

無効にする

sudo systemctl disable サービス名

実行したコマンド

<サービスの停止>

sudo systemctl stop alsa-utirls
sudo systemctl stop dbus
sudo systemctl stop triggerhappy.service triggerhappy.service
sudo systemctl stop triggerhappy.socket
sudo systemctl stop cups

<サービス自動起動無効>

sudo systemctl disable alsa-utirls
sudo systemctl disable dbus
sudo systemctl disable triggerhappy.service triggerhappy.service
sudo systemctl disable triggerhappy.socket
sudo systemctl disable cups

設定の反映を行うのに再起動します。

sudo reboot

結果

<サービス停止前>

               total        used        free      shared  buff/cache   available
Mem:           921Mi       328Mi        55Mi        10Mi       538Mi       526Mi
Swap:          384Mi        68Mi       316Mi

<サービス停止後>

               total        used        free      shared  buff/cache   available
Mem:           921Mi       376Mi        78Mi       8.0Mi       466Mi       479Mi
Swap:          376Mi       1.0Mi       375Mi

起動スクリプトを作る

まずは、Shellスクリプトである宣言をする

# !/bin/sh

処理を作成する(自分の場合です。)

cd ~/dockerbuild/redmine/

起動する設定を行う

参考サイトはこちらです。
/etc/systemd/system/ ディレクトリに autorun.serviceを、以下のように作成する

[Unit]
Description=Execute at OS startup and terminates
After=network.target
[Service]
Type=oneshot
ExecStart=/home/pi/autorun.sh
ExecStop=/home/pi/os_term.sh
RemainAfterExit=true
[Install]
WantedBy=multi-user.target

After=network.target はネットワーク関連のプロセスが起動した後に当サービスを起動するという意味らしいです。
サービスの有効化

sudo systemctl daemon-reload
sudo systemctl enable autorun.service

Redmineの起動確認

Redmineの使い方

まずは、初期設定を行う。

チケットのトラッカー

チケットのトラッカーを追加してやります。
上部のメニューにある「管理」をクリックしてから、下のような画面を開くことができます。

ここをクリックして、下のような画面を表示できますので「新しいトラッカー」をクリックして作成します。
ここでは、下のように今後作成するチケットの種類(カテゴリ)を作成します。

チケットのステータス

同様に、上部のメニューにある「管理」をクリックしてから、下のような画面を開くことができます。

同様に、赤枠の部分をクリックしてやると下のような画面が開けます。

これはすでに入力した後なのですが、こんな感じで、「ステータス(状態)」を登録することで、作成するチケットの状態を指定します。
つまりは、「このチケットは<ステータス>に対応した工程の作業」という意味です。

優先度

これも同様に、「選択肢の値」を選択します。

下のように、「新しい値」をクリックして追加してやります。

チケットの作成

チケットのトラッカーを追加してやると下のように、「新しいチケット」をクリックすることができます。これが見当たらないときは設定がたりない状態ということです。

これで、チケットを作成して、アイティアと行いたい作業が混同することを防げるであろう。
まぁこれ流行ってみないことにはどうしようもないな。。。

でわでわ。。。

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。