0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WindowsでDockerを使用してLinux環境を構築する。

0
Posted at

はじめに

普段からUnix系のコマンドに慣れていると、Windowsでコマンドによる整形等やろうとしたときに四苦八苦することがよくあります。

最近ではWLS2もあるので、大分ハードルが低くなっていますが、仕事柄、複数のPCを使うことも多く、それぞれのPCで自分用の作業環境を作るのも面倒なので、Git等での管理も楽で簡単に環境構築出来るDockerで作ってみたので構築した環境を紹介したいと思います。

Dockerによる開発環境の構築

Linuxの環境を使うだけであれば、WindowsであればWLS2を使う、VirtualBoxで仮想マシンを作る等、最近は色々と選択肢がありますが、好きなパッケージ等入れて自分なりの環境を構築するまでにはそれなりに時間もかかり、複数のPCに同じ環境を用意しようとした場合は更に時間がかかります。

それに比べ、Dockerであれば、最初に作り込んだDockerfileを用意しておけば、Windowsでも、MacOSでも、Linuxでも同じように使用できること、そもそもDockerfileやDocker Composeのファイルはテキストのため、Git等で管理しやすいのが利点かと思います。

今回は、Windows端末にDocker Desktopをインストールし、作業用途のコンテナを構築してみようと思います。

作った環境

今回作成するコンテナ用のディレクトリ配下に以下のようにファイル等配置し、コンテナ作成しました。

パス 内容
Dockerfile Dockerファイル
docker-compose.yml Docker Composeファイル
/config/zpreztorc カスタム済みpreztoファイル
/config/agnoster.zsh-theme カスタム済みpreztoファイル
/share/ Windowsホスト側との共有用ディレクトリ
~/.aws Windowsホスト側で設定しているAWS CLI設定ファイルを使うため共有

Dockerfile

適当に使いそうなパッケージやツールを諸々入れました。

また、普段使っているMacOSではpreztoagnosterというテーマを使って、過去コマンドの検索やシンタックスハイライト等の機能を使っているため、設定用のファイルを別で用意して、配置したファイルを上書きするようにしました。

MacOSやLinuxでの内容となりますが、preztoの詳細は以前書いた以下を参考にしてください。

ユーザについては今回自分しか使わない作業用なのでrootでの使用前提としています。

# ============================================================
# Dockerfile 設定
# ============================================================
FROM ubuntu:26.04

# ロケール・タイムゾーン設定
ENV TZ=Asia/Tokyo
ENV LANG=ja_JP.UTF-8

# ------------------------------------------------------------
# 基本パッケージのインストール
# ------------------------------------------------------------
RUN apt-get update && apt-get install -y \
    # ロケール
    locales \
    tzdata \
    # 基本ツール
    curl \
    git \
    vim \
    unzip \
    zip \
    # ビルドツール
    build-essential \
    make \
    gcc \
    g++ \
    # zprezto
    zsh \
    # Ansible
    ansible \
    # その他の便利ツール
    jq \
    awscli \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# ロケール生成
RUN locale-gen ${LANG} && \
    ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone

# ------------------------------------------------------------
# zprezto設定
# ------------------------------------------------------------
RUN git clone --recursive https://github.com/sorin-ionescu/prezto.git "/root/.zprezto"

COPY config/zpreztorc /root/.zprezto/runcoms/zpreztorc
COPY config/agnoster.zsh-theme /root/.zprezto/modules/prompt/external/agnoster/agnoster.zsh-theme

# ホームディレクトリにシンボリックリンク作成
# 参考:https://github.com/sorin-ionescu/prezto
SHELL ["/bin/zsh", "-c"]
RUN setopt EXTENDED_GLOB && \
    for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do \
      ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"; \
    done

# ------------------------------------------------------------
# tfenv設定
# ------------------------------------------------------------
RUN git clone https://github.com/tfutils/tfenv.git /root/.tfenv && \
    /root/.tfenv/bin/tfenv install 1.15.7 && \
    /root/.tfenv/bin/tfenv use 1.15.7 && \
    cat << _EOF_ >> /root/.zshrc

# ============ カスタム設定 ============
export PATH=$HOME/.tfenv/bin:$PATH
_EOF_

# ------------------------------------------------------------
# デフォルトのシェルを zsh に設定
# ------------------------------------------------------------
RUN usermod -s /bin/zsh root

# コンテナ起動時に zsh を実行
CMD ["/bin/zsh"]

Docker Compose

今回の使用用途は基本的にjqによる整形や、Linuxコマンドでの作業用途なので、最低限の設定のみ行っています。

