概要

先日、.NET 6 がリリースされたので、ついでにdockerコンテナで試してみました。
VSCodeのRemote Container使えば一発ですが、Non rootユーザでdocker from dockerとか
試してみたかったので、自前でDockerfileを用意。
Dockfile
FROM mcr.microsoft.com/dotnet/sdk:6.0
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
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
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
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
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
RUN apt-get install -y zip unzip make vim
USER $USERNAME
WORKDIR $WORKSPACE
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