<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Spectra</title>
    <description>The latest articles on DEV Community by Spectra (@spectra010s).</description>
    <link>https://dev.to/spectra010s</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3530999%2Fb03b55e5-cb51-4236-a6cf-745ad833cf91.jpeg</url>
      <title>DEV Community: Spectra</title>
      <link>https://dev.to/spectra010s</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spectra010s"/>
    <language>en</language>
    <item>
      <title>A Day in My Setup: Building Full-Stack Apps on a Phone with Docker, Redis, and Codespaces</title>
      <dc:creator>Spectra</dc:creator>
      <pubDate>Wed, 09 Sep 2026 15:18:17 +0000</pubDate>
      <link>https://dev.to/spectra010s/a-day-in-my-setup-building-full-stack-apps-on-a-phone-with-docker-redis-and-codespaces-1k1m</link>
      <guid>https://dev.to/spectra010s/a-day-in-my-setup-building-full-stack-apps-on-a-phone-with-docker-redis-and-codespaces-1k1m</guid>
      <description>&lt;p&gt;&lt;em&gt;How I run and test a full-stack automation system with headless Chromium, message queues, and databases—entirely from a phone-based development workflow.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Working Within the Constraints
&lt;/h2&gt;

&lt;p&gt;When people think of software engineering, they often picture dual 4K monitors, mechanical keyboards, and powerful workstations. But with cloud development environments and the right tooling, the workstation doesn't always have to be where the heavy work happens.&lt;/p&gt;

&lt;p&gt;Today, I was contributing to &lt;strong&gt;Replex&lt;/strong&gt;—an open-source video automation tool that uses &lt;strong&gt;Playwright&lt;/strong&gt;, &lt;strong&gt;BullMQ&lt;/strong&gt;, &lt;strong&gt;Redis&lt;/strong&gt;, &lt;strong&gt;MongoDB&lt;/strong&gt;, &lt;strong&gt;Express&lt;/strong&gt;, and &lt;strong&gt;Next.js&lt;/strong&gt; to autonomously browse websites and record demo reels across different viewports.&lt;/p&gt;

