<?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: GSVPS</title>
    <description>The latest articles on DEV Community by GSVPS (@huo_huo_ba0fc42b443732322).</description>
    <link>https://dev.to/huo_huo_ba0fc42b443732322</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%2F2950670%2F47498544-29a0-430b-862e-89ff9e9179c9.png</url>
      <title>DEV Community: GSVPS</title>
      <link>https://dev.to/huo_huo_ba0fc42b443732322</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/huo_huo_ba0fc42b443732322"/>
    <language>en</language>
    <item>
      <title>How to Build a Self-Hosted Remote Desktop with Cloudflare Workers and WebRTC</title>
      <dc:creator>GSVPS</dc:creator>
      <pubDate>Sun, 05 Jul 2026 02:15:33 +0000</pubDate>
      <link>https://dev.to/huo_huo_ba0fc42b443732322/how-to-build-a-self-hosted-remote-desktop-with-cloudflare-workers-and-webrtc-b12</link>
      <guid>https://dev.to/huo_huo_ba0fc42b443732322/how-to-build-a-self-hosted-remote-desktop-with-cloudflare-workers-and-webrtc-b12</guid>
      <description>&lt;p&gt;If you want a self-hosted remote desktop without paying for a relay server, a Cloudflare-based setup is one practical option to evaluate.&lt;/p&gt;

&lt;p&gt;A recent GSVPS tutorial walks through deploying GsDesk, an open-source remote desktop project that can run on Cloudflare Workers or on a VPS. The Cloudflare version uses Workers for the API layer, authentication, and signaling, while the desktop stream itself is designed to go peer to peer over WebRTC instead of being relayed through the server.&lt;/p&gt;

&lt;p&gt;That separation is the main idea worth paying attention to. It reduces bandwidth pressure on the backend, but it also means you still need to think about client compatibility, NAT traversal, and what happens when direct peer connectivity is limited.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this deployment includes
&lt;/h2&gt;

&lt;p&gt;According to the original tutorial, the Cloudflare deployment uses these building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare Workers for the application entry point and request handling&lt;/li&gt;
&lt;li&gt;D1 for relational data&lt;/li&gt;
&lt;li&gt;KV for lightweight key-value data&lt;/li&gt;
&lt;li&gt;R2 for object storage&lt;/li&gt;
&lt;li&gt;Durable Objects for coordination and signaling state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The article also describes a browser control path and a Windows client, with the server handling API requests, authentication, and WebSocket signaling rather than forwarding the actual remote desktop video stream.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you deploy
&lt;/h2&gt;

&lt;p&gt;The original guide is most useful if you already have these prerequisites in place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Cloudflare account with access to Workers and the related storage products&lt;/li&gt;
&lt;li&gt;A domain or worker route you can publish to&lt;/li&gt;
&lt;li&gt;Node.js and the Cloudflare tooling needed to build and deploy the project&lt;/li&gt;
&lt;li&gt;A clear plan for your controller token, JWT secret, and any other deployment secrets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are testing this architecture for the first time, it is worth treating the deployment as a lab environment first. Verify the control plane, then validate remote access behavior from the networks and devices you actually care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to verify after deployment
&lt;/h2&gt;

&lt;p&gt;The most practical part of the source tutorial is the verification checklist. After deployment, check at least three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The root URL responds successfully, so you know the worker is reachable.&lt;/li&gt;
&lt;li&gt;The web control path loads correctly, so static assets and route configuration are in sync.&lt;/li&gt;
&lt;li&gt;The client can connect with the expected API address and token, so the control plane is working end to end.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the web control path has been changed from its default value, rebuild the web assets before redeploying. Otherwise, mismatched paths can lead to missing static files or broken routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this architecture fits well
&lt;/h2&gt;

&lt;p&gt;This kind of design can make sense when you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A low-cost control plane for a personal or small-team remote access setup&lt;/li&gt;
&lt;li&gt;Browser-based control alongside a desktop client&lt;/li&gt;
&lt;li&gt;A self-hosted option that does not require a traditional always-on relay server for screen transport&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is less of a drop-in choice if you need guaranteed connectivity in heavily restricted network environments, because peer-to-peer designs still depend on the surrounding network conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloudflare Workers vs. VPS self-hosting
&lt;/h2&gt;