生成物をWindows側でも利用できるように、「/share」のみホスト側と共有し、その他のディレクトリは永続化していません。

AWSコマンドはホストとなるWindows側でも使うため、設定ファイル等格納される「~/.aws」をリードオンリーで共有するようにしています。

# ============================================================
# Docker Compose 設定
# ============================================================
services:
  worklinux:
    build: .
    image: worklinux
    hostname: worklinux
    container_name: worklinux
    restart: unless-stopped
    tty: true
    stdin_open: true
    volumes:
      - C:/Users/username/.aws:/root/.aws:ro
      - C:/Users/username/share:/share
    working_dir: /share

volumes:
  worklinux-home:
    driver: local

prezto設定ファイル

自分用にカスタマイズしたprezto関連のファイルを用意しておきます。

agnoster.zsh-themeの変更

デフォルトだとコンソールにユーザ名も表示されますが、今回はrootログインしか行わないため、ホスト名と現在のディレクトリのみ表示するようにしました。

また、後述のWindows Terminalで見栄えが良くなるよう、prompt_contextprompt_dirの色指定部分をカスタマイズしています。

agnoster.zsh-theme(展開してください)
# vim:ft=zsh ts=2 sw=2 sts=2
#
# agnoster's Theme - https://gist.github.com/3712874
# A Powerline-inspired theme for ZSH
#
# # README
#
# In order for this theme to render correctly, you will need a
# [Powerline-patched font](https://gist.github.com/1595572).
#
# In addition, I recommend the
# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
# using it on Mac OS X, [iTerm 2](http://www.iterm2.com/) over Terminal.app -
# it has significantly better color fidelity.
#
# # Goals
#
# The aim of this theme is to only show you *relevant* information. Like most
# prompts, it will only show git information when in a git working directory.
# However, it goes a step further: everything from the current user and
# hostname to whether the last call exited with an error to whether background
# jobs are running in this shell will all be displayed automatically when
# appropriate.

### Segments of the prompt, default order declaration

typeset -aHg AGNOSTER_PROMPT_SEGMENTS=(
    prompt_status
    prompt_context
    prompt_virtualenv
    prompt_dir
    prompt_git
    prompt_end
)

### Segment drawing
# A few utility functions to make it easy and re-usable to draw segmented prompts

CURRENT_BG='NONE'
if [[ -z "$PRIMARY_FG" ]]; then
	PRIMARY_FG=black
fi

# Characters
SEGMENT_SEPARATOR="\ue0b0"
PLUSMINUS="\u00b1"
BRANCH="\ue0a0"
DETACHED="\u27a6"
CROSS="\u2718"
LIGHTNING="\u26a1"
GEAR="\u2699"

# Begin a segment
# Takes two arguments, background and foreground. Both can be omitted,
# rendering default background/foreground.
prompt_segment() {
  local bg fg
  [[ -n $1 ]] && bg="%K{$1}" || bg="%k"
  [[ -n $2 ]] && fg="%F{$2}" || fg="%f"
  if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
    print -n "%{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%}"
  else
    print -n "%{$bg%}%{$fg%}"
  fi
  CURRENT_BG=$1
  [[ -n $3 ]] && print -n $3
}

# End the prompt, closing any open segments
prompt_end() {
  if [[ -n $CURRENT_BG ]]; then
    print -n "%{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR"
  else
    print -n "%{%k%}"
  fi
  print -n "%{%f%}"
  CURRENT_BG=''
}

### Prompt components
# Each component will draw itself, and hide itself if no information needs to be shown

# Context: user@hostname (who am I and where am I)
prompt_context() {
  local user=`whoami`

  if [[ "$user" != "$DEFAULT_USER" || -n "$SSH_CONNECTION" ]]; then
    #prompt_segment $PRIMARY_FG default " %(!.%{%F{yellow}%}.)$user@%m "
    prompt_segment 'blue' default " %(!.%{%F{yellow}%}.)%m "
  fi
}

# Git: branch/detached head, dirty status
prompt_git() {
  local color ref
  is_dirty() {
    test -n "$(git status --porcelain --ignore-submodules)"
  }
  ref="$vcs_info_msg_0_"
  if [[ -n "$ref" ]]; then
    if is_dirty; then
      color=yellow
      ref="${ref} $PLUSMINUS"
    else
      color=green
      ref="${ref} "
    fi
    if [[ "${ref/.../}" == "$ref" ]]; then
      ref="$BRANCH $ref"
    else
      ref="$DETACHED ${ref/.../}"
    fi
    prompt_segment $color $PRIMARY_FG
    print -n " $ref"
  fi
}