&lt;p&gt;Here's a look at my development setup, how I optimize my cloud resources, and how I run the different services from a phone.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture at a Glance
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ My Phone / Local Environment ]
  ├── Local Git Repo (Editing &amp;amp; quick checks without burning Codespace quota)
  └── Mobile Browser (http://localhost:3000)
            │
            ▼  (gh cs ports forward 3000:3000 5000:5000)
[ GitHub Codespaces Cloud Container ]
  ├── 🐳 Docker (Redis:6379 &amp;amp; MongoDB:27017)
  ├── 🖥️ screen: Next.js Frontend (:3000)
  ├── 🖥️ screen: Express API Server (:5000)
  ├── 🖥️ screen: BullMQ Worker + Headless Chromium
  └── ☁️ Cloudinary Video Pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Workflow: Step by Step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Conserving Cloud Quota (Local-First Editing)
&lt;/h3&gt;

&lt;p&gt;GitHub Codespaces gives me a monthly pool of compute time. To make the most of it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I write code and perform initial lint and syntax checks locally on my device.&lt;/li&gt;
&lt;li&gt;Commit and push the branch to GitHub.&lt;/li&gt;
&lt;li&gt;SSH into my Codespaces environment and pull the latest changes.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pull the latest changes into the Codespace&lt;/span&gt;
git pull origin improve-mobile-recording
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes I code directly inside Codespaces, but when I don't need the cloud environment yet, doing the lightweight work locally saves those minutes for when I actually need them.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Spinning Up Data Stores with Docker
&lt;/h3&gt;

&lt;p&gt;For Redis and MongoDB, Docker saves me from installing and configuring each service directly in the Codespace.&lt;/p&gt;

&lt;p&gt;Instead of setting up each database separately and managing additional services, I can spin both of them up in a couple of commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Start Redis in the background for BullMQ task queues&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; redis-local &lt;span class="nt"&gt;-p&lt;/span&gt; 6379:6379 redis:alpine

&lt;span class="c"&gt;# 2. Start MongoDB in the background for persistent video history&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; mongo-local &lt;span class="nt"&gt;-p&lt;/span&gt; 27017:27017 mongo:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Both services are running and ready for the application to connect to them.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Setting Up Headless Automation
&lt;/h3&gt;

&lt;p&gt;The worker needs a Chromium browser environment to automate and record web interactions, so I install the required dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;backend &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install
&lt;/span&gt;npx playwright &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--with-deps&lt;/span&gt; chromium

&lt;span class="nb"&gt;cd&lt;/span&gt; ../frontend &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. Running Services with GNU &lt;code&gt;screen&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The frontend, API, and worker all need to run simultaneously. Rather than keeping multiple terminal sessions open, I use GNU &lt;code&gt;screen&lt;/code&gt; to run them as detached sessions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Session 1: Next.js Frontend&lt;/span&gt;
screen &lt;span class="nt"&gt;-dmS&lt;/span&gt; frontend bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd frontend &amp;amp;&amp;amp; npm run dev"&lt;/span&gt;

&lt;span class="c"&gt;# Session 2: Express Backend Server&lt;/span&gt;
screen &lt;span class="nt"&gt;-dmS&lt;/span&gt; backend-server bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd backend &amp;amp;&amp;amp; npm run dev"&lt;/span&gt;

&lt;span class="c"&gt;# Session 3: BullMQ Playwright Worker&lt;/span&gt;
screen &lt;span class="nt"&gt;-dmS&lt;/span&gt; backend-worker bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd backend &amp;amp;&amp;amp; npm run worker"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can inspect the worker logs whenever I need to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;screen &lt;span class="nt"&gt;-r&lt;/span&gt; backend-worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And detach again with &lt;code&gt;Ctrl+A&lt;/code&gt;, then &lt;code&gt;D&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This lets all the services continue running while I use another terminal session for the next part of the setup.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. The Magic Link: Port Forwarding
&lt;/h3&gt;

&lt;p&gt;At this point, the application is running inside Codespaces. I still need to interact with it from my phone's browser.&lt;/p&gt;

&lt;p&gt;That's where GitHub CLI port forwarding comes in.&lt;/p&gt;

&lt;p&gt;I initially forgot to forward the backend's port too, assuming the frontend could reach it directly in Codespaces. The API calls wouldn't resolve from my phone, so I added &lt;code&gt;5000:5000&lt;/code&gt; to the forward command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh cs ports forward 3000:3000 5000:5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Forwarding:
  • Local port 3000  ──▶  Codespaces Next.js UI (:3000)
  • Local port 5000  ──▶  Codespaces Express API (:5000)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can open &lt;code&gt;http://localhost:3000&lt;/code&gt; in my phone's browser and interact with the application running in the Codespace.&lt;/p&gt;

&lt;p&gt;The frontend can then dispatch background jobs to the API, which communicates with Redis and the worker running Playwright and Chromium.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Verification &amp;amp; End-to-End Testing
&lt;/h3&gt;

&lt;p&gt;Once everything is running, I verify that the pieces are actually communicating.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test API connectivity through the tunnel&lt;/span&gt;
curl http://localhost:5000/api/history

&lt;span class="c"&gt;# Output: [] (Healthy 200 response!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I can trigger an actual recording job and inspect the worker's output from its detached &lt;code&gt;screen&lt;/code&gt; session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;screen &lt;span class="nt"&gt;-r&lt;/span&gt; backend-worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker then processes the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Job 1] Started for URL: https://example.com on mobile
[Recorder] Warming up cache...
[Recorder] Found menu button via: button[aria-label*="menu" i]. Clicking...
[Recorder] Clicking visible menu link (Pricing)...
[Job 1] Streaming video upload to Cloudinary...
[Job 1] Saved to MongoDB!
[Job 1] Completed successfully!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At that point, the entire chain—from the frontend on my phone to the backend, queue, worker, browser automation, video pipeline, and database—is working together.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Setup Shows
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Optimization:&lt;/strong&gt; I don't have to run the application's resource-intensive environment on my phone. Codespaces handles the databases, worker, Chromium, and application servers, while my phone is mainly used for editing, terminal access, and interacting with the running application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Less Environment Management:&lt;/strong&gt; Without Docker and &lt;code&gt;screen&lt;/code&gt;, I'd have to install and manage each service individually and keep separate terminal sessions open for the frontend, backend, worker, Redis, and MongoDB. Docker handles the data stores, while &lt;code&gt;screen&lt;/code&gt; keeps the application processes running independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Constraint Changes the Workflow, Not Necessarily the Work:&lt;/strong&gt; A phone obviously isn't as comfortable as a full workstation, but with the right tooling, it doesn't prevent me from working on a multi-service application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The setup isn't conventional, but it works, and this is what a few hours of software engineering looked like for me today.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>devops</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