&lt;p&gt;The source material notes that GsDesk also supports VPS self-hosting. In practice, the choice is mostly about operational tradeoffs.&lt;/p&gt;

&lt;p&gt;Use the Cloudflare route if you want a managed edge control plane and are comfortable with the Cloudflare product stack.&lt;/p&gt;

&lt;p&gt;Use the VPS route if you want more conventional server control, easier low-level customization, or a setup that is less tied to one platform's services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final note
&lt;/h2&gt;

&lt;p&gt;If you want the full deployment walkthrough, including the original build and deployment flow, read the source article from GSVPS here:&lt;br&gt;
&lt;a href="https://www.gsvps.com/articles/news-20" rel="noopener noreferrer"&gt;https://www.gsvps.com/articles/news-20&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Original source: GSVPS. This adaptation keeps the original relationship visible and does not claim hands-on test results beyond what the source describes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Migrate a Linux VPS with rsync and Keep Downtime Low</title>
      <dc:creator>GSVPS</dc:creator>
      <pubDate>Fri, 03 Jul 2026 04:49:46 +0000</pubDate>
      <link>https://dev.to/huo_huo_ba0fc42b443732322/how-to-migrate-a-linux-vps-with-rsync-and-keep-downtime-low-1aaa</link>
      <guid>https://dev.to/huo_huo_ba0fc42b443732322/how-to-migrate-a-linux-vps-with-rsync-and-keep-downtime-low-1aaa</guid>
      <description>&lt;p&gt;Moving a Linux VPS to a new server is usually less about one command and more about sequencing. If you copy files too early, your data goes stale. If you switch DNS too soon, users land on an incomplete system. If you try to clone everything at once, you can easily bring across temporary paths and host-specific settings that do not belong on the new machine.&lt;/p&gt;

&lt;p&gt;This article is adapted from a GSVPS tutorial on Linux VPS migration. Original source:&lt;br&gt;
&lt;a href="https://www.gsvps.com/articles/linux-vps-ru-he-qian-yi-dao-xin-fu-wu-qi-2026-zui-xin-rsync-jiao-cheng-ji-hu-1-1-wu-sun-qian-yi-wang-zhan-docker-he-shu-ju" rel="noopener noreferrer"&gt;https://www.gsvps.com/articles/linux-vps-ru-he-qian-yi-dao-xin-fu-wu-qi-2026-zui-xin-rsync-jiao-cheng-ji-hu-1-1-wu-sun-qian-yi-wang-zhan-docker-he-shu-ju&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The practical goal is not "zero risk." It is a controlled migration with a short write-free window and a clear rollback path.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Start with an inventory, not with &lt;code&gt;rsync&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Before copying anything, write down what actually lives on the old server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web roots such as &lt;code&gt;/var/www&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Nginx or Apache config&lt;/li&gt;
&lt;li&gt;application env files and secrets&lt;/li&gt;
&lt;li&gt;database engines and database names&lt;/li&gt;
&lt;li&gt;Docker Compose files, bind mounts, and named volumes&lt;/li&gt;
&lt;li&gt;cron jobs&lt;/li&gt;
&lt;li&gt;SSL certificate paths&lt;/li&gt;
&lt;li&gt;firewall rules and open ports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also note what should &lt;em&gt;not&lt;/em&gt; be copied blindly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/proc&lt;/code&gt;, &lt;code&gt;/sys&lt;/code&gt;, &lt;code&gt;/dev&lt;/code&gt;, &lt;code&gt;/run&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;temporary files&lt;/li&gt;
&lt;li&gt;mounted backup disks&lt;/li&gt;
&lt;li&gt;bootloader state&lt;/li&gt;
&lt;li&gt;network interface settings tied to the old host&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That distinction matters. A migration usually fails because someone copied "everything" without deciding what "everything" meant.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Prepare the new server first
&lt;/h2&gt;

&lt;p&gt;The destination host should be reachable and basically ready before any final sync:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create the admin user you will keep using&lt;/li&gt;
&lt;li&gt;add SSH keys&lt;/li&gt;
&lt;li&gt;install the packages your stack needs&lt;/li&gt;
&lt;li&gt;confirm time, hostname, and firewall rules&lt;/li&gt;
&lt;li&gt;make sure the target disks are mounted where you expect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful early checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hostnamectl
ip addr
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;
lsblk
systemctl &lt;span class="nt"&gt;--failed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the new server cannot pass basic health checks, do not start the migration yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Lower DNS TTL before the cutover
&lt;/h2&gt;

