Build Your Own Remote Dev Environment Based on VSCode
Requirements:
- System: Ubuntu 24.04
- Node.js: v22.21.1
- Docker
- Fly.io CLI
Build VSCode
Section titled “Build VSCode”Download VSCode Source Code
Section titled “Download VSCode Source Code”git clone https://github.com/microsoft/vscode.gitcd vscodeHere, we will build based on a historical version v1.99.3.
git checkout -b my-vscode-1.99.3 1.99.3Install Dependencies
Section titled “Install Dependencies”sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev libkrb5-dev python-is-python3Compile VSCode
Section titled “Compile VSCode”cd vscodenpm installnpm run compileBuild Docker Image
Section titled “Build Docker Image”Create Build Script
Section titled “Create Build Script”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
#!/usr/bin/env bashset -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}"#!/usr/bin/env bashset -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[@]}" "$@"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" \
WORKDIR /home/vscode/workspace
EXPOSE 8080
ENTRYPOINT ["/usr/bin/dumb-init", "--"]CMD ["/usr/local/bin/entrypoint.sh"]Then start building the image.
cd vscodebash scripts/build.shAfter the build is complete, you can use docker images to view the built image.
Push Image to Dockerhub
Section titled “Push Image to Dockerhub”Register a Docker Hub account, and install Docker.
docker logindocker tag vscode-web:local {username}/vscode-web:latestdocker push {username}/vscode-web:latestDeploy to Fly.io
Section titled “Deploy to Fly.io”Login Fly.io
Section titled “Login Fly.io”Register a Fly.io account, and install Fly.io CLI.
fly auth loginConfigure Token
Section titled “Configure Token”Configure the access_token in the ~/.fly/config.yml file to the FLY_API_TOKEN environment variable.
export FLY_API_TOKEN=$(cat ~/.fly/config.yml | grep access_token | awk -F ': ' '{print $2}')Create App
Section titled “Create App”fly apps create {username}-vscode-web-ideCreate Volume
Section titled “Create Volume”fly volumes create vscode_workspace --size 3 --region sin --app {username}-vscode-web-ideCreate fly.toml file
Section titled “Create fly.toml file”Create a fly.toml file in the project root directory.
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.
fly deployAccess VSCode Web
Section titled “Access VSCode Web”If everything is normal, then you can now access VSCode Web normally.
https://{username}-vscode-web-ide.fly.dev?tkn=rviFq8oBBOIp92fGXnSlWygbjNpGU2FelEeMVQp6CTRiuux0BxGKU01yCCmICBbY