カテゴリー: docker

  • Ubuntuコンテナにおける利用可能なPHPの version について

    Ubuntuコンテナにおける利用可能なPHPの version について

    背景

    PHPは広く使用されているオープンソースの汎用スクリプト言語で、特にWeb開発に適しています。Dockerコンテナ内で異なるバージョンのPHPが利用できるかどうかは、開発やデプロイのプロセスに大きな影響を与える可能性があります。

    最近、異なるUbuntuコンテナでインストール可能なPHPのバージョンを深く掘り下げる必要がある状況に遭遇しました。

    発見プロセス

    当初、ubuntu:18.04ベースのDockerコンテナにPHPバージョン7.3以上をインストールしようとしました。ppa:ondrej/php を追加しても、7.2以上のバージョンのPHPをインストールすることができませんでした。

    私のプロジェクトの多くは、様々な依存関係やそれ以降のPHPバージョンで導入された機能により、少なくともPHP 7.3が必要だったため、この制限は大きな課題となりました。

    Ubuntu 18.04での実験

    ubuntu:18.04コンテナを使い、以下のコマンドを活用してPHP 7.3と8.0のインストールを試みました

    sudo add-apt-repository ppa:ondrej/php
    sudo apt-get update
    sudo apt-get install php7.3

    以下の様なエラーになりました

    E: Unable to locate package php7.3
    E: Couldn't find any package by glob 'php7.3'
    E: Couldn't find any package by regex 'php7.3'

    Ubuntu 20.04への乗り換え

    ubuntu:18.04で直面した課題に促され、Dockerコンテナをubuntu:20.04に切り替えることにしました。

    同じ手順を適用したところ、PHPバージョン7.3、7.4、そしてPHP 8.0まで問題なくインストールできました。

    分析

    このことにより、ベースイメージが利用可能なPHP の version に影響することが明確になりました。Ubuntu 18.04は古いLTSリリースであるため、時には複雑な設定を追加しなければ、7.2以上のPHPバージョンをネイティブにサポートしていません。

    対照的に、最新のLTSバージョンであるUbuntu 20.04は、ソフトウェアの互換性と可用性の進歩を反映して、新しいPHPバージョンをすぐにサポートしています。

    結論

    Docker環境でPHPを扱う開発者やDevOpsエンジニアにとって、ベースコンテナイメージとソフトウェアパッケージの可用性の関係を理解することは非常に重要です。

    PHPのバージョン7.3以降を使用する予定であれば、ubuntu:20.04コンテナを選択するのが、より簡単で効率的な選択かと思います。

    推奨事項

    • プロジェクトのセットアップを開始する前に、選択したUbuntuコンテナのバージョンとのPHPバージョンの互換性を必ず確認してください。
    • 新しいPHPバージョンのサポートが必要な場合は、Dockerコンテナを新しいUbuntuバージョンにアップグレードすることを検討してください。
    • UbuntuのリリースでサポートされているPHPのバージョンについて常に情報を入手し、スムーズな開発とデプロイを行いましょう。

  • Dockerの未タグ付けイメージを一括削除:ストレージの最適化方法

    Dockerの未タグ付けイメージを一括削除:ストレージの最適化方法

    はじめに

    Dockerを使用していると、ビルドやテストの過程で多数の未使用、未タグ付けのイメージが生成されることがあります。これらは、<none>として表示され、時間とともにストレージを圧迫してしまいます。特に、頻繁にイメージをビルドする開発者や、ストレージ容量に制限がある環境で作業している人にとって、この問題は大きな悩みの一つです。

    未タグ付けイメージとは?

    Dockerの未タグ付けイメージは、以前のビルドからの残骸や、新しいイメージをビルドする際に古いイメージがタグなしで残されることが原因で生成されます。これらは<none>として表示され、通常は手動での削除が必要です。

    未タグ付けイメージの一括削除方法

    以下のコマンドを使用して、未タグ付けのイメージを一括で削除することができます。

    docker rmi $(docker images -f "dangling=true" -q)

    このコマンドは、未タグ付けのイメージIDをリストし、それをdocker rmiコマンドに渡して削除します。

    注意点

    未タグ付けのイメージを削除する前に、使用中のコンテナが存在しないか確認してください。使用中のコンテナがある場合、関連するコンテナを先に停止または削除する必要があります。

    まとめ

    Dockerの未タグ付けイメージはストレージの無駄な使用を引き起こす可能性があります。定期的にこれらのイメージをクリーンアップすることで、効率的なストレージ管理を実現できます。上記のコマンドを利用して、容易にストレージの最適化を行うことができます。

  • Dockerビルドエラーの解消: ストレージ不足とその対処法

    Dockerビルドエラーの解消: ストレージ不足とその対処法

    はじめに: Dockerを利用している際に、ビルドプロセス中に突如としてエラーが発生することがあります。この記事では、特にapt-get updateapt-get install コマンドの実行中に起きたエラーと、それを解消するために行った対処法について解説します。

    問題の発生: Dockerイメージのビルド中に以下のエラーメッセージが表示されました。

    #0 1.518 Err:1 http://deb.debian.org/debian bullseye InRelease
    #0 1.518 At least one invalid signature was encountered.
    ...
    #0 2.793 E: The repository 'http://deb.debian.org/debian bullseye-updates InRelease' is not signed.
    ERROR: failed to solve: process "/bin/sh -c apt-get update && apt-get install -y openssh-client git libzip-dev && rm -rf /var/lib/apt/lists/*" did not complete successfully: exit code: 100

    これにより、Dockerビルドが中断され、ビルドプロセスが完了しませんでした。

    原因の特定: 初めは、リポジトリの署名エラーが原因であると考えましたが、実際にはストレージの不足が原因でした。Dockerはビルドプロセス中に一時的なファイルを生成し、これがストレージ容量を消費します。特に、apt-get install コマンドは、パッケージのダウンロードとインストールのために一時的なファイルを作成します。

    対処法: ストレージの空き容量を確保する必要がありました。以下のコマンドを使用して、未使用のDockerリソースを削除し、ストレージ空間を解放しました。

    docker system prune --volumes

    このコマンドは、未使用のコンテナ、ネットワーク、イメージ、およびボリュームを削除し、必要な空き容量を確保します。

    結果: コマンドの実行後、再度Dockerビルドを試みたところ、今回のエラーは解消され、ビルドプロセスが正常に完了しました。

    まとめ: Dockerを使用する際は、十分なストレージ容量が確保されていることを確認することが重要です。また、定期的に未使用のDockerリソースをクリーンアップすることで、このような問題を未然に防ぐことができます。今回の経験は、Dockerのエラーメッセージが常に明確でないことを示しており、エラーの原因を特定し解決するためには、さまざまな角度からのトラブルシューティングが必要であることを思い出させてくれました。

    以上の内容を参考にして、Docker環境におけるトラブルシューティングの知識とスキルをさらに磨くことができることを願っています。

  • ECS: exec format error 問題への対処

    ECS: exec format error 問題への対処

    Dockerを使ったアプリケーションのデプロイは現代の開発プロセスの基盤となっています。しかし、Dockerイメージのビルドからデプロイまでの過程で予期しないエラーに遭遇することがあります。今回は、ECSでの「exec format error」というエラーの原因と解決方法を共有します。

    問題の発生

    特定のアーキテクチャ(例: ARM)でビルドされたDockerイメージを、異なるアーキテクチャ(例: amd64)の環境で実行しようとすると、「exec format error」というエラーが発生します。

    この問題は、特にM1チップを搭載したMacなどのARMアーキテクチャのマシンでDockerを使用してイメージをビルドする際によく見られます。ARMベースのイメージを、amd64アーキテクチャの環境(例: ECS)で実行しようとすると、上記のエラーが発生します。

    解決策: --platform オプションの使用

    Dockerビルド時に、--platformオプションを使用してアーキテクチャを明示的に指定することで、この問題を解決することができます。

    例:

    docker build --platform linux/amd64 -f Dockerfile -t your-image-name .

    このオプションを使用することで、イメージは指定されたアーキテクチャでビルドされます。

    まとめ

    アーキテクチャの違いは、Dockerイメージのビルドとデプロイの間で予期しない問題を引き起こすことがあります。この問題を回避するためには、ビルド時にターゲットアーキテクチャを明示的に指定することが重要です。--platformオプションを活用して、ECSやその他のデプロイ環境でのエラーを防ぎましょう。

  • Error response from daemon: Ports are not available: exposing port TCP 127.0.0.1:80 -> 0.0.0.0:0: not allowed as current user. You can enable privileged port mapping from Docker -> Settings… -> Advanced -> Enable privileged port mapping

    Error response from daemon: Ports are not available: exposing port TCP 127.0.0.1:80 -> 0.0.0.0:0: not allowed as current user. You can enable privileged port mapping from Docker -> Settings… -> Advanced -> Enable privileged port mapping

     

     ports:
    - ${LOCAL_IP}:80:80
    - ${LOCAL_IP}:443:443

    docker-compose で上記のように 80, 443 のような 1023 番以下のport をマッピングさせようとしたところ、エラーになることがあります。

    Error response from daemon: Ports are not available: exposing port TCP 127.0.0.1:80 -> 0.0.0.0:0: not allowed as current user.
    You can enable privileged port mapping from Docker -> Settings... -> Advanced -> Enable privileged port mapping

    一般的にエラー文言に従い、Dockerの設定から “Enable privileged port mapping” を有効にしましたが、エラーが解消されない状況に陥りました。

    この問題に直面したとき、Dockerの設定でCLIツールのインストール方法を変更することで回避できました。

    具体的には、Dockerの設定の “Advanced” タブから “Choose how to configure the installation of Docker’s CLI tools” を開き、その設定を “User” から “System” に変更しました。

     

    この変更により、Dockerはシステムレベルで動作するようになり、これにより特権ポートを使用するための必要な権限を得ることができるようになるようです。

    結果として、ポート80と443が正常に割り当てられるようになり、エラーは解消しました。

     

     

  • M1 MacでDockerを使ってPowerShellを動作させる

    M1 MacでDockerを使ってPowerShellを動作させる

    M1 MacでDockerを使用してPowerShellを動作させる際には、いくつかの課題が生じる可能性があります。

    この記事では、DockerfileをM1 Macでビルドする際に遭遇する可能性がある問題とその解決策を説明します。

    問題の概要

    以下のDockerfileを使用してビルドを試みると、特定のエラーが発生する可能性があります。

    FROM --platform=linux/x86_64 mcr.microsoft.com/powershell:7.3-ubuntu-22.04
    RUN pwsh -Command Install-Module -Name Microsoft.Graph -Scope AllUsers -F

    エラーメッセージは以下の通りです。

    ---> [Warning] The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
    ---> Running in 28a633eea3df
    An error has occurred that was not properly handled. Additional information is shown below. The PowerShell process will exit.
    An error has occurred that was not properly handled. Additional information is shown below. The PowerShell process will exit.
    qemu: uncaught target signal 11 (Segmentation fault) - core dumped
    Segmentation fault
    The command '/bin/sh -c pwsh -Command Install-Module -Name Microsoft.Graph -Scope AllUsers -F' returned a non-zero code: 139

    このエラーは、使用しているイメージのプラットフォームがホストと一致しない場合に発生します。

    具体的には、このエラーはx86_64(AMD64)プラットフォーム向けのイメージをARM64プラットフォーム(M1 Macが使用しているプラットフォーム)で実行しようとしたときに発生します。

    さらに、Segmentation faultというエラーになることもあります。

    これは、プログラムが不正なメモリ領域にアクセスしようとしたときに発生します。

    このエラーは通常、プログラムのバグや、プログラムが不適切な方法でメモリを操作した結果として発生します。

    この場合、エラーはQEMU(異なるCPUアーキテクチャ間でのエミュレーションを提供するソフトウェア)から発生しており、x86_64プラットフォーム向けのコードをARM64プラットフォームで実行しようとしたことが原因と考えられます。

    解決策

    この問題を解決するためには、ARM64プラットフォーム向けのPowerShellを直接インストールする必要があります。

    https://github.com/GitSumito/CodeArsenal/blob/main/Powershell_On_Docker_For_M1Mac/Dockerfile

    上のリポジトリは build したDockerfile です。

    以下 Dockerfile の解説です。

    # Select the base image
    FROM arm64v8/ubuntu:latest

    この行では、ベースイメージとしてARM64プラットフォーム向けの最新のUbuntuイメージを選択しています。

    # Update the package lists for upgrades for security purposes
    RUN apt-get update && apt-get upgrade -y

    この行では、セキュリティのためにパッケージリストを更新し、アップグレードします。

    # Install necessary tools
    RUN apt-get install -y curl wget tar sudo
    # Install the ICU library
    RUN apt-get install -y libicu-dev

    この行では、ICU(International Components for Unicode)ライブラリをインストールしています。ICUは、Unicodeとグローバリゼーション(i18n)サポートを提供するC/C++およびJavaライブラリです。

    # Download the PowerShell binary
    RUN wget -O /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz

    この行では、PowerShellのバイナリをダウンロードしています。wgetコマンドを使用して、指定したURLからPowerShellのtar.gzファイルをダウンロードし、/tmpディレクトリにpowershell.tar.gzという名前で保存します。

    # Create the target folder where PowerShell will be placed
    RUN mkdir -p /usr/local/microsoft/powershell/7.3.4

    この行では、PowerShellが配置されるターゲットフォルダを作成します。

    # Expand PowerShell to the target folder
    RUN tar zxf /tmp/powershell.tar.gz -C /usr/local/microsoft/powershell/7.3.4

    この行では、ダウンロードしたPowerShellのtar.gzファイルをターゲットフォルダに展開します。

    # Set execute permissions
    RUN chmod +x /usr/local/microsoft/powershell/7.3.4/pwsh

    この行では、PowerShell実行ファイルに実行権限を設定します。

    # Create a symbolic link that points to pwsh
    RUN ln -s /usr/local/microsoft/powershell/7.3.4/pwsh /usr/local/bin/pwsh

    この行では、pwshへのシンボリックリンクを作成します。これにより、どのディレクトリからでもpwshコマンドを使用してPowerShellを起動できるようになります。

    # Install necessary PowerShell modules
    RUN pwsh -Command Install-Module -Name ExchangePowerShell -F
    RUN pwsh -Command Install-Module -Name Microsoft.Graph -F

    最後に、必要なPowerShellモジュールをインストールします。この例では、ExchangePowerShellモジュールとMicrosoft.Graphモジュールをインストールします。

    Dockerfileのビルドが成功すると、以下のような出力が表示されます:

    ---> c6bd065a23d8
    Step 6/11 : RUN mkdir -p /usr/local/microsoft/powershell/7.3.4
    ---> Running in 77c3cfaf924e
    Removing intermediate container 77c3cfaf924e
    ---> 19263b7b1096
    Step 7/11 : RUN tar zxf /tmp/powershell.tar.gz -C /usr/local/microsoft/powershell/7.3.4
    ---> Running in 6f9b149944ae
    Removing intermediate container 6f9b149944ae
    ---> 86c0945e8a86
    Step 8/11 : RUN chmod +x /usr/local/microsoft/powershell/7.3.4/pwsh
    ---> Running in bed70b0443d1
    Removing intermediate container bed70b0443d1
    ---> b767beaee0b3
    Step 9/11 : RUN ln -s /usr/local/microsoft/powershell/7.3.4/pwsh /usr/local/bin/pwsh
    ---> Running in 26c1c7b4b1cf
    Removing intermediate container 26c1c7b4b1cf
    ---> ff72047deef1
    Step 10/11 : RUN pwsh -Command Install-Module -Name ExchangePowerShell -F
    ---> Running in e024612672c1
    Removing intermediate container e024612672c1
    ---> 08eb8f79bdd4
    Step 11/11 : RUN pwsh -Command Install-Module -Name Microsoft.Graph -F
    ---> Running in 2988a85004a6
    Removing intermediate container 2988a85004a6
    ---> 0205240f3f6f
    Successfully built 0205240f3f6f
    Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

    このDockerfileを使用することで、M1 MacでもDocker上でPowerShellを動作させることが可能になります。

  • Docker:未タグ付けイメージの効率的な削除方法

    Docker:未タグ付けイメージの効率的な削除方法

    Dockerの活用において、管理が複雑化しやすい一部分として、未タグ付け(”dangling”または”untagged”とも表現される)のイメージが存在します。 これらのイメージは新たなビルドにより生成される一方で、古いイメージのタグが剥がれることで生じます。 これらの未タグ付けのイメージが増えると、ディスクスペースの消費が増大し、リソースの効率的な使用が妨げられます。 そこで、本記事では未タグ付けのDockerイメージを一括で削除する方法について説明します。具体的な手順は以下の通りです。

    docker rmi $(docker images -f "dangling=true" -q)

    このコマンドについて詳しく見ていきましょう。

    • docker images -f "dangling=true" -q: このコマンドは、未タグ付けのイメージのIDを一覧表示します。フィルタリングオプション-fで”dangling=true”を指定し、出力オプション-qでIDのみを出力します。
    • docker rmi: このコマンドは、指定したイメージを削除します。前述のコマンドで取得したイメージIDをこのコマンドに渡します。

    このコマンドラインを実行することで、未タグ付けのイメージを効率的に削除できます。 ただし、注意すべき点として、この操作にはDockerデーモンへの管理者権限が必要です。 また、使用しているDockerのバージョンによっては、”dangling”ではなく”untagged”という語句を使用する必要があるかもしれません。 以上が、Dockerで未タグ付けのイメージを一括で削除する方法になります。 この方法を用いて、ディスクスペースの有効活用を図り、システムの効率的な運用を実現しましょう。

  • docker remote repository に image があるか確認する

    dokcer manifest inspect を使って確認することができる

    $ docker manifest inspect $IMAGE_NAME:$IMAGE_TAG
    

    上記コマンドを実行して、イメージが存在していると

    {
    	"schemaVersion": 2,
    	"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
    	"config": {
    		"mediaType": "application/vnd.docker.container.image.v1+json",
    		"size": 9641,
    		"digest": "sha256:xxxxxxx"
    	},
    	"layers": [
    

    というレスポンスを返す

    存在しない場合は以下のようなレスポンスになる

    no such manifest:
    

    そのため

    $ docker manifest inspect $IMAGE_NAME:$IMAGE_TAG > /dev/null ; echo $?
    

    で存在確認が可能

  • [6785] INTERNAL ERROR: cannot create temporary directory!

    原因

    一時領域を作ることができないほどdiskが圧迫している。

    対処

    空き容量を確保する

    docker rm -f $(docker ps -a -q)

    docker builder prune -a -f

    上記両方を行うことで容量を確保できることが多い。

  • What to do when /Var/Lib/Docker/Overlay2 gets bloated in Docker

    Introduction

    I ran out of storage on my docker build server. I need to delete unnecessary files, but there is a command to safely allocate space.

    What to do first

    grasp of the situation

    Identify what is putting pressure on the disk in docker.

    Use docker system df command, you can identify the disk usage related to docker.

    # docker system df
    TYPE                    TOTAL      ACTIVE     SIZE       RECLAIMABLE
    Images               9              1              2.014GB   1.962GB (97%)
    Containers           2              0              0B              0B
    Local Volumes        4              2              824.6MB   781.2MB (94%)
    Build Cache          0              0              0B              0B
    

    cope

    It will remove stopped containers, unused volumes, unused networks, and unused images.

    docker system prune

    However, the option to delete unused volumes and images is required.

    # docker system prune --help
    
    Usage:	docker system prune [OPTIONS]
    
    Remove unused data
    
    Options:
      -a, --all             Remove all unused images not just dangling ones
          --filter filter   Provide filter values (e.g. 'label=<key>=<value>')
      -f, --force           Do not prompt for confirmation
          --volumes         Prune volumes
    

    Delete Volumes

    I was able to reduce the size of the file by 355.4MB.

    553d15cd6b78ad0f21788a22e9ce16a7295c4bab97609973
    deleted: sha256:7ae9338aed73a0f33568db53740431038d3a1f779c4dae40d27433984e1cd97c
    deleted: sha256:b1be54c8cadff1e50b87b93559320a1ae57b8d0dd326507148f7ca81d707beed
    deleted: sha256:86d78f10b9718618eaae056f5dfa1edae518949aee4578e4147268e9db2e75f0
    
    Total reclaimed space: 355.4MB

    However, this does not remove the storage.

    use –volumes optiion. you can also delete storage.

    docker system prune --volumes
    WARNING! This will remove:
            - all stopped containers
            - all networks not used by at least one container
            - all volumes not used by at least one container
            - all dangling images
            - all build cache
    Are you sure you want to continue? [y/N] y

    Deleting Images

    If you choose –all option. you can also delete images.

    # docker system prune --all
    WARNING! This will remove:
            - all stopped containers
            - all networks not used by at least one container
            - all images without at least one container associated to them
            - all build cache
    Are you sure you want to continue? [y/N]

    After work

    When you finish deleting unnecessary files, it will be zero.

    # docker system df
    TYPE    TOTAL   ACTIVE  SIZE    RECLAIMABLE
    Images  0    0    0B   0B
    Containers    0    0    0B   0B
    Local Volumes 0    0    0B   0B
    Build Cache   0    0    0B   0B