&lt;p&gt;If a site or API is moving, lower DNS TTL well before the migration window. That gives you a faster switchover later and reduces the period where some users still hit the old host.&lt;/p&gt;

&lt;p&gt;This does not eliminate downtime by itself. It only shortens propagation pain when the final change happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Use &lt;code&gt;rsync&lt;/code&gt; for repeatable file transfer
&lt;/h2&gt;

&lt;p&gt;For website files, application directories, and many bind-mounted workloads, &lt;code&gt;rsync&lt;/code&gt; is still one of the most useful tools because you can run it more than once.&lt;/p&gt;

&lt;p&gt;A common pattern is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;run an initial sync while services are still live&lt;/li&gt;
&lt;li&gt;validate the new server&lt;/li&gt;
&lt;li&gt;stop write-heavy services briefly&lt;/li&gt;
&lt;li&gt;run one final sync&lt;/li&gt;
&lt;li&gt;switch traffic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example for a web root:&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;sudo &lt;/span&gt;rsync &lt;span class="nt"&gt;-aHAXx&lt;/span&gt; &lt;span class="nt"&gt;--numeric-ids&lt;/span&gt; &lt;span class="nt"&gt;--delete&lt;/span&gt; &lt;span class="nt"&gt;--info&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress2 &lt;span class="se"&gt;\&lt;/span&gt;
  /var/www/ user@NEW_SERVER:/var/www/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flags here matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; preserves recursion, permissions, timestamps, and symlinks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-HAX&lt;/code&gt; helps preserve hard links, ACLs, and xattrs where relevant&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-x&lt;/code&gt; keeps the copy on one filesystem&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--numeric-ids&lt;/code&gt; avoids UID or GID name mismatches&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--delete&lt;/code&gt; keeps the destination aligned with the source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not use &lt;code&gt;--delete&lt;/code&gt; casually against the wrong path. Verify both source and destination before pressing Enter.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Treat databases separately from static files
&lt;/h2&gt;

&lt;p&gt;If the application writes to MySQL, MariaDB, or PostgreSQL, file sync alone is not enough.&lt;/p&gt;

&lt;p&gt;Typical export commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;--single-transaction&lt;/span&gt; &lt;span class="nt"&gt;--routines&lt;/span&gt; &lt;span class="nt"&gt;--triggers&lt;/span&gt; DB_NAME &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.sql
pg_dump &lt;span class="nt"&gt;-Fc&lt;/span&gt; DB_NAME &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; db.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those should be imported on the new server after the database service is prepared.&lt;/p&gt;

&lt;p&gt;For busy applications, the cleanest cutover is usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enable maintenance mode or temporarily stop writes&lt;/li&gt;
&lt;li&gt;take the final dump or replication-consistent copy&lt;/li&gt;
&lt;li&gt;import on the new host&lt;/li&gt;
&lt;li&gt;run the final file sync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That write-free window is where you win or lose data consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. For Docker, migrate config and data intentionally
&lt;/h2&gt;

&lt;p&gt;If the workload runs under Docker Compose, copy the Compose files, env files, and persistent data paths deliberately rather than assuming the container image is the hard part.&lt;/p&gt;

&lt;p&gt;A simple sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose config
docker compose down
&lt;span class="nb"&gt;sudo &lt;/span&gt;rsync &lt;span class="nt"&gt;-aHAX&lt;/span&gt; &lt;span class="nt"&gt;--delete&lt;/span&gt; /srv/app/ user@NEW_SERVER:/srv/app/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then on the new server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose pull
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
docker compose ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use named volumes instead of bind mounts, inspect where the actual persistent data lives before moving anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Validate before DNS cutover
&lt;/h2&gt;

&lt;p&gt;Before sending production traffic to the new host, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the web server starts cleanly&lt;/li&gt;
&lt;li&gt;the application can connect to its database&lt;/li&gt;
&lt;li&gt;file permissions are correct&lt;/li&gt;
&lt;li&gt;scheduled jobs exist where needed&lt;/li&gt;
&lt;li&gt;TLS certificates are present or can be reissued&lt;/li&gt;
&lt;li&gt;uploads, login flows, and API writes still work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful checks include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
systemctl status nginx
docker compose logs &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100
ss &lt;span class="nt"&gt;-tlnp&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the service stack is not healthy locally, changing DNS only hides the real problem behind a network symptom.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Keep rollback simple
&lt;/h2&gt;

