<?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: Muhammad Jawad Iqbal Khan</title>
    <description>The latest articles on DEV Community by Muhammad Jawad Iqbal Khan (@codebyjawad).</description>
    <link>https://dev.to/codebyjawad</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%2F4057702%2F355630a8-3bd7-4a5a-83cd-4fb739e8759b.png</url>
      <title>DEV Community: Muhammad Jawad Iqbal Khan</title>
      <link>https://dev.to/codebyjawad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codebyjawad"/>
    <language>en</language>
    <item>
      <title>Reinstall your VPS in one command - no control panel, no rescue ISO</title>
      <dc:creator>Muhammad Jawad Iqbal Khan</dc:creator>
      <pubDate>Sat, 01 Aug 2026 08:53:32 +0000</pubDate>
      <link>https://dev.to/codebyjawad/reinstall-your-vps-in-one-command-no-control-panel-no-rescue-iso-4h98</link>
      <guid>https://dev.to/codebyjawad/reinstall-your-vps-in-one-command-no-control-panel-no-rescue-iso-4h98</guid>
      <description>&lt;h1&gt;
  
  
  Reinstall your VPS in one command — no control panel, no rescue ISO
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;A practical tutorial. &lt;code&gt;restage&lt;/code&gt; is an open-source toolkit that reinstalls a&lt;br&gt;
Linux server over the network with a single command, boots a rescue&lt;br&gt;
environment, or writes a disk image — without a control panel, without a&lt;br&gt;
rescue ISO, and without manual bootloader surgery.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;You rent a VPS. Three months later you want a clean Debian instead of the&lt;br&gt;
Ubuntu image the provider shipped — or you just want to start over. Most&lt;br&gt;
providers give you a clunky control-panel "reinstall" button that works only&lt;br&gt;
for their own images. Some don't give you one at all.&lt;/p&gt;

&lt;p&gt;So what do people actually do?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep a server running for years with cruft you're afraid to touch.&lt;/li&gt;
&lt;li&gt;Boot a rescue ISO in the provider's panel, then fight with &lt;code&gt;dd&lt;/code&gt;, &lt;code&gt;mount&lt;/code&gt;,
&lt;code&gt;chroot&lt;/code&gt;, and grub by hand.&lt;/li&gt;
&lt;li&gt;Use a control panel you don't want, just to get the reinstall feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There had to be a better way.&lt;/p&gt;
&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;What if reinstalling looked like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;restage linux debian 12 &lt;span class="nt"&gt;--ssh-key&lt;/span&gt; &lt;span class="s2"&gt;"ssh-ed25519 AAAA..."&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command. It downloads a minimal kernel + initrd, patches the initrd with&lt;br&gt;
an installer runtime plus your credentials and network config, installs a&lt;br&gt;
one-shot boot entry, and reboots. When the machine comes back, the installer&lt;br&gt;
finds the target disk by its &lt;strong&gt;partition-table UUID&lt;/strong&gt; (never by device name),&lt;br&gt;
writes the OS from official cloud images, fixes the bootloader, and reboots&lt;br&gt;
into your brand-new system.&lt;/p&gt;

&lt;p&gt;Because the disk is selected by PTUUID, the tool survives kernel device&lt;br&gt;
renaming between boots. And nothing touches the disk until the action plan&lt;br&gt;
has been shown and confirmed.&lt;/p&gt;

