I often test "new things" (software, language, ...), and I need a new clean environment every time. For this, Gitpod is the perfect day-to-day tool (at least for me). But, sometimes, I need a local development environment, even several local development environments. I'm working with a MacBook pro M1 (arm architecture), and I tried several solutions.
The DevContainer solution with VSCode is too slow (I use the same image as my GitPod projects, and you can run linux/amd64
with Docker Desktop for Mac M1. It works, but it is slow, and I encountered issues with the Rut compilation of some projects).
So, I tried OpenVSCode Server with Docker; it's pretty nice, you get VSCode in your browser, and you can derive your own Docker image from gitpod/openvscode-server:latest
and then add your tools (for example, install GoLang, Rust, ...). But there's always a time when I struggle with Docker, and I can't manage to install or configure the tools I want.
Ultimately, my last successful try was with OpenVSCode Server running in a Multipass VM.
Let me explain my process.
Prepare the project
Of course, you must install Multipass (my process should work on macOS and Linux).
I created a directory with sub-directories with the following structure:
.
├── config
│ └── .env
├── scripts
│ └── .gitkeep
├── vm.cloud-init.yaml
└── workspace
└── .gitkeep
I will share the two sub-directories scripts
and workspace
with the OS of the VM and my host system. The config
directory is to store a .env
file (used when creating the VM) and some generated files at the end of the process.
This is the content of the .env
file:
VM_NAME="my-little-ide"
VM_CPUS=4
VM_MEM="8G"
VM_DISK="20GB"
VM_DOMAIN="my-little-ide.local"
OPENVSCODE_SERVER_VERSION="1.74.2"
OPENVSCODE_SERVER_OS="linux"
OPENVSCODE_SERVER_ARCH="arm64"
OPENVSCODE_SERVER_PORT="8080"
This is the content of the vm.cloud-init.yaml
file:
package_update: true
manage_etc_hosts: "localhost"
This file allows to tune the install of the Multipass VM (more information here: https://ubuntu.com/blog/using-cloud-init-with-multipass)
The VM creation script
At the root of the main directory, I added a create-vm.sh
script (with the execution rights: chmod +x create-vm.sh
):
#!/bin/bash
set -o allexport; source config/.env; set +o allexport
echo "🖥️ creating ${VM_NAME}"
multipass launch --name ${VM_NAME} \
--cpus ${VM_CPUS} \
--mem ${VM_MEM} \
--disk ${VM_DISK} \
--cloud-init ./vm.cloud-init.yaml
# share the directories
multipass mount scripts ${VM_NAME}:scripts
multipass mount workspace ${VM_NAME}:workspace
VM_IP=$(multipass info ${VM_NAME} | grep IPv4 | awk '{print $2}')
multipass info ${VM_NAME}
echo "${VM_IP} ${VM_DOMAIN}" > config/vm.hosts.config
# Install and Start OpenVSCode Server
multipass --verbose exec ${VM_NAME} -- bash <<EOF
echo "💾 Installing OpenVSCode Server"
wget https://github.com/gitpod-io/openvscode-server/releases/download/openvscode-server-v${OPENVSCODE_SERVER_VERSION}/openvscode-server-v${OPENVSCODE_SERVER_VERSION}-${OPENVSCODE_SERVER_OS}-${OPENVSCODE_SERVER_ARCH}.tar.gz
tar -xzf openvscode-server-v${OPENVSCODE_SERVER_VERSION}-${OPENVSCODE_SERVER_OS}-${OPENVSCODE_SERVER_ARCH}.tar.gz
rm openvscode-server-v${OPENVSCODE_SERVER_VERSION}-${OPENVSCODE_SERVER_OS}-${OPENVSCODE_SERVER_ARCH}.tar.gz
echo "🚀 Start OpenVSCode Server"
cd openvscode-server-v${OPENVSCODE_SERVER_VERSION}-${OPENVSCODE_SERVER_OS}-${OPENVSCODE_SERVER_ARCH}
./bin/openvscode-server --port ${OPENVSCODE_SERVER_PORT} --host ${VM_IP} --without-connection-token &
echo "🌍 http://${VM_IP}:8080/?folder=/home/ubuntu/scripts"
echo "🌍 http://${VM_IP}:8080/?folder=/home/ubuntu/workspace"
EOF
echo "+-----------------------------------------------+"
echo "🖐️ update your /etc/hosts file with:"
cat config/vm.hosts.config
echo "+-----------------------------------------------+"
Then, execute ./create-vm.sh
in a terminal. Regarding the speed of your internet connection, you should get a running VM more or less quickly:
🚀 Start OpenVSCode Server
🌍 http://192.168.64.42:8080/?folder=/home/ubuntu/scripts
🌍 http://192.168.64.42:8080/?folder=/home/ubuntu/workspace
Server bound to 192.168.64.42:8080 (IPv4)
Extension host agent listening on 8080
Web UI available at http://localhost:8080/
[16:04:29] Extension host agent started.
[16:04:29] Started initializing default profile extensions in extensions installation folder. file:///home/ubuntu/.openvscode-server/extensions
[16:04:29] Completed initializing default profile extensions in extensions installation folder. file:///home/ubuntu/.openvscode-server/extensions
The script has generated a vm.hosts.config
file in the config
directory:
config
├── .env
└── vm.hosts.config
The content of vm.hosts.config
is like this: 192.168.64.42 my-little-ide.local
If you add this line to the
/etc/hosts
file, you can open the Web IDE with this URL http://my-little-ide.local:8080 instead of this one http://192.168.64.42:8080
Open the IDE
Open http://my-little-ide.local:8080 with our browser. You should get something like this:
Click on the document icon in the left menu bar:
Choose the "Open Folder" option. You see that you can select the /home/ubuntu location or the shared directories scripts
and workspace
:
Select scripts
:
Remarks
Usually, I put all my installation tools scripts in the scripts
directory and the source code of my projects in the workspace
directory. And in these directories, I add a .vscode
directory with some VSCode configuration files:
scripts
└── .vscode
├── extensions.json
└── settings.json
For example:
settings.json
{
"workbench.iconTheme": "material-icon-theme",
"workbench.colorTheme": "Solarized Dark",
"terminal.integrated.defaultProfile.linux": "bash",
"terminal.integrated.fontSize": 16,
"editor.fontSize": 16,
}
extensions.json
{
"recommendations": [
"pkief.material-icon-theme"
]
}
When the IDE prompt for installing extensions, click on the "Install" button:
Now, you can run your scripts to install what you want in your VM:
If you wish to access the workspace
directory, you simply need to use this URL: http://my-little-ide.local:8080/?folder=/home/ubuntu/workspace and check if your tools are correctly installed:
Some useful commands to handle the VM
Stop the VM
#!/bin/bash
set -o allexport; source config/.env; set +o allexport
multipass stop ${VM_NAME}
Start the VM
#!/bin/bash
set -o allexport; source config/.env; set +o allexport
multipass start ${VM_NAME}
VM_IP=$(multipass info ${VM_NAME} | grep IPv4 | awk '{print $2}')
multipass --verbose exec ${VM_NAME} -- bash <<EOF
cd openvscode-server-v${OPENVSCODE_SERVER_VERSION}-${OPENVSCODE_SERVER_OS}-${OPENVSCODE_SERVER_ARCH}
./bin/openvscode-server --port ${OPENVSCODE_SERVER_PORT} --host ${VM_IP} --without-connection-token &
EOF
Connect to the shell of the VM
#!/bin/bash
set -o allexport; source config/.env; set +o allexport
multipass shell ${VM_NAME}
Drop the VM
#!/bin/bash
set -o allexport; source config/.env; set +o allexport
multipass delete ${VM_NAME}
multipass purge
rm config/*.config
That's it for this tutorial.
You can find all the source code and scripts here https://github.com/bots-garden/spawn-ide