&lt;p&gt;Do not tear down the old server immediately after cutover.&lt;/p&gt;

&lt;p&gt;Keep it available long enough to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;compare logs&lt;/li&gt;
&lt;li&gt;recover missed files&lt;/li&gt;
&lt;li&gt;re-check database state&lt;/li&gt;
&lt;li&gt;reverse DNS if a critical issue appears&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A migration plan is better when rollback is boring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;The original GSVPS article focuses on using &lt;code&gt;rsync&lt;/code&gt; to move a Linux VPS with minimal disruption. That is a sensible base, but the real success condition is broader: prepare the target host, separate static files from live data, run repeatable syncs, and keep the final write window short and explicit.&lt;/p&gt;

&lt;p&gt;If you treat migration as a sequence instead of a copy job, &lt;code&gt;rsync&lt;/code&gt; becomes a reliable part of the process rather than a gamble.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>selfhosted</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>VPS Hosting Performance Comparison: Key Metrics for 2026</title>
      <dc:creator>GSVPS</dc:creator>
      <pubDate>Thu, 02 Jul 2026 20:17:11 +0000</pubDate>
      <link>https://dev.to/huo_huo_ba0fc42b443732322/vps-hosting-performance-comparison-key-metrics-for-2026-51pd</link>
      <guid>https://dev.to/huo_huo_ba0fc42b443732322/vps-hosting-performance-comparison-key-metrics-for-2026-51pd</guid>
      <description>&lt;p&gt;Choosing a VPS provider is one of the most critical decisions for developers and system administrators. Here's what I've learned from benchmarking various providers:&lt;/p&gt;

&lt;h2&gt;
  
  
  CPU Performance Matters
&lt;/h2&gt;

&lt;p&gt;Single-core performance can vary significantly. Look for modern AMD EPYC or Intel Xeon processors with high clock speeds rather than just core count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage: NVMe vs SSD
&lt;/h2&gt;

&lt;p&gt;NVMe storage offers 3-5x faster read/write speeds compared to traditional SSD. If your application is I/O intensive, this is non-negotiable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network Throughput
&lt;/h2&gt;

&lt;p&gt;Test with iperf3 before committing. Some providers advertise 1Gbps but deliver far less during peak hours. Check real user reviews and independent benchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Price-to-Performance Ratio
&lt;/h2&gt;

&lt;p&gt;After extensive testing, I found that providers like GSVPS (&lt;a href="http://www.gsvps.com" rel="noopener noreferrer"&gt;www.gsvps.com&lt;/a&gt;) offer excellent value with NVMe storage and generous bandwidth at competitive rates. They're worth checking out if you're shopping around.&lt;/p&gt;

&lt;h2&gt;
  
  
  Essential Benchmarks to Run
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;UnixBench for overall system performance&lt;/li&gt;
&lt;li&gt;fio for disk I/O&lt;/li&gt;
&lt;li&gt;iperf3 for network throughput&lt;/li&gt;
&lt;li&gt;yabs.sh for a quick all-in-one test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always test before you commit to a long-term plan. The hosting market in 2026 is competitive, which means better options for informed buyers.&lt;/p&gt;

</description>
      <category>vps</category>
      <category>hosting</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
    <item>
      <title>A Practical Linux Operations Roadmap for 2026</title>
      <dc:creator>GSVPS</dc:creator>
      <pubDate>Thu, 02 Jul 2026 02:25:50 +0000</pubDate>
      <link>https://dev.to/huo_huo_ba0fc42b443732322/a-practical-linux-operations-roadmap-for-2026-2145</link>
      <guid>https://dev.to/huo_huo_ba0fc42b443732322/a-practical-linux-operations-roadmap-for-2026-2145</guid>
      <description>&lt;p&gt;Linux operations is a wide field, and most beginners get stuck for the same reason: they try to learn everything at once. A more useful approach is to build a sequence. Start with system basics, add one service stack, then add automation, security, and monitoring.&lt;/p&gt;