&lt;p&gt;That's exactly what &lt;a href="https://github.com/codebyjawad/restage" rel="noopener noreferrer"&gt;restage&lt;/a&gt; does —&lt;br&gt;
an MIT-licensed, POSIX/bash toolkit with tests, CI, and docs.&lt;/p&gt;
&lt;h2&gt;
  
  
  What you can do with it
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restage linux &amp;lt;distro&amp;gt; &amp;lt;version&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reinstall to Debian, Ubuntu, Alpine, AlmaLinux, Rocky, or openEuler from official cloud images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restage dd --img &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write any raw or compressed disk image (gzip / xz / zstd / qcow2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restage windows --image-name NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reinstall to Windows from an official ISO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restage alpine&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boot the Alpine Live rescue environment (non-destructive)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restage netboot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boot the netboot.xyz menu (non-destructive)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restage reset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cancel a pending reinstall before reboot&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Non-destructive commands (&lt;code&gt;alpine&lt;/code&gt;, &lt;code&gt;netboot&lt;/code&gt;) are handy when a server won't&lt;br&gt;
boot and you need a rescue environment right now.&lt;/p&gt;
&lt;h2&gt;
  
  
  Safety first
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; &lt;code&gt;linux&lt;/code&gt;, &lt;code&gt;dd&lt;/code&gt;, and &lt;code&gt;windows&lt;/code&gt; erase the entire primary disk.&lt;/p&gt;

&lt;p&gt;That's why the toolkit is paranoid by design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every run produces an explicit &lt;strong&gt;action plan&lt;/strong&gt; you approve before anything
happens.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--dry-run&lt;/code&gt; prints the plan and changes nothing:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;restage linux debian 12 &lt;span class="nt"&gt;--ssh-key&lt;/span&gt; &lt;span class="s2"&gt;"ssh-ed25519 AAAA..."&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Input is validated centrally, before any plan is built.&lt;/li&gt;
&lt;li&gt;Networking (static or DHCP) is captured into the installer, so the rescue
environment doesn't depend on a DHCP server.&lt;/li&gt;
&lt;li&gt;There's a &lt;code&gt;reset&lt;/code&gt; command to cancel a pending reinstall while the host is
still up.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Installing
&lt;/h2&gt;

&lt;p&gt;Requirements: Linux, running as root, with &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt; (or &lt;code&gt;wget&lt;/code&gt;),&lt;br&gt;
&lt;code&gt;gzip&lt;/code&gt;, &lt;code&gt;xz&lt;/code&gt;, &lt;code&gt;cpio&lt;/code&gt;, &lt;code&gt;zcat&lt;/code&gt;, and a supported bootloader (grub, extlinux, or&lt;br&gt;
EFI).&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/codebyjawad/restage.git
&lt;span class="nb"&gt;cd &lt;/span&gt;restage

./restage.sh version      &lt;span class="c"&gt;# run directly from the tree&lt;/span&gt;
make &lt;span class="nb"&gt;install&lt;/span&gt;              &lt;span class="c"&gt;# or install to /usr/local/bin/restage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Your first reinstall
&lt;/h2&gt;

&lt;p&gt;Always plan first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;restage linux debian 12 &lt;span class="nt"&gt;--ssh-key&lt;/span&gt; &lt;span class="s2"&gt;"ssh-ed25519 AAAA..."&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect the plan: target disk, OS to install, boot entry, SSH settings. If it&lt;br&gt;
looks right, run the same command with &lt;code&gt;--yes&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;restage linux debian 12 &lt;span class="nt"&gt;--ssh-key&lt;/span&gt; &lt;span class="s2"&gt;"ssh-ed25519 AAAA..."&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fetches the kernel + initrd, patches the installer runtime, sets a&lt;br&gt;
one-shot boot entry, and reboots. When the machine returns, it's running&lt;br&gt;
Debian 12 with your SSH key — password login disabled.&lt;/p&gt;

&lt;p&gt;Other examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;restage linux ubuntu 24.04 &lt;span class="nt"&gt;--password&lt;/span&gt; &lt;span class="s1"&gt;'ChangeMe123!'&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
restage &lt;span class="nb"&gt;dd&lt;/span&gt; &lt;span class="nt"&gt;--img&lt;/span&gt; https://example.com/image.qcow2 &lt;span class="nt"&gt;--yes&lt;/span&gt;
restage windows &lt;span class="nt"&gt;--image-name&lt;/span&gt; &lt;span class="s2"&gt;"Windows 11 Pro"&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
restage alpine                      &lt;span class="c"&gt;# rescue environment, no disk writes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why a new project?
&lt;/h2&gt;

&lt;p&gt;Most VPS reinstall tools are a single long shell script that grew organically&lt;br&gt;
over years: no tests, no CI, opaque errors, &lt;code&gt;eval&lt;/code&gt; of user-controlled&lt;br&gt;
strings, and documentation in one language only. &lt;code&gt;restage&lt;/code&gt; is a&lt;br&gt;
from-scratch, production-minded reimplementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modular &lt;code&gt;lib/&lt;/code&gt; + &lt;code&gt;flows/&lt;/code&gt; + &lt;code&gt;runtime/&lt;/code&gt; instead of a monolith.&lt;/li&gt;
&lt;li&gt;bats unit + integration tests, run by CI on every push.&lt;/li&gt;
&lt;li&gt;Strict, centralized input validation and an explicit action plan.&lt;/li&gt;
&lt;li&gt;POSIX-quoted generated config instead of &lt;code&gt;eval&lt;/code&gt; on user strings.&lt;/li&gt;
&lt;li&gt;A catalog-driven distro list — adding a distro is a data change.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was inspired by (but shares no code with) the well-known&lt;br&gt;
&lt;code&gt;bin456789/reinstall&lt;/code&gt; project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to get it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/codebyjawad/restage" rel="noopener noreferrer"&gt;https://github.com/codebyjawad/restage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://codebyjawad.github.io/restage/" rel="noopener noreferrer"&gt;https://codebyjawad.github.io/restage/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;License: MIT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you manage VPSes, try &lt;code&gt;--dry-run&lt;/code&gt; on one of them. It prints the whole&lt;br&gt;
plan and changes nothing — the safest possible way to see what a one-command&lt;br&gt;
reinstall looks like.&lt;/p&gt;




&lt;p&gt;If you manage VPSes, give &lt;a href="https://github.com/codebyjawad/restage" rel="noopener noreferrer"&gt;restage&lt;/a&gt; a try. It's MIT-licensed, tested in CI, and --dry-run prints the whole plan without changing anything. Docs: &lt;a href="https://codebyjawad.github.io/restage/" rel="noopener noreferrer"&gt;https://codebyjawad.github.io/restage/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bash</category>
      <category>devops</category>
      <category>vps</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
