2025/05/06 Updated by

Docker Image を自作する (1)

Ubuntu 24.04LTS + 新規ユーザ


[Up] Japanese English

ubuntu24.04LTS をベースとし、新規ユーザを作成する

方針

作成手順

  1. 作業用フォルダを作成する。
  2.   $ mkdir -p ~/doc/docker/ubuntu24_user
      $ cd ~/doc/docker/ubuntu24_user
    
  3. 作業用フォルダの中に Dockerfile を作成する。
  4. Dockerfile
    # ゲストOS: Ubuntu 24.04 LTS
    
    FROM ubuntu:24.04
    
    
    # Change Your Own UNAME, UID, GID, PASS
    
    ENV UNAME=guest
    ENV UID=3000
    ENV GID=3000
    ENV PASS=パスワード
    
    
    # 必要なパッケージのインストール
    
    RUN apt-get update && \
        DEBIAN_FRONTEND=noninteractive apt-get install -y \
        sudo \
        bash \
        && rm -rf /var/lib/apt/lists/*
    
    
    # Copy Shell Script "entrypoint.sh"
    
    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    
    ENTRYPOINT ["/entrypoint.sh"]
    
    CMD []
    
  5. 作業用フォルダの中に entrypoint.sh を作成する。
  6. entrypoint.sh
    #!/bin/bash
    set -e
    
    if [ ! -f /var/app/.initialized ]; then
        ######## First Time ########
    
        echo "First run. Setting up ..."
        mkdir -p /var/app
        touch /var/app/.initialized
    
        # ユーザーが存在しない場合のみ作成する
        if id "${UNAME}" &>/dev/null; then
            echo "User ${UNAME} already exists. Skipping creation."
        else
            # 同名グループが無ければ作成
            if ! getent group "${UNAME}" &>/dev/null; then
                echo "Creating group ${UNAME} with GID=${GID}"
                groupadd -g ${GID} ${UNAME}
            else
                echo "Group ${UNAME} already exists. Skipping group creation."
            fi
        
            echo "Creating user ${UNAME} with UID=${UID}, GID=${GID}"
            useradd -m -u ${UID} -g ${GID} -s /bin/bash ${UNAME}
            echo "${UNAME}:${PASS}" | chpasswd
            usermod -aG sudo ${UNAME}
        fi
    
        # ホームディレクトリの Owner が root:root になることがあるので変更する。
        chown -v ${UNAME}:${UNAME}  /home/${UNAME}
    
    else
        ######## Second Time or Later ########
        
        echo "Starting for the second time or later ..."
    
    fi
    
    
    # Execute Commands in CMD
    
    if [ "$#" -gt 0 ]; then
        exec "$@"
    else
        echo "No command provided. Starting bash ..."
        exec bash
    fi
    
  7. Image を build する。
  8.   $ docker build -t ubuntu24-user .
      ...
    成功
    
  9. 生成した Image を確認する
  10. $ docker image ls
    REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
    ubuntu24-user   latest    ac92161948dc   21 seconds ago   126MB
    ...
    

Container 用の永続的なファイルシステムを作成する

コンテナに永続的なファイルシステムを提供するために、1777 のパーミッションでフォルダを作っておく。 skicky bit が on (1777) のフォルダには、 「誰でもファイルを作成できるが、作成した本人だけがファイルを変更したり消したりできる」 という特徴がある。

$ sudo mkdir -p /home/docker         ← ディレクトリを作成する
$ sudo chmod 1777 /home/docker       ← 誰でもファイルを作成できるが、作成した本人にしか消去できないモードに設定する
$ ls -ld /home/docker                ← ディレクトリのsticky bit が on になっていることを確認する。
drwxrwxrwt 3 root root 4096  5月 06 17:57 /home/docker

Docker Contaner を生成する (1)

Image ubuntu24-user のデフォルトのユーザ情報を用いて、新しい Container ubuntu24-guest を生成する。

  1. Image から Container を生成して起動する。ユーザ情報はデフォルト値 (guest) を利用する。 Container のファイルシステム内にホストOSのディレクトリをマウントする。
  2. $ docker run --name ubuntu24-guest \
        -v /home/docker/guest:/mnt/hostos \
        -it ubuntu24-user
    
    起動オプション
  3. Container を起動した対話環境が、そのまま Container 内で動作する bash との対話環境になる。root権限でloginした状態である。
  4. First run. Setting up ...                                                 ←(Conainer内の対話環境)
    Creating group guest with GID=3000
    Creating user guest with UID=3000, GID=3000
    ownership of '/home/guest' retained as guest:guest
    No command provided. Starting bash ...
    #              ← Container 内の対話環境 (root権限の bash) が動く
    
  5. (Container 内で) Container 内の対話環境を調べる。
  6. # whoami
    root                                       ← root権限で動作している
    # pwd
    /                                          ← カレントディレクトリは '/'
    # ls -ld /mnt/hostos
    drwxr-xr-x 2 root root 4096 May  6 09:29 /mnt/hostos         ← ホストOSをマウントしたディレクトリ
    
  7. (Container 内で) Container の状況を調べる。
  8. # ls -ld /home/guest
    drwxr-x--- 2 guest guest 4096 May  6 14:06 /home/guest
    # ls -la /home/guest
    total 20
    drwxr-x--- 2 guest guest 4096 May  6 14:06 .
    drwxr-xr-x 1 root  root  4096 May  6 14:06 ..
    -rw-r--r-- 1 guest guest  220 Mar 31  2024 .bash_logout
    -rw-r--r-- 1 guest guest 3771 Mar 31  2024 .bashrc
    -rw-r--r-- 1 guest guest  807 Mar 31  2024 .profile
    
  9. (Container 内で) Container 内に作成したユーザの状況を調べる。
  10. # grep guest /etc/group
    sudo:x:27:ubuntu,guest                         ← sudo グループにも追加されている
    guest:x:3000:                                  ← グループID
    # grep guest /etc/passwd
    guest:x:3000:3000::/home/guest:/bin/bash       ← ユーザIDなど
    # ls -ld /home/guest
    drwxr-x--- 2 guest guest 4096 May  6 14:06 /home/guest         ← ホームディレクトリのパーミッション
    # ls -la /home/guest
    total 20
    drwxr-x--- 2 guest guest 4096 May  6 14:06 .
    drwxr-xr-x 1 root  root  4096 May  6 14:06 ..
    -rw-r--r-- 1 guest guest  220 Mar 31  2024 .bash_logout         ← ホームディレクトリに自動で追加されたファイル群
    -rw-r--r-- 1 guest guest 3771 Mar 31  2024 .bashrc
    -rw-r--r-- 1 guest guest  807 Mar 31  2024 .profile
    
  11. (Container 内で) Control-P + Control-Q を入するtことで、Container 内の対話環境から抜けて、ホストOSの対話環境に戻る。
  12. ここで^C (Control-C) などを入力して Container の対話環境を終了すると Container 自体の実行が終了してしまうので注意。

    # ^P ^Q ← 'Control-P' + 'Control-Q' で Container を detatch する。
    $ ← ホストOSの対話環境に戻る
  13. Container からマウントされるホスト OS の /home/docker/guest が存在しない場合は作成されている。 ホストOSにおけるファイルの権限は "docker run" を実行したホストOSのユーザ (nitta) の場合と、root の場合があるようだ(システムの設定状況依存)。
  14. $ ls -ld /home/docker/guest
    drwxr-xr-x 2 nitta nitta 4096  5月  2 16:28 /home/docker/guest
    
    $ ls -ld /home/docker/guest
    drwxr-xr-x 2 root root 4096  5月  6 18:29 /home/docker/guest
    
  15. 起動した Container の様子を調べる。
  16. $ docker container ls
    CONTAINER ID   IMAGE           COMMAND            CREATED         STATUS         PORTS     NAMES
    158d183c43e3   ubuntu24-user   "/entrypoint.sh"   6 seconds ago   Up 2 minutes             ubuntu24-guest
    
  17. Container のログを調べる。
  18. $ docker logs ubuntu24-guest
    First run. Setting up ...
    Creating group guest with GID=3000
    Creating user guest with UID=3000, GID=3000
    ownership of '/home/guest' retained as guest:guest
    No command provided. Starting bash ...
    root@3cac23972a28:/# whoami                         ← Container の対話環境の入出力はログに残っている
    root
    ...
    
  19. ホストOSのシェルを、Container の シェルに attachする。
  20. $ docker attach ubuntu24-guest
    # ← Container内のroot権限の対話環境にアクセスする
  21. (Container内で) 追加したユーザにloginする。
  22. # whoami root ← まだroot権限だけど # login guestguest として login する Password: ← guest のパスワードを入力する(エコーバックされない)
    Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.11.0-25-generic x86_64) ... $ guest 権限の対話環境となる
  23. (Container 内の guest 権限で) ユーザ状態を調べる
  24. $ whoami                   ← ユーザ名を調べる
    guest
    $ pwd                      ← ホームディレクトリのパスを表示する。
    /home/guest
    
  25. (Container 内の guest 権限で) パスワードを変更する
  26. $ passwd
    Changing password for guest.
    Current password: パスワード ← エコーバックされない
    New password:  新しいパスワード ← エコーバックされない
    Retype new password:  新しパスワード ← エコーバックされない
    passwd: password updated successfully
    
  27. (Container 内の guest 権限で) 途中でホストOSに戻ることもできる
  28. $ ^P ^Q ← Control-P と Control-Q を順にタイプする
    $ ← ホストOSの対話環境
  29. ホストOSから Container に attach すると、先ほどの対話環境の続きとなる。
  30. $ docker attach ubuntu24-guest
    
    $       ← Containerのguest権限の対話環境
    
  31. guest ユーザのシェルを終わるには、exit
  32. $ exit ← guest権限
    # ← Containerのroot権限の対話環境
  33. (Container内で) root権限の対話環境を終了すると、Containerの実行も終了する。
  34. $ exit
    Connection to localhost closed. $ ← ホストOSの対話環境
  35. docker の状態を調べる。
  36. 実行中の Container の一覧には ubuntu24-guest は無いことがわかる。
    $ docker container ls
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    
    停止中の Container の一覧には存在する。
    $ docker container ls -a
    CONTAINER ID   IMAGE           COMMAND            CREATED       STATUS                     PORTS     NAMES
    3cac23972a28   ubuntu24-user   "/entrypoint.sh"   3 hours ago   Exited (0) 7 seconds ago             ubuntu24-guest
    
    Image はそのまま存在している。
    $ docker image ls
    REPOSITORY      TAG       IMAGE ID       CREATED       SIZE
    ubuntu24-user   latest    758568c4f956   3 hours ago   81.4MB
    
  37. [注意] Container を生成したときの環境変数は、名前と値のペアが Conainer 内に記録されている。したがって、パスワードのような重要な情報はできるだけ迅速に変更しておくことを推奨する。
  38. $ docker inspect -f '{{.Config}}' ubuntu24-user
    {   false false false map[] false false false \
    [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    UNAME=guest UID=3000 GID=3000 PASS=password\
    ] []  true  map[]  [/entrypoint.sh] false  [] \
    map[org.opencontainers.image.ref.name:ubuntu org.opencontainers.image.version:24.04]   []}
    

Docker Contaner を生成する (2)

Image ubuntu24-user を用いて、 ユーザ情報を指定して新しい Container ubuntu24-nitta を生成する。

  1. docker image として ubuntu24-user が存在している。
  2. $ docker image ls
    REPOSITORY      TAG       IMAGE ID       CREATED        SIZE
    ubuntu24-user   latest    758568c4f956   17 hours ago   81.4MB
    
  3. Image から Container を生成して起動する。下に示すのは新規ユーザ名を nitta とした例である。
  4. $ docker run --name ubuntu24-nitta \ -e UNAME=nitta -e UID=2000 -e GID=2000 -e PASS=新しいパスワード \ -v /home/docker/nitta:/mnt/hostos \ -it ubuntu24-user
    First run. Setting up ... Creating group nitta with GID=2000 Creating user nitta with UID=2000, GID=2000 ownership of '/home/nitta' retained as nitta:nitta No command provided. Starting bash ...
    起動オプション
  5. (Container 内で) Conainer を run したシェルで、そのまま Container の対話環境が動く。rootとして login した状態である。
  6. (Container 内で) マウントしたホストOSのディレクトリを調べる。
  7. # ls -ld /mnt/hostos
    drwxr-xr-x 2 root root 4096 May  7 06:37 /mnt/hostos
    
  8. (Container 内で) 新規ユーザ nittaのホームディレクトリについて調べる。
  9. # ls -ld /home/nitta
    drwxr-x--- 2 nitta nitta 4096 May  7 06:37 /home/nitta
    # ls -la /home/nitta
    total 20
    drwxr-x--- 2 nitta nitta 4096 May  7 06:37 .
    drwxr-xr-x 1 root  root  4096 May  7 06:37 ..
    -rw-r--r-- 1 nitta nitta  220 Mar 31  2024 .bash_logout
    -rw-r--r-- 1 nitta nitta 3771 Mar 31  2024 .bashrc
    -rw-r--r-- 1 nitta nitta  807 Mar 31  2024 .profile
    
  10. (Container 内で) 新規ユーザ nitta として login する。
  11. # login nitta Password: ← パスワードを入力する。エコーバックされない。
    Welcome to Ubuntu 24.04.2 LTS (GNU/Linux 6.11.0-25-generic x86_64) ... To run a command as administrator (user "root"), use "sudo ". See "man sudo_root" for details. #
  12. (Container 内のユーザ nittaで) パスワードを変更する。
  13. $ passwd
    Changing password for nitta.
    Current password:             ← 古いパスワードを入力する。エコーバックされない。
    New password:                 ← 新しいパスワードを入力する。エコーバックされない。
    Retype new password:          ← もう一度新しいパスワードを入力する。エコーバックされない。
    passwd: password updated successfully
    
  14. (Container 内 → ホストOS) 端末操作(Control-P + Control-Q)で、Container を動作させたままホストOSの対話環境に抜ける。
  15. $ ^p ^q ← Container内の対話環境で Control-P Control-Q を続けてタイプする。
    $ ← ホストOSの対話環境に戻る
  16. Docker Container の様子を調べると Container ubuntu24-user は動作中であることがわかる。(-l オプションなしの dockder container ls で表示されるので。)
  17. $ docker container ls
    CONTAINER ID   IMAGE           COMMAND            CREATED              STATUS              PORTS     NAMES
    c45866de1d5d   ubuntu24-user   "/entrypoint.sh"   About a minute ago   Up About a minute             ubuntu24-nitta
    
    $ docker container ls -a
    CONTAINER ID   IMAGE           COMMAND            CREATED              STATUS                    PORTS     NAMES
    c45866de1d5d   ubuntu24-user   "/entrypoint.sh"   About a minute ago   Up About a minute                   ubuntu24-nitta
    3cac23972a28   ubuntu24-user   "/entrypoint.sh"   17 hours ago         Exited (0) 14 hours ago             ubuntu24-guest
    
  18. Container からマウントされている ホストOS のディレクトリを調べる。
  19. $ ls -ld /home/docker/nitta
    drwxr-xr-x 2 root root 4096  5月  7 15:37 /home/docker/nitta