&lt;p&gt;This post is adapted from a GSVPS tutorial on Linux operations. The original article is here:&lt;br&gt;
&lt;a href="https://www.gsvps.com/articles/linux-yun-wei-ru-men-jiao-cheng-2026-cong-xi-tong-guan-li-docker-nginx-dao-ansible-quan-mian-xue-xi-zhi-nan" rel="noopener noreferrer"&gt;https://www.gsvps.com/articles/linux-yun-wei-ru-men-jiao-cheng-2026-cong-xi-tong-guan-li-docker-nginx-dao-ansible-quan-mian-xue-xi-zhi-nan&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are just getting started with Linux server work, this is the order that makes the rest of the stack easier to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start with core system habits
&lt;/h2&gt;

&lt;p&gt;Before touching Docker, Nginx, or Ansible, get comfortable with a few system-level tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;navigating the filesystem&lt;/li&gt;
&lt;li&gt;reading logs&lt;/li&gt;
&lt;li&gt;managing users and groups&lt;/li&gt;
&lt;li&gt;checking disk, memory, and network state&lt;/li&gt;
&lt;li&gt;editing configuration files safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is not to memorize commands. The point is to recognize where to look when something breaks.&lt;/p&gt;

&lt;p&gt;Examples worth practicing early:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;mv&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ip addr&lt;/code&gt;, &lt;code&gt;ip route&lt;/code&gt;, &lt;code&gt;ss -tlnp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;df -h&lt;/code&gt;, &lt;code&gt;free -h&lt;/code&gt;, &lt;code&gt;lsblk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;systemctl status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;journalctl -u &amp;lt;service&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can answer "what changed?", "what is listening?", and "what is failing?" on a Linux host, you already have useful operational skill.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Learn one web stack end to end
&lt;/h2&gt;

&lt;p&gt;A beginner does not need five deployment patterns. One is enough at first.&lt;/p&gt;

&lt;p&gt;The classic entry point is a small LNMP-style stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;Nginx&lt;/li&gt;
&lt;li&gt;MySQL or PostgreSQL&lt;/li&gt;
&lt;li&gt;PHP or another app runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The value of this exercise is not the exact stack choice. It is the experience of wiring services together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install packages&lt;/li&gt;
&lt;li&gt;enable services at boot&lt;/li&gt;
&lt;li&gt;check listening ports&lt;/li&gt;
&lt;li&gt;inspect logs after config changes&lt;/li&gt;
&lt;li&gt;test locally before exposing a service publicly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you do not plan to run PHP in production, Nginx plus one database teaches the core operational loop: configure, reload, verify, and debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Add container basics only after the host makes sense
&lt;/h2&gt;

&lt;p&gt;Docker helps a lot, but it does not replace Linux fundamentals. If you cannot inspect storage, networking, and logs on the host, containers usually make debugging harder.&lt;/p&gt;

&lt;p&gt;Once the host feels familiar, Docker becomes much easier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run a service in isolation&lt;/li&gt;
&lt;li&gt;map ports intentionally&lt;/li&gt;
&lt;li&gt;persist data with volumes&lt;/li&gt;
&lt;li&gt;read container logs&lt;/li&gt;
&lt;li&gt;inspect environment variables and startup commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful first checks include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker ps -a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker logs &amp;lt;container&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker inspect &amp;lt;container&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker stats&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, simple Compose files are enough. The goal is to understand service dependencies, not to jump straight into orchestration.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Treat automation as the next multiplier
&lt;/h2&gt;

&lt;p&gt;Manual work teaches you what matters. Automation keeps you from repeating it badly.&lt;/p&gt;

&lt;p&gt;After you can update a host, deploy a web service, and troubleshoot a failed restart by hand, start learning Ansible. It is still one of the most practical ways to manage small and medium Linux fleets because it keeps the workflow readable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;define inventory&lt;/li&gt;
&lt;li&gt;describe desired state&lt;/li&gt;
&lt;li&gt;run repeatable changes over SSH&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good beginner automation targets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install baseline packages&lt;/li&gt;
&lt;li&gt;create users and SSH keys&lt;/li&gt;
&lt;li&gt;deploy Nginx config&lt;/li&gt;
&lt;li&gt;push application files&lt;/li&gt;
&lt;li&gt;restart services only when config changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can turn a one-hour manual rebuild into an idempotent playbook, you have crossed an important line from administration into operations engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Security should be operational, not decorative
&lt;/h2&gt;

