Build Your Own GitHub Codespaces Alternative in 222 Lines of Pulumi

Build Your Own GitHub Codespaces Alternative in 222 Lines of Pulumi

tl;dr

In this article, we use Pulumi to spin up a cloud-based development environment that emulates GitHub Codespaces. We define the environment using the devcontainer.json spec and establish a secure tunnel to mount your local file system on a remote server.

This setup runs on Hetzner Cloud, starts in under 5 minutes, and costs less than one-sixth the price of GitHub Codespaces.

The full source of the project is in a GitHub Repository.

Introduction

Containers are a fantastic way to package and run your applications—and standardize them. Similarly, devcontainers provide a consistent environment for development across teams. GitHub Codespaces leverages the VSCode devcontainer specification to offer a ready-to-use cloud development environment.

However, what if you need to attach local resources, external infrastructure, or other cloud-based services to your development setup? This guide shows you how to achieve that using Pulumi to provision and manage your own cloud-based development environment.

Objective

Our objective is to create a single, reproducible definition for your development environment. We achieve this by:

  • Provisioning a Remote Server: Using Pulumi to create a development server (with flexibility to choose different cloud providers or even self-hosted hardware).
  • Defining the Environment: Using the devcontainer.json spec to standardize the development environment.
  • Attaching Local Resources: Optionally connecting your local file system via a secure tunnel to the remote server.

This complete setup should be ready in less than 5 minutes and easily reproducible for every developer on your team.

Why Is This Important?

Key Benefits

FeatureGitHub CodespacesOur Solution
Hardware/Provider ChoiceLimitedFull control
Monthly Cost (4vCPU)$ 51.12$ 8.23
Local FS IntegrationNoYes (via SSHfs)
Cloud Resource ColocationNoYes (via Pulumi)
Backup/Snapshot ControlManagedSelf-service

Reproducibility

Whether you’re working in a team or switching between machines as a solo developer, having a consistent environment eliminates the classic “works on my machine” problem.

Run on the Hardware You Want (GPU, ARM, etc.)

Modern applications often require specialized hardware—like GPUs or ARM processors. Unlike GitHub Codespaces, which offers fixed configurations, our approach lets you choose the exact hardware that meets your needs. Whether it’s via a specific cloud provider or your own infrastructure, you’re in control.

Co-locate with Your Cloud Resources

In complex projects, your development environment might need to interact with cloud resources such as databases, storage services, or APIs. With Pulumi, you can provision these resources alongside your development server for better integration and lower latency.

Attach Your Local Storage with Secure Tunnels

You might prefer to keep your code on your local machine while developing on a remote server. Our setup uses a secure tunnel to mount your local file system onto the remote server. (Be sure to follow security best practices when exposing local resources.)

Control the Environment Lifecycle and Backups

Running your own environment means you control its lifecycle. With Pulumi, you can automate tasks like creating backups, taking snapshots, or loading database fixtures—ensuring your environment always aligns with your project’s needs.

Cost Efficiency

GitHub Codespaces is a remarkable product, but its costs can add up quickly—especially for teams with heavy usage. Consider the following cost breakdown for running Codespaces on a 4 vCPU, 16 GB RAM machine for 40 hours per week:

PlanCost per HourHours per MonthFree HoursBillable HoursCost per Month
GitHub Standard$ 0.3617330142$ 51.12
GitHub Pro$ 0.3617345128$ 46.08

Now, compare that with alternative cloud providers:

ProviderInstance TypevCPUsRAMGPUGPU MemoryCost per HourCost per Month
HetznerCCX23416n/an/a$ 0.0475$ 8.23
RunPod.ioRTX 4000 Ada531RTX 4000 Ada20$ 0.20$ 34.64
DigitalOceanH10010240H10080$ 3.39$ 587.14

While GitHub Codespaces offers a seamless experience—especially with its tight GitHub integration—the flexibility to choose hardware and reduce costs makes a custom solution very appealing for many teams.

Example Setup / Demo

In this demo, we’ll use Pulumi to provision a development server on Hetzner Cloud. The Pulumi program will:

  • Create a Virtual Machine on Hetzner Cloud
  • Install Docker on the VM
  • Establish a Secure Tunnel to mount your local file system on the remote server
  • Launch the Development Environment using the devcontainer CLI with a remote Docker host
  • Open VSCode pointed at the remote server, with your local file system mounted

Prerequisites

Make sure you have the following installed:

Also, ensure you have a Hetzner Cloud account and an API key.

Configuring

  1. Clone the Repository

    git clone https://github.com/bascodes/pulumi-selfhosted-codespace.git
  2. Change into the directory

    cd pulumi-selfhosted-codespace
  3. Adjust your configuration in pulumi-program/Pulumi.yaml

    Open pulumi-program/Pulumi.yaml and update the settings to match your environment:

    config:
      userPublicKeyPath: "/home/your_username/.ssh/id_ed25519.pub" # Path to your public SSH key
      userPrivateKeyPath: "/home/your_username/.ssh/id_ed25519" # Path to your private SSH key
      workspaceExportDirectory: "/home/your_username/workspace" # Local directory for workspace export
      devcontainerConfigPath: "../.devcontainer/demo/devcontainer.json" # Path to your devcontainer configuration
      localDockerHost: "unix:///var/run/docker.sock" # Docker host for local Docker daemon
      sshdPort: 2222 # SSH port to be used on the VM
      userName: "your_username" # Username for the development environment
      userUid: 1000 # User ID (adjust if necessary)
      userGid: 1000 # Group ID (adjust if necessary)
      hcloudServerType: "cax11" # Hetzner server type
      hcloudServerLocation: "nbg1" # Hetzner server location
  4. Deploy the Infrastructure

    Run the following command to provision your environment:

    pulumi up

Within a few minutes, your new development environment will be live!

Conclusion and Next Steps

You’ve now built a cost-effective, reproducible cloud-based development environment using Pulumi and Hetzner Cloud. This setup gives you the flexibility to choose the hardware that best meets your needs, co-locate with other cloud resources, and even attach your local file system securely.

Next Steps

  • Explore Customization: Tweak the configuration to add features such as GPU support, additional storage, or integrations with other cloud services.
  • Enhance Security: Review best practices for securing tunnels and exposed endpoints.
  • Automate Maintenance: Use Pulumi to further automate lifecycle tasks like backups, snapshots, and updates.

By following this guide, you gain full control over your development environment—ensuring consistency, cost efficiency, and the flexibility to scale as your projects evolve.