# Dir: current working directory
prompt_dir() {
  #prompt_segment blue $PRIMARY_FG ' %~ '
  prompt_segment cyan black ' %~ '
}

# Status:
# - was there an error
# - am I root
# - are there background jobs?
prompt_status() {
  local symbols
  symbols=()
  [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}$CROSS"
  [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}$LIGHTNING"
  [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}$GEAR"

  [[ -n "$symbols" ]] && prompt_segment $PRIMARY_FG default " $symbols "
}

# Display current virtual environment
prompt_virtualenv() {
  if [[ -n $VIRTUAL_ENV ]]; then
    color=cyan
    prompt_segment $color $PRIMARY_FG
    print -Pn " $(basename $VIRTUAL_ENV) "
  fi
}

## Main prompt
prompt_agnoster_main() {
  RETVAL=$?
  CURRENT_BG='NONE'
  for prompt_segment in "${AGNOSTER_PROMPT_SEGMENTS[@]}"; do
    [[ -n $prompt_segment ]] && $prompt_segment
  done
}

prompt_agnoster_precmd() {
  vcs_info
  PROMPT='%{%f%b%k%}$(prompt_agnoster_main) '
}

prompt_agnoster_setup() {
  autoload -Uz add-zsh-hook
  autoload -Uz vcs_info

  prompt_opts=(cr subst percent)

  add-zsh-hook precmd prompt_agnoster_precmd

  zstyle ':vcs_info:*' enable git
  zstyle ':vcs_info:*' check-for-changes false
  zstyle ':vcs_info:git*' formats '%b'
  zstyle ':vcs_info:git*' actionformats '%b (%a)'
}

prompt_agnoster_setup "$@"

zpreztorcの変更

gitsyntax-highlightingAutosuggestionsの機能を使用するため、モジュール設定を追加しています。

また、テーマをお気に入りのagnosterにするため、スタイル設定でテーマを指定しています。

zpreztorc(展開してください)
#
# Sets Prezto options.
#
# Authors:
#   Sorin Ionescu <sorin.ionescu@gmail.com>
#

#
# General
#

# Set case-sensitivity for completion, history lookup, etc.
# zstyle ':prezto:*:*' case-sensitive 'yes'

# Color output (auto set to 'no' on dumb terminals).
zstyle ':prezto:*:*' color 'yes'

# Add additional directories to load prezto modules from
# zstyle ':prezto:load' pmodule-dirs $HOME/.zprezto-contrib

# Allow module overrides when pmodule-dirs causes module name collisions
# zstyle ':prezto:load' pmodule-allow-overrides 'yes'

# Set the Zsh modules to load (man zshmodules).
# zstyle ':prezto:load' zmodule 'attr' 'stat'

# Set the Zsh functions to load (man zshcontrib).
# zstyle ':prezto:load' zfunction 'zargs' 'zmv'

# Set the Prezto modules to load (browse modules).
# The order matters.
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'git' \
  'completion' \
  'syntax-highlighting' \
  'history-substring-search' \
  'autosuggestions' \
  'prompt'

#
# Autosuggestions
#

# Set the query found color.
# zstyle ':prezto:module:autosuggestions:color' found ''

#
# Completions
#

# Set the entries to ignore in static '/etc/hosts' for host completion.
# zstyle ':prezto:module:completion:*:hosts' etc-host-ignores \
#   '0.0.0.0' '127.0.0.1'

#
# Editor
#

# Set the characters that are considered to be part of a word.
# zstyle ':prezto:module:editor' wordchars '*?_-.[]~&;!#$%^(){}<>'

# Set the key mapping style to 'emacs' or 'vi'.
zstyle ':prezto:module:editor' key-bindings 'emacs'

# Auto convert .... to ../..
# zstyle ':prezto:module:editor' dot-expansion 'yes'

# Allow the zsh prompt context to be shown.
#zstyle ':prezto:module:editor' ps-context 'yes'

#
# Git
#

# Ignore submodules when they are 'dirty', 'untracked', 'all', or 'none'.
# zstyle ':prezto:module:git:status:ignore' submodules 'all'

#
# GNU Utility
#

# Set the command prefix on non-GNU systems.
# zstyle ':prezto:module:gnu-utility' prefix 'g'

#
# History
#

# Set the file to save the history in when an interactive shell exits.
# zstyle ':prezto:module:history' histfile "${ZDOTDIR:-$HOME}/.zsh_history"

# Set the maximum  number  of  events  stored  in  the  internal history list.
# zstyle ':prezto:module:history' histsize 10000

# Set the maximum number of history events to save in the history file.
# zstyle ':prezto:module:history' savehist 10000

#
# History Substring Search
#