&lt;p&gt;A lot of "security hardening" advice is either too vague or too heavy for small deployments. For most Linux VPS and small server environments, the basics still matter most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;disable direct root SSH login where possible&lt;/li&gt;
&lt;li&gt;prefer SSH keys over passwords&lt;/li&gt;
&lt;li&gt;limit exposed ports&lt;/li&gt;
&lt;li&gt;keep services updated&lt;/li&gt;
&lt;li&gt;watch authentication logs&lt;/li&gt;
&lt;li&gt;use a firewall with rules you can explain&lt;/li&gt;
&lt;li&gt;add Fail2ban or equivalent controls for repeated login abuse&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two practical rules help here:&lt;/p&gt;

&lt;p&gt;First, do not enable controls you cannot recover from remotely.&lt;/p&gt;

&lt;p&gt;Second, log review is part of security. If you never read auth logs, service logs, or ban events, you are not really verifying that your controls work.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Monitoring starts with simple questions
&lt;/h2&gt;

&lt;p&gt;Many teams jump straight to dashboards. Early on, it is better to build the habit of checking a system with a few direct questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the service up?&lt;/li&gt;
&lt;li&gt;Is it reachable on the expected port?&lt;/li&gt;
&lt;li&gt;Is the host out of disk or memory?&lt;/li&gt;
&lt;li&gt;Did a recent change increase errors?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why tools like &lt;code&gt;journalctl&lt;/code&gt;, &lt;code&gt;ss&lt;/code&gt;, &lt;code&gt;df&lt;/code&gt;, &lt;code&gt;free&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, and &lt;code&gt;iostat&lt;/code&gt; still matter. They help you answer the first operational questions quickly.&lt;/p&gt;

&lt;p&gt;When your environment grows, you can layer better visibility on top:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Glances for quick host inspection&lt;/li&gt;
&lt;li&gt;Prometheus for metrics collection&lt;/li&gt;
&lt;li&gt;Grafana for dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key is not the tool count. The key is whether you can move from symptom to evidence without guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Build a repeatable weekly routine
&lt;/h2&gt;

&lt;p&gt;Linux operations gets easier when maintenance becomes routine instead of reactive.&lt;/p&gt;

&lt;p&gt;A simple weekly checklist is enough for many small environments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check load, memory, disk, and service status.&lt;/li&gt;
&lt;li&gt;Review authentication and web service logs for anomalies.&lt;/li&gt;
&lt;li&gt;Apply pending security updates on a controlled schedule.&lt;/li&gt;
&lt;li&gt;Confirm backups are recent and restorable.&lt;/li&gt;
&lt;li&gt;Verify SSL certificate and domain-related expiry risk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is not glamorous work, but it prevents a large share of avoidable outages.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. What to learn after the basics
&lt;/h2&gt;

&lt;p&gt;Once the first layer feels natural, the next useful topics are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WireGuard or Tailscale for private access&lt;/li&gt;
&lt;li&gt;log rotation and retention&lt;/li&gt;
&lt;li&gt;backup automation&lt;/li&gt;
&lt;li&gt;nftables or a clearer firewall model&lt;/li&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;high-availability patterns&lt;/li&gt;
&lt;li&gt;Kubernetes only when you have a real need for it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common mistake is skipping directly to complex tooling before learning service behavior on one machine. In practice, strong single-host discipline scales better than weak multi-node complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;The original GSVPS article covers a wide range of Linux operations topics, from command-line basics to Docker, databases, automation, and hardening. The most practical way to use that kind of guide is not to copy every command into one server. It is to turn it into a learning order.&lt;/p&gt;

