Skip to content

Build Your Own Remote Dev Environment Based on VSCode

Requirements:

Terminal window
git clone https://github.com/microsoft/vscode.git
cd vscode

Here, we will build based on a historical version v1.99.3.

Terminal window
git checkout -b my-vscode-1.99.3 1.99.3
Terminal window
sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev libkrb5-dev python-is-python3
Terminal window
cd vscode
npm install
npm run compile

Create a Dockerfile file in the project root directory, and create build.sh and entrypoint.sh files in the scripts directory.

  • Directoryvscode
    • Directoryscripts/
      • build.sh
      • entrypoint.sh
    • Dockerfile
scripts/build.sh
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "$0")/.." && pwd)
cd "$ROOT_DIR"
IMAGE_NAME="${IMAGE_NAME:-vscode-web}"
IMAGE_TAG="${IMAGE_TAG:-local}"
DOCKERFILE="${DOCKERFILE:-Dockerfile}"
WEB_DIST_DIR="${WEB_DIST_DIR:-vscode-reh-web-linux-x64}"
echo "[ENV] IMAGE_NAME=${IMAGE_NAME} IMAGE_TAG=${IMAGE_TAG} DOCKERFILE=${DOCKERFILE}"
echo "[ENV] WEB_DIST_DIR=${WEB_DIST_DIR}"
echo "[STEP] Build VS Code web dist -> ${WEB_DIST_DIR}"
rm -rf "${WEB_DIST_DIR}"
npm run gulp "${WEB_DIST_DIR}"
cp -r ../"${WEB_DIST_DIR}" ./
echo "[STEP] Docker build ${IMAGE_NAME}:${IMAGE_TAG}"
docker build \
--build-arg WEB_DIST_DIR="${WEB_DIST_DIR}" \
-t "${IMAGE_NAME}:${IMAGE_TAG}" \
-f "${DOCKERFILE}" \
"${ROOT_DIR}"
echo "[DONE] Built image: ${IMAGE_NAME}:${IMAGE_TAG}"
scripts/entrypoint.sh
#!/usr/bin/env bash
set -euo pipefail
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
APP_HOME="${APP_HOME:-/opt/vscode-web}"
HOST="0.0.0.0"
LISTEN_PORT="${IDE_PORT:-8080}"
CONNECTION_TOKEN="${CONNECTION_TOKEN:-rviFq8oBBOIp92fGXnSlWygbjNpGU2FelEeMVQp6CTRiuux0BxGKU01yCCmICBbY}"
ARGS=(
--host "${HOST}"
--port "${LISTEN_PORT}"
--connection-token "${CONNECTION_TOKEN}"
)
log "[INFO] Starting VS Code Web on ${HOST}:${LISTEN_PORT}?tkn=${CONNECTION_TOKEN}"
log "[INFO] APP_HOME=${APP_HOME}"
SERVER_BIN="${SERVER_BIN:-${APP_HOME}/bin/code-server-oss}"
exec "${SERVER_BIN}" "${ARGS[@]}" "$@"
Dockerfile
FROM ubuntu:24.04
ARG WEB_DIST_DIR=vscode-reh-web-linux-x64
ENV DEBIAN_FRONTEND=noninteractive \
APP_HOME=/opt/vscode-web \
IDE_PORT=8080 \
PNPM_STORE_DIR=/home/vscode/workspace/.pnpm-store
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
bash \
dumb-init \
git \
unzip \
zip \
wget \
net-tools \
lrzsz \
gnupg \
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& npm install -g pnpm@9 \
&& npm cache clean --force \
&& rm -rf /var/lib/apt/lists/*
RUN groupadd -r vscode && useradd -m -r -g vscode -s /bin/bash vscode
RUN mkdir -p "$APP_HOME" /home/vscode/workspace "$PNPM_STORE_DIR" \
&& chown -R vscode:vscode "$APP_HOME" /home/vscode
COPY ${WEB_DIST_DIR}/ "$APP_HOME"/
COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod 0755 /usr/local/bin/entrypoint.sh \
&& chown -R vscode:vscode "$APP_HOME"
USER vscode
RUN pnpm config set store-dir "$PNPM_STORE_DIR" --global \
&& git config --global user.name "vscode" \
&& git config --global user.email "[email protected]"
WORKDIR /home/vscode/workspace
EXPOSE 8080
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["/usr/local/bin/entrypoint.sh"]

Then start building the image.

Terminal window
cd vscode
bash scripts/build.sh

After the build is complete, you can use docker images to view the built image.

Register a Docker Hub account, and install Docker.

Terminal window
docker login
docker tag vscode-web:local {username}/vscode-web:latest
docker push {username}/vscode-web:latest

Register a Fly.io account, and install Fly.io CLI.

Terminal window
fly auth login

Configure the access_token in the ~/.fly/config.yml file to the FLY_API_TOKEN environment variable.

Terminal window
export FLY_API_TOKEN=$(cat ~/.fly/config.yml | grep access_token | awk -F ': ' '{print $2}')
Terminal window
fly apps create {username}-vscode-web-ide
Terminal window
fly volumes create vscode_workspace --size 3 --region sin --app {username}-vscode-web-ide

Create a fly.toml file in the project root directory.

fly.toml
app = '{username}-vscode-web-ide'
primary_region = 'sjc'
[build]
image = '{username}/vscode-web:latest'
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = 'suspend'
auto_start_machines = true
min_machines_running = 0
processes = ['app']
[[vm]]
memory = '4gb'
cpu_kind = 'shared'
cpus = 8
[[mounts]]
source = "vscode_workspace"
destination = "/home/vscode/workspace"

Then you can start deploying.

Terminal window
fly deploy

If everything is normal, then you can now access VSCode Web normally.

https://{username}-vscode-web-ide.fly.dev?tkn=rviFq8oBBOIp92fGXnSlWygbjNpGU2FelEeMVQp6CTRiuux0BxGKU01yCCmICBbY