# Set the query found color.
# zstyle ':prezto:module:history-substring-search:color' found ''

# Set the query not found color.
# zstyle ':prezto:module:history-substring-search:color' not-found ''

# Set the search globbing flags.
# zstyle ':prezto:module:history-substring-search' globbing-flags ''

# Enable search case-sensitivity.
# zstyle ':prezto:module:history-substring-search' case-sensitive 'yes'

# Enable search for fuzzy matches.
# zstyle ':prezto:module:history-substring-search' fuzzy 'yes'

# Enable search uniqueness.
# zstyle ':prezto:module:history-substring-search' unique 'yes'

# Enable prefixed search.
# zstyle ':prezto:module:history-substring-search' prefixed 'yes'

#
# macOS
#

# Set the keyword used by `mand` to open man pages in Dash.app
# zstyle ':prezto:module:osx:man' dash-keyword 'manpages'

#
# Pacman
#

# Set the Pacman frontend.
# zstyle ':prezto:module:pacman' frontend 'yaourt'

#
# Prompt
#

# Set the prompt theme to load.
# Setting it to 'random' loads a random theme.
# Auto set to 'off' on dumb terminals.
zstyle ':prezto:module:prompt' theme 'agnoster'

# Set the working directory prompt display length.
# By default, it is set to 'short'. Set it to 'long' (without '~' expansion)
# for longer or 'full' (with '~' expansion) for even longer prompt display.
# zstyle ':prezto:module:prompt' pwd-length 'short'

# Set the prompt to display the return code along with an indicator for non-zero
# return codes. This is not supported by all prompts.
# zstyle ':prezto:module:prompt' show-return-val 'yes'

#
# Python
#

# Auto switch the Python virtualenv on directory change.
# zstyle ':prezto:module:python:virtualenv' auto-switch 'yes'

# Automatically initialize virtualenvwrapper if pre-requisites are met.
# zstyle ':prezto:module:python:virtualenv' initialize 'yes'

#
# Ruby
#

# Auto switch the Ruby version on directory change.
# zstyle ':prezto:module:ruby:chruby' auto-switch 'yes'

#
# Screen
#

# Auto start a session when Zsh is launched in a local terminal.
# zstyle ':prezto:module:screen:auto-start' local 'yes'

# Auto start a session when Zsh is launched in a SSH connection.
# zstyle ':prezto:module:screen:auto-start' remote 'yes'

#
# SSH
#

# Set the SSH identities to load into the agent.
# zstyle ':prezto:module:ssh:load' identities 'id_rsa' 'id_rsa2' 'id_github'

#
# Syntax Highlighting
#

# Set syntax highlighters.
# By default, only the main highlighter is enabled.
# zstyle ':prezto:module:syntax-highlighting' highlighters \
#   'main' \
#   'brackets' \
#   'pattern' \
#   'line' \
#   'cursor' \
#   'root'
#
# Set syntax highlighting styles.
# zstyle ':prezto:module:syntax-highlighting' styles \
#   'builtin' 'bg=blue' \
#   'command' 'bg=blue' \
#   'function' 'bg=blue'
#
# Set syntax pattern styles.
# zstyle ':prezto:module:syntax-highlighting' pattern \
#   'rm*-rf*' 'fg=white,bold,bg=red'

#
# Terminal
#

# Auto set the tab and window titles.
# zstyle ':prezto:module:terminal' auto-title 'yes'

# Set the window title format.
# zstyle ':prezto:module:terminal:window-title' format '%n@%m: %s'

# Set the tab title format.
# zstyle ':prezto:module:terminal:tab-title' format '%m: %s'

# Set the terminal multiplexer title format.
# zstyle ':prezto:module:terminal:multiplexer-title' format '%s'

#
# Tmux
#

# Auto start a session when Zsh is launched in a local terminal.
# zstyle ':prezto:module:tmux:auto-start' local 'yes'

# Auto start a session when Zsh is launched in a SSH connection.
# zstyle ':prezto:module:tmux:auto-start' remote 'yes'

# Integrate with iTerm2.
# zstyle ':prezto:module:tmux:iterm' integrate 'yes'

# Set the default session name:
# zstyle ':prezto:module:tmux:session' name 'YOUR DEFAULT SESSION NAME'

#
# Utility
#

# Enabled safe options. This aliases cp, ln, mv and rm so that they prompt
# before deleting or overwriting files. Set to 'no' to disable this safer
# behavior.
# zstyle ':prezto:module:utility' safe-ops 'yes'

Dockerの作成

PowerShellやCmdを起動し、Dockerfile等を配置したディレクトリで以下実行します。

Docker Composeの実行
docker compose up -d