&lt;p&gt;If you are early in your Linux operations journey, focus on this sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;system basics&lt;/li&gt;
&lt;li&gt;one service stack&lt;/li&gt;
&lt;li&gt;container basics&lt;/li&gt;
&lt;li&gt;automation&lt;/li&gt;
&lt;li&gt;security and monitoring&lt;/li&gt;
&lt;li&gt;disciplined maintenance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That path is not the fastest-looking one, but it is usually the one that produces fewer fragile systems.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>devops</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Enable and Verify TCP BBR on Linux</title>
      <dc:creator>GSVPS</dc:creator>
      <pubDate>Wed, 01 Jul 2026 16:00:59 +0000</pubDate>
      <link>https://dev.to/huo_huo_ba0fc42b443732322/how-to-enable-and-verify-tcp-bbr-on-linux-47p6</link>
      <guid>https://dev.to/huo_huo_ba0fc42b443732322/how-to-enable-and-verify-tcp-bbr-on-linux-47p6</guid>
      <description>&lt;p&gt;BBR is a TCP congestion-control algorithm that estimates bandwidth and round-trip time. It can improve throughput on long-distance or high-latency TCP connections, but it is not a universal speed boost. If the bottleneck is CPU, storage, a bandwidth cap, a poor route, or UDP traffic, BBR may make little difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check support first
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
sysctl net.core.default_qdisc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Linux 4.9 or newer is generally required. Continue only if the available algorithms include &lt;code&gt;bbr&lt;/code&gt;. If BBR is missing, editing sysctl configuration will not help; upgrade to a supported kernel first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enable BBR safely
&lt;/h2&gt;

&lt;p&gt;Back up the configuration and check for conflicting entries:&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;sudo cp&lt;/span&gt; /etc/sysctl.conf /etc/sysctl.conf.bak
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-nE&lt;/span&gt; &lt;span class="s1"&gt;'net.core.default_qdisc|net.ipv4.tcp_congestion_control'&lt;/span&gt; /etc/sysctl.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the keys are absent, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then load the configuration:&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;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern Ubuntu, Debian, CentOS Stream, Rocky Linux, and AlmaLinux installations usually need no extra steps when the running kernel supports BBR. CentOS 7 often has an older default kernel, so check the actual kernel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify the active setting
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sysctl net.ipv4.tcp_congestion_control
sysctl net.core.default_qdisc
lsmod | &lt;span class="nb"&gt;grep &lt;/span&gt;bbr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important result is &lt;code&gt;net.ipv4.tcp_congestion_control = bbr&lt;/code&gt;. Some systems may not show an obvious &lt;code&gt;lsmod&lt;/code&gt; entry even when BBR is active.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure instead of guessing
&lt;/h2&gt;

&lt;p&gt;Compare before and after results using the same destination, file size, time window, and route. Look at sustained throughput, rsync or SCP stability, retransmissions, and performance over high-latency links. A single page refresh is not a useful benchmark.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;sysctl -p&lt;/code&gt; reports an invalid argument, recheck the available algorithms and look for duplicate settings in &lt;code&gt;/etc/sysctl.conf&lt;/code&gt; and &lt;code&gt;/etc/sysctl.d/&lt;/code&gt;. If the value changes after reboot, another sysctl file, cloud-init, a control panel, or an optimization script may be overriding it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roll back
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/sysctl.conf.bak /etc/sysctl.conf
&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The practical rule: verify kernel support, back up the configuration, enable BBR, confirm the active value, and measure under repeatable conditions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gsvps.com/articles/linux-kai-qi-bbr-jiao-cheng-ubuntu-debian-centos-yi-jian-kai-qi-bbr-jia-su-yu-jian-ce-2026-zui-xin" rel="noopener noreferrer"&gt;The original GSVPS guide&lt;/a&gt; includes distro-specific commands and a status-check script.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>networking</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a Self-Hosted Remote Desktop with Cloudflare Workers and WebRTC</title>
      <dc:creator>GSVPS</dc:creator>
      <pubDate>Mon, 29 Jun 2026 18:51:02 +0000</pubDate>
      <link>https://dev.to/huo_huo_ba0fc42b443732322/building-a-self-hosted-remote-desktop-with-cloudflare-workers-and-webrtc-kka</link>
      <guid>https://dev.to/huo_huo_ba0fc42b443732322/building-a-self-hosted-remote-desktop-with-cloudflare-workers-and-webrtc-kka</guid>
      <description>&lt;p&gt;Running a remote desktop service usually means maintaining a relay server with enough bandwidth to carry every screen frame. That is expensive and creates an obvious bottleneck. A different design is to separate the control plane from the media plane:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare Workers handles the API, authentication, and WebSocket signaling.&lt;/li&gt;
