Erste Schritte mit Remote Containern in VS Code

Eher zufällig bin ich auf das Feature Remote Containers vom Visual Studio Code gestoßen. Mit den Remote Containers macht VS Code möglich, dass man eine Konfiguration von VS Code in einen Docker Container verpackt. Das klingt erstmal nicht besonders aufregend, wird aber interessant, wenn man bedenkt, dass dieser Container dann auch schon die Entwicklungsabhängigkeiten enthalten kann. Ich kann mir also eine Arbeitsumgebung für z.B. TypeScript bauen, die alle notwendigen Tools wie npm, yarn… und sinnvolle Entwicklungsplugins schon enthält und kann die entsprechenden Dockerfiles und Konfigurationsdateien mit ins Git Repository aufnehmen.

Wie sieht das Ganze praktisch aus? In einem Unterordner .devcontainer liegen eine devcontainer.json und weitere Dateien. Neben einem Dockerfile ist auch der Einsatz von docker-compose möglich. Im folgenden Beispiel passe ich die Installation der Plugins an, so dass Plugins für Clojure bereits installiert sind. Im Dockerfile installiere ich leiningen, das Build-Tool für Clojure.

{
	"name": "Java 12",
	"dockerFile": "Dockerfile",

	// Set *default* container specific settings.json values on container create.
	"settings": { 
		"terminal.integrated.shell.linux": "/bin/bash",
		"java.home": "/usr/java/openjdk-12",
		"git.ignoreLegacyWarning": true
	},

	// Add the IDs of extensions you want installed when the container is created.
	"extensions": [
        "vscjava.vscode-java-pack",
        "betterthantomorrow.calva"
	],

	// Use 'forwardPorts' to make a list of ports inside the container available locally.
	// "forwardPorts": [],

	// Use 'postCreateCommand' to run commands after the container is created.
	"postCreateCommand": [
        "/home/vscode/bin/lein",
        "git clone https://github.com/functional-koans/clojure-koans.git",
        "cd clojure-koans",
        "lein koan run"
    ],

	// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
	"remoteUser": "vscode"
}
{
FROM openjdk:12-jdk

ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
    # [Optional] Add sudo support for the non-root user
    && yum install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME 

# Verify git, needed tools installed
RUN yum install -y git openssh-clients less net-tools which curl procps unzip

# Install leiningen
# das stammt von mir!
RUN mkdir /home/${USERNAME}/bin
RUN curl https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein -o /home/${USERNAME}/bin/lein
RUN chmod a+x /home/${USERNAME}/bin/lein

# Clean yum cache
RUN yum clean all

# Allow for a consistent java home location for settings - image is changing over time
RUN if [ ! -d "/docker-java-home" ]; then ln -s "${JAVA_HOME}" /docker-java-home; fi

Fazit: Die Remote Containers sind eine sinnvolle Sache, wenn ich einmal alle Entwicklungsabhängigkeiten zentral bündeln möchte. Gerade wenn ich meinen Rechner frei von x Installationen halten möchte, bietet dieses Feature die Möglichkeit, die ganzen Dependencies elegant zu verpacken. Auch neuen Entwicklern in einem Projekt kann es den Einstieg enorm vereinfachen, weil der ganze Installationskrampf wegfällt.