1
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?

「docker compose コマンド打つの面倒くさい!」を解決する Makefile活用術

Posted at

Docker環境を操作するコマンドを楽にしたいならMakefileを作っておくと楽

  • 毎回docker compose up -d とうつのが面倒臭い人むけ。

1. dockerコンテナの立ち上げ(docker compose up -dやdocker compose down)をmakeで実行する

  • Makefile という名前で以下の内容を記述し、保存する。
.PHONY: build \
	up \
	down

# Dockerイメージのビルド
build:
	docker compose build

# コンテナを起動
up:
	docker compose up -d

# コンテナの停止と削除
down:
	docker compose down
  • コンテナを起動してみる

    • make up とターミナルで打つと以下のようになる。
    $ make up
    docker compose up -d
    Compose now can delegate build to bake for better performances
    Just set COMPOSE_BAKE=true
    [+] Building 17.9s (10/10) FINISHED                                                                                                                                                  docker:rancher-desktop
     => [python-dev internal] load build definition from Dockerfile                                                                                                                                        0.0s
     => => transferring dockerfile: 259B                                                                                                                                                                   0.0s
     => [python-dev internal] load metadata for docker.io/library/python:3.11-slim                                                                                                                         2.7s
     => [python-dev internal] load .dockerignore                                                                                                                                                           0.0s
     => => transferring context: 2B                                                                                                                                                                        0.0s
     => [python-dev 1/4] FROM docker.io/library/python:3.11-slim@sha256:82c07f2f6e35255b92eb16f38dbd22679d5e8fb523064138d7c6468e7bf0c15b                                                                   0.0s
     => [python-dev internal] load build context                                                                                                                                                           0.0s
     => => transferring context: 74B                                                                                                                                                                       0.0s
     => CACHED [python-dev 2/4] WORKDIR /workspace                                                                                                                                                         0.0s
     => CACHED [python-dev 3/4] COPY requirements.txt requirements.txt                                                                                                                                     0.0s
     => [python-dev 4/4] RUN pip install --no-cache-dir --upgrade pip &&     pip install --no-cache-dir -r requirements.txt                                                                               14.9s
     => [python-dev] exporting to image                                                                                                                                                                    0.3s 
     => => exporting layers                                                                                                                                                                                0.3s 
     => => writing image sha256:05674b8126330613f7d28a8b315a4538e1f21a7e67275a53fcf84d02c42b3436                                                                                                           0.0s 
     => => naming to docker.io/library/env-setting-learning-python-dev                                                                                                                                     0.0s 
     => [python-dev] resolving provenance for metadata file                                                                                                                                                0.0s 
    [+] Running 3/3                                                                                                                                                                                             
     ✔ python-dev                            Built                                                                                                                                                         0.0s 
     ✔ Network env-setting-learning_default  Created                                                                                                                                                       0.1s 
     ✔ Container env-setting                 Started
    
  • 上記のログの中で、最初にdocker compose up -dと表示されるのを避けたいのであれば、をつける。

    • Makefileを以下のようにする。
    .PHONY: build \
    	up \
    	down
    
    # Dockerイメージのビルド
    build:
    	@ docker compose build # @マークを最初につける
    
    # コンテナを起動
    up:
    	@ docker compose up -d
    
    # コンテナの停止と削除
    down:
    	@ docker compose down
    

2. Makefileで他ファイルに定義されている内容を読みにいく

  • 今回作るもの:

    • make shell というコマンドで動くものを定義してみる。
  • 注意点:

    • 基本的に他のファイルの中身を見にいく時は、.envにその内容を記述しておくのが、GOOD
  • .env ファイルを用意する。

    TEST_ENV_VAL=hello
    
  • Makefileを以下のようにする

    include .env # 追加
    export # 追加
    
    .PHONY: build \
    	up \
    	down \
    	shell # 追加
    
    shell: # 追加
    	@ echo "$(TEST_ENV_VAL)"
    
    # Dockerイメージのビルド
    build:
    	@ docker compose build
    
    # コンテナを起動
    up:
    	@ docker compose up -d
    
    # コンテナの停止と削除
    down:
    	@ docker compose down
    
    
  • ターミナルでmake shell してみる

    $ make shell
    hello
    

3. コンテナ名を自動で取得させる(Makefileで他ファイルの中身を見にいく方法)

  • 2.同様に、.env コンテナの名前を書く。

    TEST_ENV_VAL=hello
    CONTAINER_NAME=env-setting
    
  • コンテナの名前が必要なので、docker-compose.yamlを編集する

    services:
      python-dev: # サービス名 (任意)
        build: . # Dockerfileがあるディレクトリ (カレントディレクトリ)
        container_name: ${CONTAINER_NAME} # .envファイルを読んで、コンテナ名を設定する
        working_dir: /workspace # コンテナ内での作業ディレクトリを指定
        volumes:
          - ./src:/workspace
        tty: true 
        restart: always # コンテナが停止した場合に常に再起動する
    
  • Makefileを編集する

    include .env
    export
    
    .PHONY: build \
    	up \
    	down \
    	shell
    
    shell:
    	@ echo "$(TEST_ENV_VAL)"
    	@ docker exec -it "$(CONTAINER_NAME)" /bin/bash
    
    # Dockerイメージのビルド
    build:
    	@ docker compose build
    
    # コンテナを起動
    up:
    	@ docker compose up -d
    
    # コンテナの停止と削除
    down:
    	@ docker compose down
    
    

実行結果

(今回利用しているDockerfileは、workspaceをWORKING_DIRとしているので、以下のようになる)

% make shell
hello
root@xxxx:/workspace# 
  • コンテナの中に入っていることがわかる。

