いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

.NET 6 を Docker コンテナで試す (Dockerfile, VSCode)

概要

f:id:gsf_zero1:20211029114036p:plain

先日、.NET 6 がリリースされたので、ついでにdockerコンテナで試してみました。

VSCodeのRemote Container使えば一発ですが、Non rootユーザでdocker from dockerとか 試してみたかったので、自前でDockerfileを用意。

Dockfile

FROM mcr.microsoft.com/dotnet/sdk:6.0

# Arguments
ARG USERNAME=dev
ARG DOCKER_NONROOT_USER=$USERNAME
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG USER_SHELL=/bin/bash
ARG WORKSPACE=/app

# Create the user with sudo support
#   https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user
RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID --shell $USER_SHELL -m $USERNAME \
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

# Install Docker CE CLI
#   https://github.com/microsoft/vscode-dev-containers/tree/main/containers/docker-from-docker
RUN apt-get update \
    && apt-get install -y apt-transport-https ca-certificates curl gnupg2 lsb-release \
    && curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | apt-key add - 2>/dev/null \
    && echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list \
    && apt-get update \
    && apt-get install -y docker-ce-cli

# Install Docker Compose
#   https://github.com/microsoft/vscode-dev-containers/tree/main/containers/docker-from-docker
RUN LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")') \
    && curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
    && chmod +x /usr/local/bin/docker-compose

# Make docker-init.sh
#   https://github.com/microsoft/vscode-dev-containers/tree/main/containers/docker-from-docker
RUN echo "#!/bin/sh\n\
    sudoIf() { if [ \"\$(id -u)\" -ne 0 ]; then sudo \"\$@\"; else \"\$@\"; fi }\n\
    SOCKET_GID=\$(stat -c '%g' /var/run/docker.sock) \n\
    if [ \"${SOCKET_GID}\" != '0' ]; then\n\
        if [ \"\$(cat /etc/group | grep :\${SOCKET_GID}:)\" = '' ]; then sudoIf groupadd --gid \${SOCKET_GID} docker-host; fi \n\
        if [ \"\$(id ${DOCKER_NONROOT_USER} | grep -E \"groups=.*(=|,)\${SOCKET_GID}\(\")\" = '' ]; then sudoIf usermod -aG \${SOCKET_GID} ${DOCKER_NONROOT_USER}; fi\n\
    fi\n\
    exec \"\$@\"" > /usr/local/share/docker-init.sh \
    && chmod +x /usr/local/share/docker-init.sh

# Install tools
RUN apt-get install -y zip unzip make vim

# Change user and workdir
USER $USERNAME
WORKDIR $WORKSPACE

# VS Code overrides ENTRYPOINT and CMD when executing `docker run` by default.
# Setting the ENTRYPOINT to docker-init.sh will configure non-root access to
# the Docker socket if "overrideCommand": false is set in devcontainer.json.
# The script will also execute CMD if you need to alter startup behaviors.
#
#   https://github.com/microsoft/vscode-dev-containers/tree/main/containers/docker-from-docker
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
CMD [ "sleep", "infinity" ]

んで、実際にイメージをビルドして中に入ってみましょう。

$ docker image build -t dotnet6env -f Dockerfile ${PWD}

$ docker container run -d -it -v ${PWD}:/app --rm dotnet6env
d2aafa7efb73d894a4e7db08f9735f479556ca22f691e0e250aad8264c2f1922

$ docker container exec -it d2aa bash
dev@d2aafa7efb73:/app$


dev@d2aafa7efb73:/app$ ls
Dockerfile


dev@d2aafa7efb73:/app$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.100
 Commit:    9e8b04bbff

Runtime Environment:
 OS Name:     debian
 OS Version:  11
 OS Platform: Linux
 RID:         debian.11-x64
 Base Path:   /usr/share/dotnet/sdk/6.0.100/

Host (useful for support):
  Version: 6.0.0
  Commit:  4822e3c3aa

.NET SDKs installed:
  6.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

ちゃんと、.NET 6が入っていますね。

てことで、C# 10が使えるか(使えるに決まっているのですが)を確認。

dev@d2aafa7efb73:/app$ dotnet new console
The template "Console App" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on /app/app.csproj...
  Determining projects to restore...
  Restored /app/app.csproj (in 72 ms).
Restore succeeded.

dev@d2aafa7efb73:/app$ cat Program.cs
<feff>// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

dev@d2aafa7efb73:/app$ dotnet run
Hello, World!

初期生成されたコードは一行だけなので、以下のように変更します。

dev@d2aafa7efb73:/app$ cat << EOF > Program.cs
> class App
> {
>   record struct Point(int X, int Y);
>   static void Main()
>   {
>     var p = new Point(10, 20);
>
>     int x = 0;
>     (x, var y) = p;
>
>     Console.WriteLine($"{x},{y}");
>   }
> }
> EOF

record struct(x, var y) = p; の部分が C# 10 の新機能ですね。

では、動くか確認

dev@d2aafa7efb73:/app$ dotnet run
10,20

オッケイですね。てことで、このコンテナはバイバイ。

$ docker container list
CONTAINER ID   IMAGE                                                 COMMAND                  CREATED          STATUS          PORTS     NAMES
d2aafa7efb73   dotnet6env                                            "/usr/local/share/do…"   11 minutes ago   Up 11 minutes             affectionate_easley

$ docker container stop d2aa
d2aa

VSCode の devcontainer.json

VSCode で動かす場合は以下のように devcontainer.json を作るといい感じですね。

{
    "name": "dotnet6",
    "runArgs": [ "--init", "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
    "mounts": [
        "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" 
    ],
    "overrideCommand": false,
    "remoteUser": "vscode",
    "updateRemoteUserUID": true,
    "build": {
        "dockerfile": "../Dockerfile",
        "context": "..",
        "args": {
            "USERNAME": "vscode"
        }
    },
    "settings": {
    },
    "extensions": [
        "ms-dotnettools.csharp"
    ]
    // "forwardPorts": [],
    // "postCreateCommand": "apt-get update && apt-get install -y curl",
}

参考情報

devlights.hatenablog.com

code.visualstudio.com

github.com

docs.microsoft.com

ufcpp.net


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com