Knowledge · Development environment

Building a Codex Cloud Development Environment After a WSL2 OOM

Setting up and checking seven GitHub repositories, Node.js, and the Android SDK

A real account of analyzing WSL2 memory failure, linking seven GitHub repositories to Codex Cloud, installing Android tools, adjusting startup instructions, and checking what Publish did and did not prove.

1. Understand what is being moved

Moving development to Codex Cloud is not the same as uploading an entire WSL2 Ubuntu disk. It means recreating a cloud execution environment from source code and project configuration stored on GitHub.

This is the environment I configured:

ComponentSetup used
Source controlSeven private GitHub repositories
Cloud developmentOne integrated Codex Cloud environment
Web toolsNode.js 24.21.0 and npm 11.19.0
Android JDKTemurin 17
Android SDKPlatform 36, Build Tools 36.0.0
Android buildExisting project Gradle settings
Web deploymentGitHub → Cloudflare Git integration
Automated checksSeparate GitHub Actions PR verification experiment

Having already configured a WSL environment helped because I knew which JDK, SDK, and Node.js versions my projects required. But it would also have been possible to set up Codex Cloud from scratch.

The motivation was a real out-of-memory incident in WSL2. This article focuses on the configuration steps and exactly what was verified afterward.

2. Check evidence of WSL2 out-of-memory errors

Do not assume every abrupt WSL shutdown was caused by memory pressure. Examine logs.

Check current memory and swap:

free -h
top

Search kernel logs for out-of-memory kills:

sudo dmesg -T | grep -Ei 'out of memory|oom|killed process'

If the journal from a previous boot was retained, this may help:

journalctl -k -b -1 --no-pager | grep -Ei 'out of memory|oom|killed process'

Depending on WSL configuration, previous-boot logs may not exist. An empty result does not prove there was no OOM event.

In this incident, I confirmed entries including oom-killer, Out of memory, zero available swap, Chrome being killed due to OOM, and subsequent forced process terminations. Memory exhaustion was confirmed, but the exact actor responsible for the eventual WSL restart was not established.

Before making any move, check for unnecessary duplicate servers, browsers, or build processes. Moving into the cloud should not simply reproduce excessive parallel resource usage.

3. Record enough environment information in GitHub

Cloning code alone does not guarantee that it builds in a new environment. The repository should make it possible to find:

  • Project rules and work boundaries in AGENTS.md and README files.
  • The Node.js version, such as .nvmrc, and dependency lockfiles.
  • The Gradle Wrapper and Android JDK/SDK requirements.
  • Real build and test commands and expected output locations.
  • Which files are tracked versus generated, including .gitignore rules.

Do not commit passwords, API tokens, SMS plaintext, or Android Release signing keys to a repository or its setup scripts.

For WSL2 installation and initial GitHub setup, see the earlier guide. This article focuses on what came next: a separate cloud execution environment.

Related readingSet Up a Vibe-Coding Development Environment with WSL2, GitHub, and Cloudflare

A step-by-step guide to developing in WSL2 Ubuntu on Windows, managing code with Git and GitHub, and deploying a web service through Cloudflare's Git integration.

I connected GitHub repositories from the Codex Cloud environment setup interface.

The seven projects were BLOG, HOME, INVEST, TOOL, CART, FLOW, and ONSEMO Connect. Connect's GitHub repository is identified as onsemo/sms-forwarder, but I use its current product name, Connect, in this article.

Connecting several repositories to one environment does not merge them into a single Git repository. Each task should name the target repository explicitly and read that repository's AGENTS.md first.

At the setup stage, I restricted the work to reading, installing, building, and running local checks. I did not authorize changes to tracked files, commits, pushes, or direct Cloudflare deployment.

Internet access was restricted primarily to the package-manager hosts needed. I confirmed HTTP 200 from the official Node.js distribution host, nodejs.org, and did not need to permit additional domains in that environment.

Other environments can have different domain allowlists. When a download fails, examine proxy, network, and authentication constraints before changing credentials or creating new keys.

5. Set up Node.js and verify the BLOG build

To match BLOG's .nvmrc, I used Node.js 24.21.0.

node --version
npm --version

The setup compared the SHA-256 hash of official Node.js downloads with the published checksum. Npm-based projects including the Connect web/PWA code installed dependencies from their existing lockfiles.

BLOG has a real npm run build command:

npm run build

In some repositories, the build rewrites tracked HTML files, indices, or sitemaps. I therefore ran the initial validation in temporary copies rather than changing the checked-out original repositories.

Representative BLOG output checks are:

test -s public/index.html
test -s public/ko/index.html
test -s public/ko/knowledge/index.html
test -s public/content-index.json

Those paths reflect this BLOG build. Check the actual output structure in other projects.