起動したら接続出来るか確認してみます。

今回はworklinuxという名前でコンテナを作成したので、以下のように実行します。

コンテナへの接続
docker exec -it worklinux /bin/zsh

問題なく接続できれば、今回の場合、以下のような表示となるはずです。

Monosnap_20260627_221450.png

Windows Terminal設定

Windows TerminalでDockerに接続するための設定を行っていきます。

Docker接続用プロファイルの作成

Windows Terminalの「設定」から「新しいプロファイルを追加します」で「新しい空のプロファイル」を選択し、以下のように必要な設定を行います。

項目 設定 備考
名前 Docker worklinux 任意の名前を指定
コマンドライン C:\Program Files\Docker\Docker\resources\bin\docker.exe exec -it worklinux /bin/zsh dockerコマンドのパスを指定

その他の設定は自分好みに設定してください。

コマンドラインには、docker.exeのパスを指定して、コマンドを後ろに記載することで、PowerShell等でdocker execコマンドを実行しなくても直接コンテナに接続することができるため、上記のように指定します。

タブ起動時接続設定

設定」→「スタートアップ」の「規定のプロファイル」で先ほど作成したDocker接続用プロファイルを選択して保存します。

Monosnap_20260627_223553.png

変更後、Windows Terminalを立ち上げ直したり、新しいタブを開くと、直接コンテナのプロンプトが立ち上がります。

Monosnap_20260627_224153.png

Nerd Fontのインストール

先ほどインストールしたzpreztoでは、Git管理されたディレクトリに移動すると現在のブランチをプロンプト上で示すモジュールが実装されておりますが、一部特殊なアイコンが使われているため、Windows Terminalで表示すると、以下のように文字化けしてしまいます。(masterの左のアイコン)

Monosnap_20260627_225317.png

機能的には問題ないので、そのまま使い続けてもいいのですが、せっかくなので、きちんと表示できるようにしようと思います。

以下のMicrosoftの公式ドキュメントに、特殊文字を表示するために必要となるNerd Fontのインストール例が紹介されているため、Nerd Fontのページからフォントをダウンロードします。

Nerd Fontのページを開くと、各種フォント用のNerd Fontが用意されているため、今回は、Windows Terminalでもデフォルトフォントとして設定されている「Cascadia Mono」用となる「CaskaydiaMono Nerd Font」をダウンロードします。

Monosnap_20260627_230451.png

ダウンロードしたZipファイルを解凍したら、.ttfファイルのみを選択して「インストール」を行います。

Monosnap_20260627_231105.png

先程の公式ドキュメントには他にもチュートリアルが色々書かれていますが、今回はフォントのインストールだけでOKです。

Nerd Fontの指定

Windows Terminalに戻り、先程作成したプロファイルを選択し、「外観」の「フォント フェイス」をクリックします。

デフォルトでは「Cascadia Mono」が選択されているはずなので、先程インストールした「CaskaydiaMono Nerd Font」を選択して、「保存」します。

Monosnap_20260627_231548.png

コンテナに接続し、Git管理のディレクトリに移動すると、先程は文字化けアイコンだったGitブランチアイコンが先ほどと異なっていることが確認できるかと思います。

Monosnap_20260627_231659.png

AWS Identity Center認証によるAWS CLI実行

急に内容が変わりますが、コンテナ内からIdentity Center認証を行う場合、そのままでは認証を通せないため以下で手順を紹介します。

Identity Centerの一時トークンを使用する場合、最初に以下コマンドでIdentity Centerへログインする必要があります。

aws ssoを使用したログイン
aws sso login --profile [プロファイル名]

実行すると、Webブラウザが立ち上がり、Identity Centerのユーザーでログインすることで、一時トークンが払い出され、コマンド実行ができるようになります。

ただ、aws sso loginをコンテナ内で行うと、コンテナ内で(今回の構成では)Webブラウザが起動できないため、失敗してしまいます。

aws sso loginで払い出された一時トークンは、docker-compose.ymlで共有設定した「C:/Users/username/.aws」配下に出力されることから、Identity Centerの一時トークンを使用する場合は、Windowsホスト側でaws sso loginを実行&一時トークンを払い出した後、コンテナ内でIdentity Centerのプロファイルを指定することでコマンド実行できるので、参考にしてください。

おわりに

今回WindowsでDockerをシームレスに使用するための設定を行いましたが、最初に自分が思っていた以上に、使える構成に仕上がったと思います。

今までWLS2、VirtualBox等、様々な仮想環境を使ってきましたが、単純に作業用途で使うなら、ホスト側OSを選ばないDockerはアリだなと感じました。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?