Developing in a Linux Container on Macbook M1/M2 (via Linux VM)

Kevin Haritmonds
3 min readJan 8, 2022

--

Okay, the title seems complicated. Let me tell what I want to achieve:

  • I don’t want to install any software on my Macbook M1/M2.
  • I want to based my development environment on Linux.
  • I don’t want to install any development packages on Linux.

Why do I want this?

  • I want my development environment to be detached to the hardware I’m using. This means I can choose and use any hardware that I like. Be it a Macbook M1/M2, a Windows laptop, etc.
  • Development is based on Linux. I don’t want to use Brew (package manager for Mac) or Chocolatey (package manager for Windows). Using Linux means I need to research only one way to do a thing. Say: how to install applications and packages, to configure them, etc. It will work the same regardless of the OS and hardware.
  • When I deploy a service, most probably it’ll be deployed on a Linux machine.
  • Today it’s quite common to find different service having different software requirements. And they might be conflicting to one another. Say a service is using Node 10, and another service is using Node 16. Or a service is using Python 3.5 and another service is using Python 3.9.
  • Developing on a Container means there is no development packages installed on the Linux! Think about this for a while. All our development is done on a Container. The Container will contain all the development packages required. When we want to develop another service, we can easily switch to use another Container.
  • This provides additional bonus that Software Engineers don’t need to spend time to set up their development environment. Just download a code repository from Git, and debug/run. As simple as that!
  • We develop in the same environment as the production container will run, limiting issues due to differences between environments.

Okay, here’s the steps in summary:

  1. On my Macbook M1/M2, I only need to install Parallels Desktop for Mac (it supports M1/M2 Mac). Any other VM technology such as UTM or VMware should be fine.
  2. I created Linux “Debian 10 ARM64” VM. I’m using the one provided by Parallels. Notice that the Linux is using arm64 architecture. So all software we are using in Linux must be compiled for arm64. Luckily, majority software are already available.
  3. Install the following on Linux:
    Visual Studio Code for Linux (arm64)
    Docker for Linux (arm64)
  4. Install Visual Studio Code extension Remote Containers.
  5. Develop inside a Container:
    – You’d need to create “.devcontainer/” directory in your code. See example for Node.js, Python 3, or C++11.
    – Launch Visual Studio Code from Linux: code . --disable-gpu
    – Visual Studio Code detects the presence of “.devcontainer/” in our code and automatically asks to install Remote - Containers extension. Go ahead and install this extension.
    – Use Command Palette (F1) to “Remote-Containers: Reopen in Container”.
    – Visual Studio Code automatically builds the Docker image (Dev Container), maps our code directory into Dev Container, and executes postCreateCommand which will populate “node_modules/” in local directory. Wow!
    – Notice we didn’t even have npm / yarn or Node installed in Linux. Everything is done inside Container.
    – Press F5 to start debugging. It shows Running on http://0.0.0.0:3000, which is hosted in Linux. You can also put breakpoints to debug.

Please let me know in comments if you need help on step-by-step details.

Linux Debian 10 VM on a Macbook M1/M2
I can launch and debug a Node app in Linux, even though I don’t have Node installed in Mac nor Linux VM (the Node app is running in a container).

--

--