4. make shellコマンドで、docker compose upとdocker execの両方を実施できるようにする

  • Makefileを編集する

    include .env
    export
    
    .PHONY: build \
    	up \
    	down \
    	shell
    
    # Dockerイメージのビルド
    build:
    	@ docker compose build
    
    # コンテナを起動
    up:
    	@ docker compose up -d
    
    # コンテナの停止と削除
    down:
    	@ docker compose down
    
    shell:
    	@ echo "$(TEST_ENV_VAL)"
    	@ $(MAKE) up
    	@ docker exec -it "$(CONTAINER_NAME)" /bin/bash
    
    • $(MAKE) up とすることで、Makefileの中で定義したup を実行できる
    • 実行結果
    % make shell
    hello
    [+] Running 2/2
     ✔ Network env-setting-learning_default  Created                                                                                                                                                       0.1s 
     ✔ Container env-setting                 Started                                                                                                                                                       0.2s 
    root@a987c008deda:/workspace#
    
    • Dockerの起動と、コンテナの内部に自動で入れるようになった。

最終的に作成したファイル

以下の5ファイルを同じ階層に置いておく。

.
├── Dockerfile
├── docker-compose.yaml
├── requirements.txt
├── Makefile
└── .env
Dockerfile
FROM python:3.11-slim

WORKDIR /workspace

COPY requirements.txt requirements.txt

RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt
docker-compose.yaml
services:
  python-dev: # サービス名 (任意)
    build: . # Dockerfileがあるディレクトリ (カレントディレクトリ)
    container_name: ${CONTAINER_NAME}
    working_dir: /workspace # コンテナ内での作業ディレクトリを指定
    volumes:
      - ./src:/workspace
    tty: true 
    restart: always # コンテナが停止した場合に常に再起動する
requirements.txt
pandas
.env
TEST_ENV_VAL=hello
CONTAINER_NAME=env-setting
Makefile
include .env
export

.PHONY: build \
	up \
	down \
	shell

# Dockerイメージのビルド
build:
	@ docker compose build

# コンテナを起動
up:
	@ docker compose up -d

# コンテナの停止と削除
down:
	@ docker compose down

shell:
	@ echo "$(TEST_ENV_VAL)"
	@ $(MAKE) up
	@ docker exec -it "$(CONTAINER_NAME)" /bin/bash

より高度な使い方:Poetryが使えるDockerコンテナを作成し、それをMakefileから実行させる

以下の4ファイルを同じ階層に置く。ターミナルからmake shellと打てば、Dockerコンテナが立ち上がりかつそのコンテナの中に入れる。
poetryはすでにインストールされているので、自分でプロジェクトを作成すれば、poetry環境下でpython開発を行える。

.
├── Dockerfile
├── docker-compose.yaml
├── Makefile
└── .env
Dockerfile
FROM python:3.11-slim

# ビルドする時だけに利用する変数
# つまり、コンテナ内で環境変数として使えるわけではない
ARG POETRY_VERSION
ARG POETRY_HOME
ARG USER_UID
ARG USERNAME

# 必要なパッケージをインストール(curl等)
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Poetryのインストール
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN curl -sSL https://install.python-poetry.org/ | python3 - --version ${POETRY_VERSION} && \
    ln -s ${POETRY_HOME}/bin/poetry /usr/local/bin/poetry

# コンテナで作成したファイルやフォルダのパーミッションとホストマシンのパーミッションを揃えるための
# 設定を行う
RUN useradd --uid ${USER_UID} -m ${USERNAME} 

USER $USERNAME

WORKDIR /home/${USERNAME}/
docker-compose.yaml
services:
  python-dev: # サービス名 (任意)
    build:
      context: . # Dockerfileがあるディレクトリ (カレントディレクトリ)
      dockerfile: Dockerfile
      args:
        POETRY_VERSION: ${POETRY_VERSION}
        POETRY_HOME: ${POETRY_HOME}
        USER_UID: ${USER_UID}
        USERNAME: ${USERNAME}
    container_name: ${CONTAINER_NAME}
    volumes:
      - type: bind
        source: ./src
        target: /home/${USERNAME}
    working_dir: /home/${USERNAME} # /home/${USERNAME} をworking_dirにしておかないと、リモートでVSCode接続したときに、ホスト側のWORKDIRを見つけられない..
    tty: true 
    restart: always # コンテナが停止した場合に常に再起動する
.env
CONTAINER_NAME=env-setting
POETRY_VERSION=2.1.2
POETRY_HOME=/opt/poetry
Makefile
include .env
export

.PHONY: build \
	up \
	down \
	shell \
	write_uid_onto_env

# Dockerイメージのビルド
build:
	@ docker compose build

# コンテナを起動
up:
	@ docker compose up -d

# コンテナの停止と削除
down:
	@ docker compose down

# ホストマシンのUIDを.envに書き込む
# 一時ファイルに避難させておかないと、USER_UIDやUSERNAMEがずっと追記され続けてしまうので、
# このような実装とした。
write_uid_onto_env:
	@ TEMP_FILE=$$(mktemp); \
	grep -v "^USER_UID=" .env | grep -v "^USERNAME=" > $$TEMP_FILE; \
	echo "USER_UID=$(shell id -u $(shell whoami))" >> $$TEMP_FILE; \
	echo "USERNAME=$$USER" >> $$TEMP_FILE; \
	mv $$TEMP_FILE .env


shell:
	@ $(MAKE) write_uid_onto_env
	@ $(MAKE) build
	@ $(MAKE) up
	@ docker exec -it "$(CONTAINER_NAME)" /bin/bash

まとめ

  • Makefileの定義の仕方や操作方法を学ぶために、Dockerコンテナを立ち上げることを実施した。
  • 追加して、poetryを実行できる環境を作るためのMakefileやDockerファイルなどをおまけで追加しt
1
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
1
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?