6. Prepare Android development tools for Connect

Connect includes an Android app alongside the web/PWA and Cloudflare Worker components. Android unit tests and Debug builds need extra tools in the cloud environment.

ToolVersion or method used
JDKTemurin 17
Android command-line toolsOfficial distribution
SDK PlatformAPI 36
Build Tools36.0.0
GradleExisting project settings and cache

Integrity checks were included in the installer. JDK downloads were compared against checksum files, and Android command-line tools were checked using the SHA-1 listed in the official repository metadata. If you select other versions, confirm official checksums and the project requirements again.

Android verification used the project's existing test and Debug-build process, rather than inventing commands for a new project.

The cloud validation covered Android compilation, unit tests, and producing a Debug APK. It did not cover:

  • SMS reception and permission behavior on a physical Galaxy phone.
  • Actual message transfer between phones or devices.
  • Web Push arriving on a real device.
  • Creating a Release APK signed with the existing key or verifying update compatibility.

The Debug APK is a development artifact, not an installation file for users. I did not replace the official Release distribution with a separate Debug download, and did not upload the existing Release signing key to the cloud environment.

7. Separate installation scripts from startup instructions

An initial setup tool offered to start the servers for all seven repositories together. But everyday development rarely needs every server to be running.

I changed the instructions to start only the project needed for the current task. The start.py utility for launching all seven was removed from the default workflow.

The roles became:

StageResponsibility
Installation scriptPrepare JDK, SDK, Node.js, and dependencies
Startup instructionsSelect repositories and start only relevant servers
Build verificationRun explicitly for the target project
GitHub ActionsSeparately automate PR builds and tests

I checked that the installation script did not issue direct commands such as wrangler deploy. Reports for five auxiliary files found no direct deployment commands or operations that printed secrets.

Starting fewer servers is not universally better. When integrated testing needs several services, those services can be started deliberately.

8. What was actually verified before and after Publish?

The initial cloud environment setup reported:

ProjectAutomated checks
CART22 tests passed
Connect web/PWA42 passed
Connect Worker32 passed
Connect Android190 passed
Android Debug APKBuilt successfully

The total was 286 passing automated tests, according to the setup report. The report also indicated successful builds and local HTTP response checks across the seven repositories.

I reviewed the installation and startup scripts, then published the environment.

In a later task connected to the existing cloud environment, BLOG was built again. Node.js 24.21.0, npm 11.19.0, support files, and caches were present. The build succeeded without reinstalling those tools and generated 21 blog posts.

The reported times were 0.22 seconds for environment preparation and 0.30 seconds for the build. Those were timings within an existing environment, not the complete boot or recovery time of a fresh cloud computer.

I have not separately verified whether a completely new instance recreates and reuses the same setup. Fast subsequent builds should not be described as proof of fresh-environment restoration.

9. Distinct roles for Codex Cloud, GitHub Actions, and Cloudflare

Codex Cloud handles development and complex investigation. GitHub Actions independently repeats explicit build and test checks.

In BLOG, I tested a GitHub Actions workflow that builds on a PR and checks output files using npm run build. That particular experiment succeeded, but I did not verify equivalent checks across every project.

Cloudflare continues to use Git-based deployment. I did not switch to updating production directly with wrangler deploy from the cloud development environment.

The main idea is to avoid depending on a single tool to perform everything.

10. Reproduction checks for the next session

To verify that the configuration is reproducible:

  1. Start a new Codex Cloud instance distinct from the previous conversation.
  2. Check that published settings and support scripts are present.
  3. In one necessary project, inspect tool versions and dependencies.
  4. Run the project's build and minimum tests.
  5. Use git status --short to check for unintended changes to tracked files.

Until that test is complete, do not describe a fast build within an existing environment as the time required to restore a completely fresh cloud setup.

Conclusion

Previous experience with WSL2 Ubuntu made configuring Codex Cloud easier, but WSL itself is not a prerequisite for using cloud development.

For primarily web/PWA projects, starting in the cloud may be sufficient. Projects needing physical Android device checks and existing Release signatures may reasonably retain a local environment as well.

What matters most is designing a workflow that can continue from recorded configuration and repeatable verification, even after one computer stops.

The later arrangement that divided responsibilities between Codex Cloud, WSL2, and GitHub Actions is described in a separate Story.

Related readingFrom One PC to a Redundant Cloud Development Workflow

ONSEMO's move from WSL2 to Codex Cloud and GitHub Actions, its resulting architecture, free-tier limits, infrastructure cost assumptions, and possible future technologies.

Development environmentTroubleshootingWSL2OOMCodex CloudGitHubAndroid SDKGradleNode.jsGitHub Actions
Connected projectsBLOGConnect / SMS Push
Practical KnowledgeVerified follow-up guides will be linked when published.