From c3bb0c9f49daedfc33a1295e931bbe5ef72a7529 Mon Sep 17 00:00:00 2001 From: Pavel Sviderski Date: Thu, 6 Mar 2025 16:49:58 +1000 Subject: [PATCH] chore(readme): add Quick demo section with video, update how it works outputs --- README.md | 134 +++++++++++++++++++++++++++++------- cmd/uncloud/machine/add.go | 1 + cmd/uncloud/machine/init.go | 1 + 3 files changed, 113 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 4f49de7e..51e7c4c5 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,14 @@ some machines go offline. Uncloud aims to be the solution for developers who want the flexibility of self-hosted infrastructure without the operational complexity of Kubernetes. +## 🎬 Quick demo + +Deploy a highly available web app with automatic HTTPS across multiple regions and on-premises in just a couple minutes. + + +Uncloud demo + + ## ✨ Features * **Deploy anywhere**: Combine cloud VMs, dedicated servers, and bare metal into a unified computing environment — @@ -66,36 +74,43 @@ platform, whether you're running on a $5 VPS, a spare Mac mini, or a rack of bar 1. Install Uncloud CLI: -```bash -brew install psviderski/tap/uncloud + ```bash + brew install psviderski/tap/uncloud -# or using curl (macOS/Linux) -curl -fsS https://get.uncloud.run/install.sh | sh -``` + # or using curl (macOS/Linux) + curl -fsS https://get.uncloud.run/install.sh | sh + ``` 2. Initialize your first machine: -```bash -uc machine init root@your-server-ip -``` + ```bash + uc machine init root@your-server-ip + ``` -3. Create a DNS A record in your DNS provider (Cloudflare, Namecheap, etc.) that points `app.example.com` to your +3. Deploy your app from a Docker image and publish its container port 8000 as HTTPS using `app.example.com` domain: + + ```bash + uc run -p app.example.com:8000/https image/my-app + ``` + +4. Create a DNS A record in your DNS provider (Cloudflare, Namecheap, etc.) that points `app.example.com` to your server's IP address. Allow a few minutes for DNS propagation. -4. Deploy your app from a Docker image: -```bash -uc run -p app.example.com:8000/https my-app-image -``` - -That's it! Your app is now running and accessible at https://app.example.com ✨ + That's it! Your app is now running and accessible at https://app.example.com ✨ 5. Clean up when you're done: -```bash -uc ls -# Copy the service ID from the output and remove it: -uc rm my-app-id -``` + ```bash + uc ls + # Copy the service name from the output and run the rm command: + uc rm my-app-name + ``` + + If you want to fully uninstall Uncloud on a machine, run: + + ```bash + uncloud-uninstall + ``` ## ⚙️ How it works @@ -105,7 +120,42 @@ under the hood to see what happens when you run certain commands. **When you initialize a new cluster on a machine:** ```bash -uc machine init root@your-server-ip +$ uc machine init --name oracle-vm ubuntu@152.67.101.197 + +Downloading Uncloud install script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/install.sh +⏳ Running Uncloud install script... +✓ Docker is already installed. +⏳ Installing Docker... +... +✓ Docker installed successfully. +✓ Linux user and group 'uncloud' created. +✓ Linux user 'ubuntu' added to group 'uncloud'. +⏳ Installing Uncloud binaries... +⏳ Downloading uncloudd binary: https://github.com/psviderski/uncloud/releases/latest/download/uncloudd_linux_arm64.tar.gz +✓ uncloudd binary installed: /usr/local/bin/uncloudd +⏳ Downloading uninstall script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/uninstall.sh +✓ uncloud-uninstall script installed: /usr/local/bin/uncloud-uninstall +✓ Systemd unit file created: /etc/systemd/system/uncloud.service +Created symlink /etc/systemd/system/multi-user.target.wants/uncloud.service → /etc/systemd/system/uncloud.service. +⏳ Downloading uncloud-corrosion binary: https://github.com/psviderski/corrosion/releases/latest/download/corrosion-aarch64-unknown-linux-gnu.tar.gz +✓ uncloud-corrosion binary installed: /usr/local/bin/uncloud-corrosion +✓ Systemd unit file created: /etc/systemd/system/uncloud-corrosion.service +⏳ Starting Uncloud machine daemon (uncloud.service)... +✓ Uncloud machine daemon started. +✓ Uncloud installed on the machine successfully! 🎉 +Cluster "default" initialised with machine "oracle-vm" +Waiting for the machine to be ready... + +Reserved cluster domain: xuw3xd.cluster.uncloud.run +[+] Deploying service caddy 1/1 + ✔ Container caddy-c47x on oracle-vm Started 0.9s + +Updating cluster domain records in Uncloud DNS to point to machines running caddy service... +[+] Verifying internet access to caddy service 1/1 + ✔ Machine oracle-vm (152.67.101.197) Reachable 0.1s + +DNS records updated to use only the internet-reachable machines running caddy service: + *.xuw3xd.cluster.uncloud.run A → 152.67.101.197 ``` 1. The CLI SSHs into the machine and installs Docker, the `uncloudd` machine daemon and @@ -121,7 +171,38 @@ uc machine init root@your-server-ip **When you add another machine:** ```bash -uc machine add ubuntu@second-server-ip +$ uc machine add --name hetzner-server root@5.223.45.199 + +Downloading Uncloud install script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/install.sh +⏳ Running Uncloud install script... +✓ Docker is already installed. +✓ Linux user and group 'uncloud' created. +⏳ Installing Uncloud binaries... +⏳ Downloading uncloudd binary: https://github.com/psviderski/uncloud/releases/latest/download/uncloudd_linux_amd64.tar.gz +✓ uncloudd binary installed: /usr/local/bin/uncloudd +⏳ Downloading uninstall script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/uninstall.sh +✓ uncloud-uninstall script installed: /usr/local/bin/uncloud-uninstall +✓ Systemd unit file created: /etc/systemd/system/uncloud.service +Created symlink /etc/systemd/system/multi-user.target.wants/uncloud.service → /etc/systemd/system/uncloud.service. +⏳ Downloading uncloud-corrosion binary: https://github.com/psviderski/corrosion/releases/latest/download/corrosion-x86_64-unknown-linux-gnu.tar.gz +✓ uncloud-corrosion binary installed: /usr/local/bin/uncloud-corrosion +✓ Systemd unit file created: /etc/systemd/system/uncloud-corrosion.service +⏳ Starting Uncloud machine daemon (uncloud.service)... +✓ Uncloud machine daemon started. +✓ Uncloud installed on the machine successfully! 🎉 +Machine "hetzner-server" added to cluster +Waiting for the machine to be ready... + +[+] Deploying service caddy 1/1 + ✔ Container caddy-d36c on hetzner-server Started 1.0s + +Updating cluster domain records in Uncloud DNS to point to machines running caddy service... +[+] Verifying internet access to caddy service 2/2 + ✔ Machine hetzner-server (5.223.45.199) Reachable 0.2s + ✔ Machine oracle-vm (152.67.101.197) Reachable 0.1s + +DNS records updated to use only the internet-reachable machines running caddy service: + *.xuw3xd.cluster.uncloud.run A → 152.67.101.197, 5.223.45.199 ``` 1. The second machine gets provisioned just like the first. A non-root SSH user will need `sudo` access. @@ -140,7 +221,14 @@ and automatically establish a WireGuard tunnel with it. **When you run a service:** ```bash -uc run -p app.example.com:8000/https my-app-image +$ uc run -p app.example.com:8000/https image/my-app + +[+] Running service my-app-1b3b (replicated mode) 1/1 + ✔ Container my-app-1b3b-tcex on oracle-vm Started + +my-app-1b3b endpoints: + • https://app.example.com → :8000 + • https://my-app-1b3b.xuw3xd.cluster.uncloud.run → :8000 ``` 1. CLI picks a machine to run your container. diff --git a/cmd/uncloud/machine/add.go b/cmd/uncloud/machine/add.go index 405fb7e4..ce428a90 100644 --- a/cmd/uncloud/machine/add.go +++ b/cmd/uncloud/machine/add.go @@ -98,6 +98,7 @@ func add(ctx context.Context, uncli *cli.CLI, remoteMachine cli.RemoteMachine, o // Wait for the cluster to be initialised to be able to deploy the Caddy service. fmt.Println("Waiting for the machine to be ready...") + fmt.Println() if err = waitClusterInitialised(ctx, machineClient); err != nil { return fmt.Errorf("wait for cluster to be initialised on machine: %w", err) } diff --git a/cmd/uncloud/machine/init.go b/cmd/uncloud/machine/init.go index b2cb4289..5666d2b6 100644 --- a/cmd/uncloud/machine/init.go +++ b/cmd/uncloud/machine/init.go @@ -121,6 +121,7 @@ func initCluster(ctx context.Context, uncli *cli.CLI, remoteMachine *cli.RemoteM // The creation of a deployment plan talks to cluster API. Since the API needs a few moments to become available // after cluster initialisation, we keep the user informed during this wait. fmt.Println("Waiting for the machine to be ready...") + fmt.Println() if !opts.noDNS { domain, err := client.ReserveDomain(ctx, &pb.ReserveDomainRequest{Endpoint: opts.dnsEndpoint})