3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Docker コンテナ内シェルのカラー設定

Last updated at Posted at 2023-09-01

モチベーション

DockerコンテナにSSH接続した際、基本的にカラー設定は無効化されている。無色だと作業効率が落ちるのでカラー化したいが毎度プロンプトや lsgrep などの各種色設定をログインする度に設定するのは骨が折れる。共有のプロジェクトなどは勝手に Dockerfile にカラー設定を書き込むことが出来ない場合も多い。

そこで docker exec でSSH接続する度に色設定情報を送り込むようにすればどのコンテナに接続しても好きな色設定 (+その他設定) でコンテナ内作業ができるので 捗ること請け合いだ!

方針

  1. カラー設定が書かれた .bashrc をホスト側に用意する
  2. ホストの .bashrc をコンテナ内にコピーする
  3. コンテナに環境変数 TERM=xterm-256color を設定する
  4. 上記をワンコマンドで実行するシェル関数を定義する

プロンプトのカラー設定

bash なら $PS1 zsh なら $PROMPT にそれぞれプロンプトに表示する情報と色の設定を書き込む。

.bashrc
# 例
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac
if [ "$color_prompt" = yes ]; then
    # 色設定あり
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    # 端末の256色設定が無効なら色コードは入れない
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset

参考:

ls grep のカラー設定

以下を .basrhc に追記しておきます。

.bashrc
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

ホストの .bashrc をコンテナ内にコピーする

docker cp コマンドを使ってホスト内のファイルをコンテナにコピーすることができる。
Docker では基本的に root ユーザーでのログインになるので root ユーザーのホームディレクトリである /root/ 以下に .bashrc をコピーする。

[書式] docker cp ホストのファイルパス コンテナ名:コンテナ内のパス

# 例:
# my_service イメージから my_service という名のコンテナを立ち上げる
docker run --rm -d -p 3000:3000 --name my_service my_service

# ホストの .basrc を コンテナの /root/ にコピーする
docker cp ~/.bashrc my_service:/root/

参考:

コンテナに TERM=xterm-256color を設定する

環境変数 $TERMxterm-256color が設定されているとターミナル内で扱える色が256色になります。
これをコンテナ内にログインするときに潜り込ませます。

docker exec -it my_service env TERM=xterm-256color /bin/bash

docker引数の --env ではなくシェルの env で設定しています。

コマンド一発でカラーシェルにログインする!

上記設定を一つの関数にまとめ一発で実行できるようにします。
~/.bashrc に以下関数を書き込む。
(【追記】→ ~/bin/ のパスを通して ~/bin/docker-ssh というシェルスクリプトを作ったほうが良さそう(※コメント参照) )

.bashrc
docker-ssh() {
    cmd1="docker cp ~/.bashrc $1:/root/"
    echo $cmd1 && eval $cmd1 && echo 'Copied! .bashrc'
    cmd2="docker exec -it $@ env TERM=xterm-256color /bin/bash"
    echo -e "\n" $cmd2 && eval $cmd2
}

使い方は、立ち上げたコンテナ名が my_service の時に以下を実行するだけです。

$ docker-ssh my_service
docker cp ~/.bashrc web:/root/
Copied! .bashrc

docker exec -it web env TERM=xterm-256color /bin/bash


image.png

docker compose の場合

docker compose で起動しているコンテナにSSH接続する際も基本的に同じ。間に compose という文言が入るだけ。

# .bashrc に以下追記
docker-compose-ssh() {
    cmd1="docker compose cp ~/.bashrc $1:/root/"
    echo $cmd1 && eval $cmd1 && echo 'Copied! .bashrc'
    cmd2="docker compose exec -it $@ env TERM=xterm-256color /bin/bash"
    echo -e "\n" $cmd2 && eval $cmd2
}
# composeでコンテナ起動
docker compose up -d
# コンテナの起動状況を確認
$ docker compose ps

NAME         IMAGE      COMMAND                 SERVICE  CREATED        STATUS       PORTS
myapp-db-1   myapp-db   "docker-entrypoint.s…"  db       5 months ago   Up 5 hours   0.0.0.0:15432->5432/tcp
myapp-web-1  myapp-web  "/app/docker/web/ent…"  web      4 days ago     Up 5 hours   0.0.0.0:13000->3000/tcp

#=> 「web」 がサービス名
# webコンテナにログイン
docker-compose-ssh web

image.png

(余談)引数を変数にする

コマンドラインのオプション引数でよく使うものはグローバル変数化しておいたほうが何かと使い勝手いいかなと思って最初は以下のようにしていた。

.bashrc
docker-ssh() {
    export DOCKER_EXEC_OPTIONS='-it --env TERM=xterm-256color'

    docker cp ~/.bashrc $1:/root/
    docker exec $DOCKER_EXEC_OPTIONS $@ /bin/bash
}

しかし、これだと以下のようなエラーになりダメだった。

$ docker-ssh web
unknown shorthand flag: ' ' in - --env TERM=xterm-256color

シェルが文字列を解釈する順序(?)的な問題かなと思って色々試すのが面倒になったので eval にしたらうまく行った。

.bashrc
docker-ssh() {
    export DOCKER_EXEC_OPTIONS='-it --env TERM=xterm-256color'

    docker cp ~/.bashrc $1:/root/
    eval "docker exec $DOCKER_EXEC_OPTIONS $@ /bin/bash"  # eval で文字列をコマンドとして解釈
}

eval はよくわかってないですがあまりよろしくないようなので、使わずにやりたいところ・・・。

わかる方教えてくださいませ!

【追記】コメントにて詳しく教えて下さいました!

3
6
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?