&lt;li&gt;D1, KV, R2, and Durable Objects provide persistence and coordination.&lt;/li&gt;
&lt;li&gt;WebRTC sends screen, keyboard, mouse, and clipboard traffic directly between peers.&lt;/li&gt;
&lt;li&gt;An optional VPS deployment replaces the Cloudflare backend with Node.js, SQLite, and Docker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GsDesk is an open-source implementation of this architecture. Its server helps two endpoints find and authenticate each other, but it does not relay the desktop video stream.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this architecture matters
&lt;/h2&gt;

&lt;p&gt;The expensive part of remote desktop software is continuous media traffic. If a Worker only processes API requests and signaling messages, the majority of bandwidth avoids the server entirely. That makes a free or low-cost serverless control plane practical for personal remote access, home labs, NAS administration, and lightweight IT support.&lt;/p&gt;

&lt;p&gt;There is an important limitation: peer-to-peer connectivity depends on the network conditions of both endpoints. Strict NAT or firewall policies can prevent direct connections. A production deployment should therefore test the networks it needs to support and decide whether a TURN relay is required as a fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fast deployment path
&lt;/h2&gt;

&lt;p&gt;Clone the project and install its dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/gsvps/gsdesk.git
&lt;span class="nb"&gt;cd &lt;/span&gt;gsdesk
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authenticate Wrangler and deploy the Cloudflare backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx wrangler login
npm run deploy:cloudflare
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After deployment, verify two separate routes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;https://your-domain.example/&lt;/code&gt; should return &lt;code&gt;success&lt;/code&gt;; this is the health endpoint, not the control interface.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;https://your-domain.example/app/&lt;/code&gt; should open the browser control interface. The path is configurable through &lt;code&gt;WEB_APP_PATH&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Windows client exposes its local UI at &lt;code&gt;http://127.0.0.1:19527&lt;/code&gt;. Configure the deployed API URL and the controller JWT secret, enable incoming control on the target device, and connect with its eight-digit device ID plus either a one-time or permanent password.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-hosting on a VPS
&lt;/h2&gt;

&lt;p&gt;If you prefer to keep the control plane off Cloudflare, the same protocol can run on a Linux VPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The self-hosted backend uses Node.js, SQLite, local file storage, and WebSockets. This option is useful when you need full control over persistence, logs, or network policy. It does not change the core design: desktop media still uses WebRTC peer-to-peer transport.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security checklist
&lt;/h2&gt;

&lt;p&gt;Before exposing an instance to the internet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;CONTROLLER_JWT_SECRET&lt;/code&gt; with a strong random value.&lt;/li&gt;
&lt;li&gt;Treat the device ID as an identifier, not a password.&lt;/li&gt;
&lt;li&gt;Keep Ed25519 device private keys on the endpoint.&lt;/li&gt;
&lt;li&gt;Use OTPs for temporary access and avoid storing them.&lt;/li&gt;
&lt;li&gt;Disable automatic acceptance when users should approve each session.&lt;/li&gt;
&lt;li&gt;Keep API rate limiting and failed-login controls enabled.&lt;/li&gt;
&lt;li&gt;Use HTTPS/WSS and review any custom reverse-proxy configuration.&lt;/li&gt;
&lt;li&gt;Restrict access to the browser control route when your use case permits it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WebRTC protects media with DTLS, but transport encryption does not compensate for weak controller secrets or overly permissive access settings. Authentication and endpoint security remain part of the threat model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to validate after deployment
&lt;/h2&gt;

&lt;p&gt;A basic smoke test should cover more than the home page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /              -&amp;gt; success
GET /api/health    -&amp;gt; API status and web_app_entry
GET /app/          -&amp;gt; browser controller
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then test device registration, a complete remote session, clipboard synchronization, file transfer, reconnect behavior, and connectivity from the actual networks you intend to use.&lt;/p&gt;

&lt;p&gt;The full tutorial includes configuration variables, API routes, directory layout, Windows client build instructions, Cloudflare and VPS deployment details, and troubleshooting notes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Original guide:&lt;/strong&gt; &lt;a href="https://www.gsvps.com/articles/tutorials-22" rel="noopener noreferrer"&gt;https://www.gsvps.com/articles/tutorials-22&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclosure: I am affiliated with GSVPS, which publishes the original tutorial and maintains the linked GsDesk project.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
