My Ultimate Development Container image
Tags: container, development, devops, vscode
Published: 2020-08-14 11:19:43

---
title: My Ultimate Development Container image
published: true
description: A Development environment I've cultivated and used throughout my projects
tags: ["container", "development", "devops", "vscode"]
cover_image: https://source.unsplash.com/tjX_sniNzgQ
---

## My Ultimate Development Container Image

Using [VSCode's Remote Development Feature](https://code.visualstudio.com/docs/remote/remote-overview), we can remotely develop on another station using [SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) or [WSL] (https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl). But my favorite feature is using [Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
We can potentially create isolated development environments per project in a container.

I've cultivated a Container image I use throughout my projects. It includes my most frequently used binaries and tools.

The key here is the layers; they were pre-designed in a way so they could be sharable for all of my containers. Basically:

- Environment variables go at the lowest layer as they rarely get modified.

- Binaries installations go in the next layers separately from one another, so when modified, they'll require only the layers above them to be rebuilt.

- Modules, requirements, dependencies, packages, libraries, etc., go in the top layer as they get modified more frequently.

You can check out the *Dockerfile* source [gist](https://gist.github.com/TomerFi/9949a082dce716d74f361b70b20eb733).
:sunglasses:

```dockerfile
# Base image is Python's image
FROM python:3.8.5

# Set shell with pipeline fail return
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Set environment variables
ENV SHELL=/bin/bash \
    DOTNET_CLI_TELEMETRY_OPTOUT=true \
    JAVA_HOME=/opt/java \
    MAVEN_HOME=/opt/maven \
    PATH_TO_FX=/usr/share/java/ \
    PATH=$PATH:/opt/java/bin:/opt/maven/bin:/opt/gopath/bin:/opt/go/bin:/root/.dotnet/tools

# Install Linux packages (including dotnet and javafx)
RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg \
    && mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/ \
    && curl -sL https://packages.microsoft.com/config/debian/10/prod.list \
        -o /etc/apt/sources.list.d/microsoft-prod.list \
    && apt-get update \
    && apt-get install -y --no-install-recommends apt-transport-https \
    && apt-get install -y --no-install-recommends dotnet-sdk-3.1 \
    && apt-get install -y --no-install-recommends git-lfs \
    && apt-get install -y --no-install-recommends nano \
    && apt-get install -y --no-install-recommends openjfx \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Install java
WORKDIR /opt/java
RUN curl -sOL https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.7%2B10_openj9-0.20.0/OpenJDK11U-jdk_x64_linux_openj9_11.0.7_10_openj9-0.20.0.tar.gz \
    && tar -xf OpenJDK11U-jdk_x64_linux_openj9_11.0.7_10_openj9-0.20.0.tar.gz \
    && rm OpenJDK11U-jdk_x64_linux_openj9_11.0.7_10_openj9-0.20.0.tar.gz \
    && mv jdk-11.0.7+10/* . \
    && rm -r jdk-11.0.7+10

# Install maven
WORKDIR /opt/maven
RUN curl -sOL https://downloads.apache.org/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz \
    && tar -xf apache-maven-3.6.3-bin.tar.gz \
    && rm apache-maven-3.6.3-bin.tar.gz \
    && mv apache-maven-3.6.3/* . \
    && rm -r apache-maven-3.6.3

# Install Node.js (includes npm)
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
    && apt-get install -y --no-install-recommends nodejs \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Install golang
WORKDIR /opt/go
RUN curl -sOL https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz \
    && tar -C /opt -xf go1.14.4.linux-amd64.tar.gz \
    && rm go1.14.4.linux-amd64.tar.gz \
    && bin/go env -w GOPATH=/opt/gopath GO111MODULE=on

# Install modules, requirements, dependencies, packages, libraries, etc.
RUN \
    # Install node modules
    npm install -g \
        commitizen@4.1.2 \
        cz-conventional-changelog@3.2.0 \
        @commitlint/cli@9.1.1 \
        @commitlint/config-conventional@9.1.1 \
        dockerfilelint@1.8.0 \
        jsonlint@1.6.3 \
        markdownlint-cli@0.23.2 \
        semantic-release@17.1.1 \
        yarn@1.22.4 \
    # Install go modules
    && go get -u \
        github.com/bufbuild/buf/cmd/buf@v0.20.5 \
        github.com/bufbuild/buf/cmd/protoc-gen-buf-check-breaking@v0.20.5 \
        github.com/bufbuild/buf/cmd/protoc-gen-buf-check-lint@v0.20.5 \
        github.com/client9/misspell/cmd/misspell@v0.3.4 \
        github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v1.3.2 \
        github.com/yoheimuta/protolint/cmd/protolint@v0.26.0 \
    # Install python dependencies
    && pip install \
        docutils==0.16 \
        pre-commit==2.6.0 \
        robotframework==3.2.1 \
        yamllint==1.24.2 \
    # Install dotnet tools
    && dotnet tool install -g dotnet-format --version 4.1.131201 \
    && dotnet tool install -g dotnet-reportgenerator-globaltool --version 4.6.4
```

I hope you find this helpful.