mirror of
https://github.com/psviderski/uncloud.git
synced 2026-10-06 13:18:58 +00:00
docs: combine landing page and docusaurus together and deploy as one image
This commit is contained in:
1 parent
cac1550b7d
commit
4fe360c573
47 files changed
+19097
-19102
No files matched your search
@@ -0,0 +1,16 @@
|
||||
# Ignore everything and use an allowlist of what is allowed to not package any secrets by accident.
|
||||
*
|
||||
|
||||
# Allow files and directories.
|
||||
!blog2/
|
||||
!docs/
|
||||
!landing/
|
||||
!src/
|
||||
!static/
|
||||
!pkg/
|
||||
!Caddyfile
|
||||
!*.js
|
||||
!*.json
|
||||
|
||||
# Ignore unnecessary files inside allowed directories.
|
||||
**/.DS_Store
|
||||
@@ -0,0 +1,20 @@
|
||||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
admin off
|
||||
}
|
||||
|
||||
:8000 {
|
||||
root * /usr/share/caddy
|
||||
file_server
|
||||
log
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# Stage 1: Base image.
|
||||
## Start with a base image containing NodeJS so we can build Docusaurus.
|
||||
FROM node:lts-alpine AS base
|
||||
## Disable colour output from yarn to make logs easier to read.
|
||||
ENV FORCE_COLOR=0
|
||||
## Enable corepack.
|
||||
RUN corepack enable
|
||||
## Set the working directory to `/opt/docusaurus`.
|
||||
WORKDIR /opt/docusaurus
|
||||
|
||||
# Stage 2: Production build.
|
||||
FROM base AS prod
|
||||
## Set the working directory to `/opt/docusaurus`.
|
||||
WORKDIR /opt/docusaurus
|
||||
## Copy over the source code.
|
||||
COPY . /opt/docusaurus/
|
||||
## Install dependencies with `--immutable` to ensure reproducibility.
|
||||
RUN npm ci
|
||||
## Build the static site.
|
||||
RUN npm run build
|
||||
|
||||
# Stage 3: Serve static Docusaurus site and landing page with Caddy.
|
||||
FROM caddy:2.10.0-alpine AS caddy
|
||||
## Copy the Caddyfile.
|
||||
COPY ./Caddyfile /etc/caddy/Caddyfile
|
||||
## Copy the Docusaurus build output.
|
||||
COPY --from=prod /opt/docusaurus/build /usr/share/caddy
|
||||
# Copy the landing page assets.
|
||||
COPY landing/images /usr/share/caddy/images
|
||||
COPY landing/index.html landing/style.css /usr/share/caddy/
|
||||
@@ -0,0 +1,5 @@
|
||||
WEBSITE_IMAGE ?= ghcr.io/psviderski/uncloud-website:latest
|
||||
|
||||
.PHONY: website-image-push
|
||||
website-image-push:
|
||||
docker buildx build --push --platform linux/amd64,linux/arm64 -t "$(WEBSITE_IMAGE)" .
|
||||
@@ -0,0 +1,52 @@
|
||||
# Website
|
||||
|
||||
## Landing page
|
||||
|
||||
Landing page is a single static HTML file located at [`./landing/index.html`](./landing/index.html). It is built
|
||||
using [Tailwind CSS](https://tailwindcss.com/).
|
||||
|
||||
### Local development
|
||||
|
||||
```shell
|
||||
cd landing
|
||||
open index.html
|
||||
# Watch the Tailwind CSS class changes and rebuild style.css
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Docs and Blog
|
||||
|
||||
`/docs` and `/blog` are built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
### Local Development
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
|
||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without
|
||||
having to restart the server.
|
||||
|
||||
## Deployment
|
||||
|
||||
Both the landing page and Docusaurus site are built into a single Docker image that runs Caddy web server to serve the
|
||||
static files.
|
||||
|
||||
Before building a production image, test the build locally:
|
||||
|
||||
```shell
|
||||
docker compose -f compose.local.yaml up --build
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
* http://localhost:8000 — should show the landing page
|
||||
* http://localhost:3000/docs/ — should show the docs generated by Docusaurus
|
||||
* http://localhost:3000/blog/ — should show the blog generated by Docusaurus
|
||||
|
||||
### Deploy to production
|
||||
|
||||
```shell
|
||||
make website-image-push
|
||||
uc deploy
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
services:
|
||||
website:
|
||||
build: .
|
||||
user: nobody
|
||||
ports:
|
||||
- "8000:8000"
|
||||
@@ -0,0 +1,8 @@
|
||||
services:
|
||||
uncloud-website:
|
||||
image: ghcr.io/psviderski/uncloud-website:latest
|
||||
pull_policy: always
|
||||
user: nobody
|
||||
x-ports:
|
||||
- uncloud.run:8000/https
|
||||
scale: 2
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Overview
|
||||
|
||||
Uncloud makes **self-hosting web applications** across multiple machines in production dead simple.
|
||||
|
||||
You can connect any machines — from cloud VMs to bare metal servers (no matter where they're located) — into a secure
|
||||
private network. Then run and scale multi-service and multi-container web apps and databases across your machines using
|
||||
simple Docker-like commands and [Docker Compose](https://docs.docker.com/reference/compose-file/) files.
|
||||
|
||||
Uncloud covers all the essentials for operating apps in production without overwhelming you with the complexity of
|
||||
traditional container orchestrators like Kubernetes or Swarm:
|
||||
|
||||
* Initial machine and network setup
|
||||
* Zero-downtime rolling deployments
|
||||
* Health checks and automatic restarts
|
||||
* Automatic HTTPS and reverse proxy configuration
|
||||
* Scaling services across multiple machines
|
||||
* Cross-machine service communication without exposing ports to the internet
|
||||
* DNS-based service discovery
|
||||
* Load balancing
|
||||
* Persistent storage
|
||||
|
||||
## Use cases
|
||||
|
||||
Some of the common use cases Uncloud is a great fit for:
|
||||
|
||||
- **Self-hosting and Homelabs**: Run your self-hosted apps on your own hardware. Start with a single machine and add
|
||||
more as your needs grow.
|
||||
- **Outgrowing Docker Compose**: Level up your Docker Compose setup with zero-downtime deployments, replicas across
|
||||
multiple machines for improved reliability, cross-machine service communication, automated reverse proxy management,
|
||||
and more using the same Compose file.
|
||||
- **Small to medium web applications**: Deploy your SaaS product, websites, or personal projects with redundancy across
|
||||
multiple machines for better reliability and your peace of mind.
|
||||
- **Hybrid setups (cloud + on-prem)**: Combine cloud VMs with on-premise for cost savings and data sovereignty — all
|
||||
managed through the same interface.
|
||||
- **Agencies and freelancers**: Host multiple client projects with proper isolation on shared infrastructure, optimising
|
||||
costs and resources.
|
||||
- **Edge computing**: Deploy applications closer to your users for lower latency and better performance.
|
||||
- **Dev/staging environments**: Spin up additional environments for development and testing that mirror production
|
||||
reusing the same Compose configuration.
|
||||
|
||||
## What makes Uncloud different
|
||||
|
||||
Here are the design decisions that make Uncloud stand out:
|
||||
|
||||
### Decentralised design
|
||||
|
||||
You can think of an Uncloud cluster as a **network of Docker hosts** (machines) that are all aware of each other. All
|
||||
machines in the cluster are equal. You can connect to any of them to manage containers on any other machine in the
|
||||
cluster. If a machine or part of the network goes down, the rest of the cluster keeps running.
|
||||
|
||||
There is no centralised control plane, so no need to worry about maintaining a quorum of machines for it. The time saved
|
||||
can be better spent developing and deploying your apps instead.
|
||||
|
||||
### Zero-config overlay network
|
||||
|
||||
Uncloud automatically configures and maintains a secure **WireGuard mesh network** across your machines. It handles key
|
||||
management, peer discovery, and NAT traversal without any manual configuration. This makes it easy to connect machines
|
||||
from different networks and locations, such as cloud VMs, on-premise servers, or your Raspberry Pi at home.
|
||||
|
||||
Docker containers running on different machines get **unique IP addresses** from the cluster network so they can
|
||||
**communicate directly** as if they were on a single machine without opening up any host ports to the internet.
|
||||
|
||||
The design and implementation were highly inspired by
|
||||
Talos [KubeSpan](https://www.talos.dev/v1.10/talos-guides/network/kubespan/).
|
||||
|
||||
### Managed DNS service
|
||||
|
||||
Uncloud can provide **managed DNS records** like `<service-name>.<cluster-id>.cluster.uncloud.run` for your public
|
||||
services through free [Uncloud DNS](https://github.com/psviderski/uncloud-dns) service. You can deploy a service and
|
||||
instantly access it from anywhere with a proper DNS name and HTTPS without any manual DNS configuration. This makes
|
||||
self-hosting much more accessible and simplifies the process of adding your own domain later.
|
||||
|
||||
### No complex orchestration
|
||||
|
||||
Uncloud operations are done using **imperative CLI commands** that have the taste of Docker and Docker Compose. The
|
||||
deployment and scaling commands can output an execution plan that describes what exactly will be changed on your cluster
|
||||
once you approve it. For example, what containers and volumes will be created or removed, and on which machines.
|
||||
|
||||
This gives you full visibility and control over every change with **immediate feedback** when something goes wrong.
|
||||
|
||||
### Minimal resource footprint
|
||||
|
||||
The Uncloud daemon consists of a couple Go and Rust binaries running alongside the Docker daemon on each machine. It
|
||||
needs no more than **150 MB of RAM** and a few percent of a CPU core in small setups. This minimal overhead maximises
|
||||
the system resources available for your apps.
|
||||
|
||||
You can run Uncloud on machines with as little as 512 MB of RAM, assuming you also need some RAM for the OS and Docker,
|
||||
as well as the apps you want to run.
|
||||
|
||||
### Troubleshooting-friendly
|
||||
|
||||
When something goes wrong, you can dive straight into standard Docker containers without layers of abstraction in your
|
||||
way. You can also SSH into any machine and use the regular Linux troubleshooting tools. For example, `ping` service
|
||||
containers by their service names, `curl` service endpoints, or analyse traffic between containers using `wireshark`.
|
||||
|
||||
## Getting started
|
||||
|
||||
Install Uncloud CLI and deploy your first app in minutes:
|
||||
|
||||
* [Install Uncloud CLI](./2-getting-started/1-install-cli.md)
|
||||
* [Deploy demo app](./2-getting-started/2-deploy-demo-app.md)
|
||||
|
||||
## Getting help
|
||||
|
||||
* **Discord community**: Join our [Discord server](https://discord.gg/eR35KQJhPu) for real-time discussions, support,
|
||||
and updates.
|
||||
* **GitHub issues**: Report bugs or request features on our [GitHub repository](https://github.com/psviderski/uncloud).
|
||||
* **Documentation**: Browse the full documentation (this website you're on) for detailed guides and references. Use
|
||||
search to find what you need quickly.
|
||||
* **Newsletter**: Subscribe to the [newsletter](https://uncloud.run/#subscribe) for development updates and early
|
||||
insights.
|
||||
@@ -0,0 +1,121 @@
|
||||
# Install CLI
|
||||
|
||||
Install the Uncloud command-line utility to manage your machines and deploy apps using `uc` commands. You will run `uc`
|
||||
locally so choose the appropriate installation method for your operating system.
|
||||
|
||||
:::info NOTE
|
||||
|
||||
Windows is not natively supported yet, but you can install and run `uc` in a
|
||||
[WSL](https://learn.microsoft.com/en-us/windows/wsl/) terminal by following the instructions for Linux.
|
||||
:::
|
||||
|
||||
## Homebrew (macOS, Linux)
|
||||
|
||||
If you have [Homebrew](https://brew.sh/) package manager installed, this is the recommended installation method on macOS
|
||||
and Linux:
|
||||
|
||||
```shell
|
||||
brew install psviderski/tap/uncloud
|
||||
```
|
||||
|
||||
To upgrade to the latest version:
|
||||
|
||||
```shell
|
||||
brew upgrade uncloud
|
||||
```
|
||||
|
||||
## Install script (macOS, Linux)
|
||||
|
||||
For a quick automated installation, use the install script:
|
||||
|
||||
```shell
|
||||
curl -fsS https://get.uncloud.run/install.sh | sh
|
||||
```
|
||||
|
||||
The script will:
|
||||
|
||||
- Detect your operating system and architecture
|
||||
- Download the appropriate latest binary from [GitHub releases](https://github.com/psviderski/uncloud/releases)
|
||||
- Install it to `/usr/local/bin/uncloud` using `sudo` (you may need to enter your user password)
|
||||
- Create a shortcut `uc` in `/usr/local/bin` for convenience
|
||||
|
||||
Don't like `curl | sh`? You can download and review the [install script](https://get.uncloud.run/install.sh) first and
|
||||
then run it:
|
||||
|
||||
```shell
|
||||
curl -fsSO https://get.uncloud.run/install.sh
|
||||
cat install.sh
|
||||
sh install.sh
|
||||
```
|
||||
|
||||
## GitHub download (macOS, Linux)
|
||||
|
||||
You can manually download and use a pre-built binary from the
|
||||
[latest release](https://github.com/psviderski/uncloud/releases/latest) on GitHub.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="macOS (Apple Silicon)">
|
||||
```shell
|
||||
curl -L https://github.com/psviderski/uncloud/releases/latest/download/uncloud_macos_arm64.tar.gz | tar xz
|
||||
mv uncloud uc
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="macOS (Intel)">
|
||||
```shell
|
||||
curl -L https://github.com/psviderski/uncloud/releases/latest/download/uncloud_macos_amd64.tar.gz | tar xz
|
||||
mv uncloud uc
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="Linux (AMD 64-bit)">
|
||||
```shell
|
||||
curl -L https://github.com/psviderski/uncloud/releases/latest/download/uncloud_linux_amd64.tar.gz | tar xz
|
||||
mv uncloud uc
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="Linux (ARM 64-bit)">
|
||||
```shell
|
||||
curl -L https://github.com/psviderski/uncloud/releases/latest/download/uncloud_linux_arm64.tar.gz | tar xz
|
||||
mv uncloud uc
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You can use the `./uc` binary directly from the current directory, or move it to a directory in your system's `PATH`
|
||||
to run it as `uc` from any location.
|
||||
|
||||
For example, move it to `/usr/local/bin` which is a common location for user-installed binaries:
|
||||
|
||||
```shell
|
||||
sudo mv ./uc /usr/local/bin
|
||||
```
|
||||
|
||||
Follow the same steps to upgrade to the latest version in the future.
|
||||
|
||||
## Debian
|
||||
|
||||
On a Debian system, you can install Uncloud CLI from an unofficial
|
||||
[repository](https://debian.griffo.io/) maintained by
|
||||
[@dariogriffo](https://github.com/dariogriffo):
|
||||
|
||||
```shell
|
||||
curl -sS https://debian.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/debian.griffo.io.gpg
|
||||
echo "deb https://debian.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/debian.griffo.io.list
|
||||
apt install -y uncloud
|
||||
```
|
||||
|
||||
Alternatively, you can download `.deb` packages directly from the repository
|
||||
[releases](https://github.com/dariogriffo/uncloud-debian/releases) page.
|
||||
|
||||
## Verify installation
|
||||
|
||||
After installation, verify that `uc` command is working:
|
||||
|
||||
```shell
|
||||
uc --version
|
||||
```
|
||||
|
||||
## Next steps
|
||||
|
||||
Now that you have `uc` installed, you're ready to:
|
||||
|
||||
- [Deploy demo app](./2-deploy-demo-app.md)
|
||||
@@ -0,0 +1,323 @@
|
||||
# Deploy demo app
|
||||
|
||||
In this guide, we'll deploy [Excalidraw](https://excalidraw.com) — a popular sketching and diagramming tool — to your
|
||||
Linux server. You'll learn the **basics of Uncloud** and see how simple it is to **run web apps** on your own
|
||||
infrastructure with secure internet access.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, you'll need:
|
||||
|
||||
- **Uncloud CLI** [installed](1-install-cli.md) on your local machine
|
||||
- A **Ubuntu or Debian server** with **public IP address** and **SSH access** (as `root` or a user with `sudo`
|
||||
privileges) using a **private key**.
|
||||
|
||||
:::tip Need a server?
|
||||
|
||||
A small Virtual Private Server (VPS) or dedicated server from providers like [Hetzner](https://www.hetzner.com) or
|
||||
[DigitalOcean](https://www.digitalocean.com) is a great choice for learning Uncloud and running lightweight services. We
|
||||
recommend using a freshly installed server as existing services on ports 80 and 443 can cause conflicts.
|
||||
|
||||
**Minimum requirements:** 1 vCPU, 512 MB RAM, Ubuntu 22.04 or Debian 11, AMD64 (recommended) or ARM64 architecture.
|
||||
Other Linux distributions may work, but haven't been tested yet.
|
||||
|
||||
:::
|
||||
|
||||
## Set up your server
|
||||
|
||||
First, let's turn your server into an Uncloud **machine**. This simply means setting it up so you can deploy and manage
|
||||
services on it using `uc`.
|
||||
|
||||
```shell
|
||||
uc machine init root@<your-server-ip>
|
||||
```
|
||||
|
||||
If the SSH key to access your server isn't added to your [SSH agent](https://www.ssh.com/academy/ssh/agent), specify it
|
||||
with the `-i` flag:
|
||||
|
||||
```shell
|
||||
uc machine init root@<your-server-ip> -i ~/.ssh/id_xxx
|
||||
```
|
||||
|
||||
This command will:
|
||||
|
||||
- Install the latest stable Docker version on your server if it's not already installed
|
||||
- Install the Uncloud daemon on your server
|
||||
- Create a Docker network for Uncloud-managed containers
|
||||
- Deploy [Caddy](https://caddyserver.com/) as your reverse proxy listening on host ports 80 and 443
|
||||
- Reserve a free `xxxxxx.cluster.uncloud.run` subdomain via the Uncloud managed DNS service and point it to your
|
||||
server's IP
|
||||
|
||||
All in about a minute!
|
||||
|
||||
<details>
|
||||
<summary>💡 Expand to see example output</summary>
|
||||
|
||||
```
|
||||
$ uc machine init root@157.180.72.195
|
||||
Downloading Uncloud install script: https://raw.githubusercontent.com/psviderski/uncloud/refs/heads/main/scripts/install.sh
|
||||
⏳ Running Uncloud install script...
|
||||
⏳ Installing Docker...
|
||||
# Executing docker install script, commit: 53a22f61c0628e58e1d6680b49e82993d304b449
|
||||
+ sh -c apt-get -qq update >/dev/null
|
||||
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get -y -qq install ca-certificates curl >/dev/null
|
||||
+ sh -c install -m 0755 -d /etc/apt/keyrings
|
||||
+ sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" -o /etc/apt/keyrings/docker.asc
|
||||
+ sh -c chmod a+r /etc/apt/keyrings/docker.asc
|
||||
+ sh -c echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list
|
||||
+ sh -c apt-get -qq update >/dev/null
|
||||
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get -y -qq install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin >/dev/null
|
||||
|
||||
Running kernel seems to be up-to-date.
|
||||
|
||||
No services need to be restarted.
|
||||
|
||||
No containers need to be restarted.
|
||||
|
||||
No user sessions are running outdated binaries.
|
||||
|
||||
No VM guests are running outdated hypervisor (qemu) binaries on this host.
|
||||
+ sh -c docker version
|
||||
Client: Docker Engine - Community
|
||||
Version: 28.2.1
|
||||
API version: 1.50
|
||||
Go version: go1.24.3
|
||||
Git commit: 879ac3f
|
||||
Built: Wed May 28 19:25:01 2025
|
||||
OS/Arch: linux/amd64
|
||||
Context: default
|
||||
|
||||
Server: Docker Engine - Community
|
||||
Engine:
|
||||
Version: 28.2.1
|
||||
API version: 1.50 (minimum version 1.24)
|
||||
Go version: go1.24.3
|
||||
Git commit: 0e2cc22
|
||||
Built: Wed May 28 19:25:01 2025
|
||||
OS/Arch: linux/amd64
|
||||
Experimental: false
|
||||
containerd:
|
||||
Version: 1.7.27
|
||||
GitCommit: 05044ec0a9a75232cad458027ca83437aae3f4da
|
||||
runc:
|
||||
Version: 1.2.5
|
||||
GitCommit: v1.2.5-0-g59923ef
|
||||
docker-init:
|
||||
Version: 0.19.0
|
||||
GitCommit: de40ad0
|
||||
|
||||
================================================================================
|
||||
|
||||
To run Docker as a non-privileged user, consider setting up the
|
||||
Docker daemon in rootless mode for your user:
|
||||
|
||||
dockerd-rootless-setuptool.sh install
|
||||
|
||||
Visit https://docs.docker.com/go/rootless/ to learn about rootless mode.
|
||||
|
||||
|
||||
To run the Docker daemon as a fully privileged service, but granting non-root
|
||||
users access, refer to https://docs.docker.com/go/daemon-access/
|
||||
|
||||
WARNING: Access to the remote API on a privileged Docker daemon is equivalent
|
||||
to root access on the host. Refer to the 'Docker daemon attack surface'
|
||||
documentation for details: https://docs.docker.com/go/attack-surface/
|
||||
|
||||
================================================================================
|
||||
|
||||
✓ Docker installed successfully.
|
||||
✓ 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! 🎉
|
||||
Cluster initialised with machine 'machine-dc3c' and saved as context 'default' in your local config (/Users/spy/.config/uncloud/config.yaml)
|
||||
Current cluster context is now 'default'.
|
||||
Waiting for the machine to be ready...
|
||||
|
||||
Reserved cluster domain: 7za6s7.cluster.uncloud.run
|
||||
[+] Deploying service caddy 7/2
|
||||
✔ Container caddy-d7uk on machine-dc3c Started 6.1s
|
||||
✔ Image caddy:2.10.0 on machine-dc3c Pulled 3.7s
|
||||
|
||||
Updating cluster domain records in Uncloud DNS to point to machines running caddy service...
|
||||
[+] Verifying internet access to caddy service 1/1
|
||||
✔ Machine machine-dc3c (157.180.72.195) Reachable 0.7s
|
||||
|
||||
DNS records updated to use only the internet-reachable machines running caddy service:
|
||||
*.7za6s7.cluster.uncloud.run A → 157.180.72.195
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Deploy Excalidraw
|
||||
|
||||
Now that your machine is set up, let's deploy `excalidraw` service from the
|
||||
[official Docker image](https://hub.docker.com/r/excalidraw/excalidraw). The service will publish the container port 80
|
||||
as HTTPS endpoint on the previously reserved domain via Caddy.
|
||||
|
||||
```shell
|
||||
uc run --name excalidraw --publish 80/https excalidraw/excalidraw
|
||||
```
|
||||
|
||||
You'll see the progress of the deployment and the public URL where you can access the service:
|
||||
|
||||
```
|
||||
[+] Running service excalidraw (replicated mode) 2/2
|
||||
✔ Container excalidraw-azpc on machine-dc3c Started 8.9s
|
||||
✔ Image excalidraw/excalidraw on machine-dc3c Pulled 4.7s
|
||||
|
||||
excalidraw endpoints:
|
||||
• https://excalidraw.7za6s7.cluster.uncloud.run → :80
|
||||
```
|
||||
|
||||
## Verify your deployment
|
||||
|
||||
After the service is deployed, use the `uc inspect` command to check its status and details:
|
||||
|
||||
```shell
|
||||
uc inspect excalidraw
|
||||
```
|
||||
|
||||
```
|
||||
ID: 4d2de1600b6ada221a03896cd388836c
|
||||
Name: excalidraw
|
||||
Mode: replicated
|
||||
|
||||
CONTAINER ID IMAGE CREATED STATUS MACHINE
|
||||
fde7ac7f11ad excalidraw/excalidraw About a minute ago Up About a minute (healthy) machine-dc3c
|
||||
```
|
||||
|
||||
In this example, the service has one container running on the machine `machine-dc3c` (our server). The container is up
|
||||
and healthy.
|
||||
|
||||
You can also list all deployed services and their public endpoints using the `uc ls` command:
|
||||
|
||||
```shell
|
||||
uc ls
|
||||
```
|
||||
|
||||
```
|
||||
NAME MODE REPLICAS ENDPOINTS
|
||||
caddy global 1
|
||||
excalidraw replicated 1 https://excalidraw.7za6s7.cluster.uncloud.run → :80
|
||||
```
|
||||
|
||||
You can see `caddy` service listed here. That's your reverse proxy, running as a regular Uncloud service.
|
||||
|
||||
## It's live! Start drawing! ✨
|
||||
|
||||
Open your browser and navigate to the URL shown in the endpoints. It may take a moment for Caddy to obtain a TLS
|
||||
certificate from Let's Encrypt. If it doesn't load immediately, wait a few seconds and try again.
|
||||
|
||||

|
||||
|
||||
You now have:
|
||||
|
||||
- Your **own Excalidraw instance** running on your server
|
||||
- A **public URL** with **automatic HTTPS** you can share with your team and friends
|
||||
- **Full control over your data** — no analytics or tracking
|
||||
|
||||
## Convert to Docker Compose format
|
||||
|
||||
Uncloud supports the [Compose file format](https://docs.docker.com/reference/compose-file/) for defining services. This
|
||||
allows you to version control your deployments, share configurations with your team, and deploy complex multi-service
|
||||
applications with a single command.
|
||||
|
||||
Let's create a `compose.yaml` file in your current directory for the `excalidraw` service we just deployed.
|
||||
|
||||
```yaml title="compose.yaml"
|
||||
services:
|
||||
excalidraw:
|
||||
image: excalidraw/excalidraw
|
||||
x-ports:
|
||||
- 80/https
|
||||
```
|
||||
|
||||
:::info note
|
||||
|
||||
The `x-ports` key is an Uncloud-specific extension to the Compose file format. It allows you to specify ports that
|
||||
should be published as HTTP(S) endpoints. Uncloud automatically configures the reverse proxy (Caddy) to route traffic to
|
||||
these ports.
|
||||
|
||||
:::
|
||||
|
||||
Now deploy it:
|
||||
|
||||
```shell
|
||||
uc deploy
|
||||
```
|
||||
|
||||
```
|
||||
Services are up to date.
|
||||
```
|
||||
|
||||
Since `excalidraw` service is already running with the same configuration, Uncloud recognises there's nothing to change.
|
||||
We've successfully converted our deployment created with `uc run` to a Compose file.
|
||||
|
||||
## Use your own domain
|
||||
|
||||
Want to use your own domain, for example, `excalidraw.example.com` instead of `excalidraw.7za6s7.cluster.uncloud.run`?
|
||||
|
||||
Add a CNAME record `excalidraw.example.com` in your DNS provider (Cloudflare, Namecheap, etc.) pointing to
|
||||
`excalidraw.7za6s7.cluster.uncloud.run`. Alternatively, you can add an A record pointing to your server's IP.
|
||||
|
||||
:::info note
|
||||
|
||||
These instructions set up your own domain _in addition to_ uncloud's managed DNS service.
|
||||
|
||||
If you want to avoid the managed service altogether, add `--no-dns` to your `uc machine init` command, and point an `A`-type DNS record to your server(s)'s IP(s).
|
||||
|
||||
:::
|
||||
|
||||
Then update the published port `80/https` in `compose.yaml` to use your domain:
|
||||
|
||||
```yaml title="compose.yaml"
|
||||
...
|
||||
x-ports:
|
||||
- excalidraw.example.com:80/https
|
||||
```
|
||||
|
||||
Finally, deploy the changes:
|
||||
|
||||
```shell
|
||||
uc deploy
|
||||
```
|
||||
|
||||
```
|
||||
Deployment plan:
|
||||
- Deploy service [name=excalidraw]
|
||||
- machine-dc3c: Run container [image=excalidraw/excalidraw]
|
||||
- machine-dc3c: Remove container [name=excalidraw-azpc]
|
||||
|
||||
Do you want to continue?
|
||||
|
||||
Choose [y/N]: y
|
||||
Chose: Yes!
|
||||
|
||||
[+] Deploying services 2/2
|
||||
✔ Container excalidraw-0z12 on machine-dc3c Started 3.5s
|
||||
✔ Container excalidraw-azpc on machine-dc3c Removed 3.4s
|
||||
```
|
||||
|
||||
Notice how Uncloud performed a **zero-downtime deployment** — it started the new container with the updated
|
||||
configuration before removing the old one. Your service stayed available throughout the update.
|
||||
|
||||
Give it a moment for Caddy to obtain a TLS certificate, then visit https://excalidraw.example.com.
|
||||
|
||||
## Clean up
|
||||
|
||||
TBD
|
||||
|
||||
## Next steps
|
||||
|
||||
TBD
|
||||
@@ -0,0 +1,4 @@
|
||||
label: Getting started
|
||||
collapsed: false # keep the category open by default
|
||||
link:
|
||||
type: generated-index
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 389 KiB |
@@ -0,0 +1,166 @@
|
||||
// @ts-check
|
||||
// `@type` JSDoc annotations allow editor autocompletion and type checking
|
||||
// (when paired with `@ts-check`).
|
||||
// There are various equivalent ways to declare your Docusaurus config.
|
||||
// See: https://docusaurus.io/docs/api/docusaurus-config
|
||||
|
||||
import {themes as prismThemes} from 'prism-react-renderer';
|
||||
|
||||
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: 'Uncloud',
|
||||
tagline: 'Self-host and scale web apps without Kubernetes complexity',
|
||||
favicon: 'img/favicon.png',
|
||||
|
||||
// Set the production url of your site here
|
||||
url: 'https://uncloud.run',
|
||||
// Set the /<baseUrl>/ pathname under which your site is served
|
||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||
baseUrl: '/',
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: '', // Usually your GitHub org/user name.
|
||||
projectName: '', // Usually your repo name.
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
|
||||
// Even if you don't use internationalization, you can use this field to set
|
||||
// useful metadata like html lang. For example, if your site is Chinese, you
|
||||
// may want to replace "en" with "zh-Hans".
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
},
|
||||
|
||||
themes: [
|
||||
[
|
||||
'@easyops-cn/docusaurus-search-local',
|
||||
/** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */
|
||||
({
|
||||
docsRouteBasePath: '/',
|
||||
hashed: true,
|
||||
highlightSearchTermsOnTargetPage: true,
|
||||
}),
|
||||
],
|
||||
],
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
docs: {
|
||||
// Remove this to remove the "edit this page" links.
|
||||
editUrl: 'https://github.com/psviderski/uncloud/edit/main/website/',
|
||||
// Serve the docs at the site's root.
|
||||
// routeBasePath: '/',
|
||||
showLastUpdateTime: true,
|
||||
sidebarPath: './sidebars.js',
|
||||
},
|
||||
blog: false,
|
||||
// blog: {
|
||||
// showReadingTime: true,
|
||||
// feedOptions: {
|
||||
// type: ['rss', 'atom'],
|
||||
// xslt: true,
|
||||
// },
|
||||
// // Please change this to your repo.
|
||||
// // Remove this to remove the "edit this page" links.
|
||||
// // editUrl:
|
||||
// // 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/',
|
||||
// // Useful options to enforce blogging best practices
|
||||
// onInlineTags: 'warn',
|
||||
// onInlineAuthors: 'warn',
|
||||
// onUntruncatedBlogPosts: 'warn',
|
||||
// },
|
||||
theme: {
|
||||
customCss: './src/css/custom.css',
|
||||
},
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
colorMode: {
|
||||
// The color mode when user first visits the site.
|
||||
defaultMode: "light",
|
||||
// Whether to use the prefers-color-scheme media-query, using user system preferences,
|
||||
// instead of the hardcoded defaultMode.
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
// The meta image URL for the site (og:image and twitter:image meta tags).
|
||||
// Relative to your site's "static" directory. Cannot be SVGs. Can be external URLs too.
|
||||
image: 'img/social-card.png',
|
||||
navbar: {
|
||||
title: 'Uncloud',
|
||||
logo: {
|
||||
alt: 'Uncloud Logo',
|
||||
src: 'img/logo.svg',
|
||||
href: 'https://uncloud.run',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'overview',
|
||||
label: 'Docs',
|
||||
position: 'left',
|
||||
},
|
||||
// {
|
||||
// to: 'blog',
|
||||
// label: 'Blog',
|
||||
// position: 'left',
|
||||
// },
|
||||
{
|
||||
type: 'search',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/psviderski/uncloud',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'light',
|
||||
links: [
|
||||
{
|
||||
title: 'Uncloud',
|
||||
items: [
|
||||
{
|
||||
html: 'Made with ❤️ by <a href="https://github.com/psviderski">@psviderski</a> in Australia'
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{
|
||||
label: 'Discord',
|
||||
href: 'https://discord.gg/eR35KQJhPu',
|
||||
},
|
||||
{
|
||||
label: 'X',
|
||||
href: 'https://x.com/psviderski',
|
||||
},
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/psviderski/uncloud',
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.palenight,
|
||||
//darkTheme: prismThemes.dracula,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export default config;
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
(()=>{var Ye=!1,Ze=!1,V=[];function Ft(e){mn(e)}function mn(e){V.includes(e)||V.push(e),hn()}function xe(e){let t=V.indexOf(e);t!==-1&&V.splice(t,1)}function hn(){!Ze&&!Ye&&(Ye=!0,queueMicrotask(_n))}function _n(){Ye=!1,Ze=!0;for(let e=0;e<V.length;e++)V[e]();V.length=0,Ze=!1}var T,I,$,Qe,Xe=!0;function Bt(e){Xe=!1,e(),Xe=!0}function Kt(e){T=e.reactive,$=e.release,I=t=>e.effect(t,{scheduler:r=>{Xe?Ft(r):r()}}),Qe=e.raw}function et(e){I=e}function zt(e){let t=()=>{};return[n=>{let i=I(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}var Vt=[],Ht=[],qt=[];function Ut(e){qt.push(e)}function ye(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Ht.push(t))}function Wt(e){Vt.push(e)}function Gt(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function tt(e,t){!e._x_attributeCleanups||Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var nt=new MutationObserver(rt),it=!1;function ie(){nt.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),it=!0}function ot(){gn(),nt.disconnect(),it=!1}var oe=[],st=!1;function gn(){oe=oe.concat(nt.takeRecords()),oe.length&&!st&&(st=!0,queueMicrotask(()=>{xn(),st=!1}))}function xn(){rt(oe),oe.length=0}function h(e){if(!it)return e();ot();let t=e();return ie(),t}var at=!1,be=[];function Jt(){at=!0}function Yt(){at=!1,rt(be),be=[]}function rt(e){if(at){be=be.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;o<e.length;o++)if(!e[o].target._x_ignoreMutationObserver&&(e[o].type==="childList"&&(e[o].addedNodes.forEach(s=>s.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{tt(s,o)}),n.forEach((o,s)=>{Vt.forEach(a=>a(s,o))});for(let o of r)if(!t.includes(o)&&(Ht.forEach(s=>s(o)),o._x_cleanups))for(;o._x_cleanups.length;)o._x_cleanups.pop()();t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.includes(o)||!o.isConnected||(delete o._x_ignoreSelf,delete o._x_ignore,qt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function ve(e){return j(L(e))}function M(e,t,r){return e._x_dataStack=[t,...L(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function ct(e,t){let r=e._x_dataStack[0];Object.entries(t).forEach(([n,i])=>{r[n]=i})}function L(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?L(e.host):e.parentNode?L(e.parentNode):[]}function j(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function we(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Ee(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>yn(n,i),s=>lt(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function yn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function lt(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),lt(e[t[0]],t.slice(1),r)}}var Zt={};function y(e,t){Zt[e]=t}function se(e,t){return Object.entries(Zt).forEach(([r,n])=>{Object.defineProperty(e,`$${r}`,{get(){let[i,o]=ut(t);return i={interceptor:Ee,...i},ye(t,o),n(t,i)},enumerable:!1})}),e}function Qt(e,t,r,...n){try{return r(...n)}catch(i){Z(i,e,t)}}function Z(e,t,r=void 0){Object.assign(e,{el:t,expression:r}),console.warn(`Alpine Expression E
Line truncated
|
||||
|
||||
${r?'Expression: "'+r+`"
|
||||
|
||||
`:""}`,t),setTimeout(()=>{throw e},0)}var Se=!0;function Xt(e){let t=Se;Se=!1,e(),Se=t}function P(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return er(...e)}var er=ft;function tr(e){er=e}function ft(e,t){let r={};se(r,e);let n=[r,...L(e)];if(typeof t=="function")return bn(n,t);let i=vn(n,t,e);return Qt.bind(null,e,t,i)}function bn(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(j([n,...e]),i);Ae(r,o)}}var dt={};function wn(e,t){if(dt[e])return dt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(async()=>{ ${e} })()`:e,o=(()=>{try{return new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`)}catch(s){return Z(s,t,e),Promise.resolve()}})();return dt[e]=o,o}function vn(e,t,r){let n=wn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=j([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>Z(l,r,t));n.finished?(Ae(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ae(i,l,a,s,r)}).catch(l=>Z(l,r,t)).finally(()=>n.result=void 0)}}}function Ae(e,t,r,n,i){if(Se&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ae(e,s,r,n)).catch(s=>Z(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var pt="x-";function S(e=""){return pt+e}function rr(e){pt=e}var mt={};function p(e,t){return mt[e]=t,{before(r){if(!mt[r]){console.warn("Cannot find directive `${directive}`. `${name}` will use the default order of execution");return}let n=H.indexOf(r)??H.indexOf("DEFAULT");n>=0&&H.splice(n,0,e)}}}function ae(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=ht(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(nr((o,s)=>n[o]=s)).filter(ir).map(Sn(n,r)).sort(An).map(o=>En(e,o))}function ht(e){return Array.from(e).map(nr()).filter(t=>!ir(t))}var _t=!1,ce=new Map,or=Symbol();function sr(e){_t=!0;let t=Symbol();or=t,ce.set(t,[]);let r=()=>{for(;ce.get(t).length;)ce.get(t).shift()();ce.delete(t)},n=()=>{_t=!1,r()};e(r),n()}function ut(e){let t=[],r=a=>t.push(a),[n,i]=zt(e);return t.push(i),[{Alpine:F,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:P.bind(P,e)},()=>t.forEach(a=>a())]}function En(e,t){let r=()=>{},n=mt[t.type]||r,[i,o]=ut(e);Gt(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),_t?ce.get(or).push(n):n())};return s.runCleanups=o,s}var Oe=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Te=e=>e;function nr(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=ar.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var ar=[];function Q(e){ar.push(e)}function ir({name:e}){return cr().test(e)}var cr=()=>new RegExp(`^${pt}([^:^.]+)\\b`);function Sn(e,t){return({name:r,value:n})=>{let i=r.match(cr()),o=r.match(/:([a-zA-Z0-9\-:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var gt="DEFAULT",H=["ignore","ref","data","id","radio","tabs","switch","disclosure","menu","listbox","combobox","bind","init","for","mask","model","modelable","transition","show","if",gt,"teleport"];function An(e,t){let r=H.indexOf(e.type)===-1?gt:e.type,n=H.indexOf(t.type)===-1?gt:t.type;return H.indexOf(r)-H.indexOf(n)}function q(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function A(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>A(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)A(n,t,!1),n=n.nextElementSibling}function C(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}function ur(){document.body||C("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?"),q(document,"alpine:init"),q(document,"alpine:initializing"),ie(),Ut(t=>E(t,A)),ye(t=>xt(t)),Wt((t,r)=>{ae(t,r).forEach(n=>n())});let e=t=>!U(t.parentElement,!0);Array.from(document.querySelectorAll(lr())).filter(e).forEach(t=>{E(t)}),q(document,"alpine:initialized")}var yt=[],fr=[];function dr(){return yt.map(e=>e())}function lr(){return yt.concat(fr).map(e=>e())}function Ce(e){yt.push(e)}function Re(e){fr.push(e)}function U(e,t=!1){return X(e,r=>{if((t?lr():dr()).some(i=>r.matches(i)))return!0})}function X(e,t){if(!!e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),!!e.parentElement)return X(e.parentElement,t)}}function pr(e){return dr().some(t=>e.matches(t))}var mr=[];function hr(e){mr.push(e)}function E(e,t=A,r=()=>{}){sr(()=>{t(e,(n,i)=>{r(n,i),mr.forEach(o=>o(n,i)),ae(n,n.attributes).forEach(o=>o()),n._x_ignore&&i()})})}function xt(e){A(e,t=>tt(t))}vLine truncated
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -32,6 +32,13 @@
|
||||
content="Take your Docker Compose apps to production with zero-downtime deployments, automatic HTTPS, and cross-machine scaling. Self-hosting made reliable without the complexity.">
|
||||
<meta name="twitter:image" content="https://uncloud.run/images/logo-wide.png">
|
||||
<meta name="twitter:image:alt" content="Uncloud logo - Self-host web apps with ease">
|
||||
<style>
|
||||
/* Prevent all inline SVGs from appearing full screen */
|
||||
svg {
|
||||
max-width: 24px;
|
||||
max-height: 24px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="font-inter antialiased bg-white text-zinc-900 tracking-tight">
|
||||
@@ -45,8 +52,9 @@
|
||||
<div class="flex items-center justify-between h-14">
|
||||
<!-- Site branding -->
|
||||
<div class="shrink-0 mr-4">
|
||||
<a class="flex items-center" href="index.html">
|
||||
<img class="w-8 h-8 rounded shadow-sm shadow-zinc-950/20" src="./images/logo.svg" alt="Logo">
|
||||
<a class="flex items-center" href="/">
|
||||
<img class="w-8 h-8 rounded shadow-sm shadow-zinc-950/20" src="./images/logo.svg" alt="Logo"
|
||||
width="32" height="32">
|
||||
<span class="ml-2 font-semibold text-lg text-zinc-900">uncloud</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -56,7 +64,7 @@
|
||||
<ul class="flex grow justify-end flex-wrap items-center">
|
||||
<li>
|
||||
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-3 lg:px-5 py-2 flex items-center transition"
|
||||
href="https://docs.uncloud.run">
|
||||
href="/docs">
|
||||
<svg class="w-4 h-4 mr-1 fill-current hidden sm:inline"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24">
|
||||
@@ -713,11 +721,11 @@
|
||||
<ul class="text-sm space-y-2">
|
||||
<li>
|
||||
<a class="text-zinc-500 hover:text-zinc-900 transition"
|
||||
href="https://docs.uncloud.run/#use-cases">Use cases</a>
|
||||
href="/docs/#use-cases">Use cases</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="text-zinc-500 hover:text-zinc-900 transition"
|
||||
href="https://docs.uncloud.run/getting-started/quick-start">Quick start</a>
|
||||
href="/docs/getting-started/deploy-demo-app">Quick start</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
Generated
+1031
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "gray-html",
|
||||
"description": "Gray HTML template - Cruip.com",
|
||||
"version": "1.0.0",
|
||||
"homepage": "https://cruip.com",
|
||||
"author": "Pasquale Vitiello",
|
||||
"license": "https://cruip.com/terms/",
|
||||
"scripts": {
|
||||
"dev": "npx tailwindcss -i ./css/style.css -o ./style.css --watch",
|
||||
"build": "npx tailwindcss -i ./css/style.css -o ./style.css"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"tailwindcss": "^3.3.6"
|
||||
}
|
||||
}
|
||||
@@ -41,10 +41,8 @@ html {
|
||||
/* 1 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
/* 2 */
|
||||
-moz-tab-size: 4;
|
||||
/* 3 */
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
tab-size: 4;
|
||||
/* 3 */
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
/* 4 */
|
||||
@@ -374,13 +372,6 @@ textarea {
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1;
|
||||
@@ -443,9 +434,7 @@ video {
|
||||
}
|
||||
|
||||
[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select{
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
background-color: #fff;
|
||||
border-color: #6b7280;
|
||||
border-width: 1px;
|
||||
@@ -472,11 +461,6 @@ video {
|
||||
border-color: #2563eb;
|
||||
}
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder{
|
||||
color: #6b7280;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input::placeholder,textarea::placeholder{
|
||||
color: #6b7280;
|
||||
opacity: 1;
|
||||
@@ -521,9 +505,7 @@ select{
|
||||
}
|
||||
|
||||
[type='checkbox'],[type='radio']{
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
padding: 0;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
@@ -531,7 +513,6 @@ select{
|
||||
vertical-align: middle;
|
||||
background-origin: border-box;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
flex-shrink: 0;
|
||||
height: 1rem;
|
||||
@@ -577,9 +558,7 @@ select{
|
||||
|
||||
@media (forced-colors: active) {
|
||||
[type='checkbox']:checked{
|
||||
-webkit-appearance: auto;
|
||||
-moz-appearance: auto;
|
||||
appearance: auto;
|
||||
appearance: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,9 +568,7 @@ select{
|
||||
|
||||
@media (forced-colors: active) {
|
||||
[type='radio']:checked{
|
||||
-webkit-appearance: auto;
|
||||
-moz-appearance: auto;
|
||||
appearance: auto;
|
||||
appearance: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,9 +588,7 @@ select{
|
||||
|
||||
@media (forced-colors: active) {
|
||||
[type='checkbox']:indeterminate{
|
||||
-webkit-appearance: auto;
|
||||
-moz-appearance: auto;
|
||||
appearance: auto;
|
||||
appearance: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,9 +747,7 @@ select{
|
||||
}
|
||||
|
||||
.form-input,.form-textarea,.form-select,.form-multiselect{
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
background-color: #fff;
|
||||
border-color: #6b7280;
|
||||
border-width: 1px;
|
||||
@@ -801,11 +774,6 @@ select{
|
||||
border-color: #2563eb;
|
||||
}
|
||||
|
||||
.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{
|
||||
color: #6b7280;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.form-input::placeholder,.form-textarea::placeholder{
|
||||
color: #6b7280;
|
||||
opacity: 1;
|
||||
@@ -850,9 +818,7 @@ select{
|
||||
}
|
||||
|
||||
.form-checkbox,.form-radio{
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
padding: 0;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
@@ -860,7 +826,6 @@ select{
|
||||
vertical-align: middle;
|
||||
background-origin: border-box;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
flex-shrink: 0;
|
||||
height: 1rem;
|
||||
@@ -906,9 +871,7 @@ select{
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.form-checkbox:checked{
|
||||
-webkit-appearance: auto;
|
||||
-moz-appearance: auto;
|
||||
appearance: auto;
|
||||
appearance: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -918,9 +881,7 @@ select{
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.form-radio:checked{
|
||||
-webkit-appearance: auto;
|
||||
-moz-appearance: auto;
|
||||
appearance: auto;
|
||||
appearance: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,9 +901,7 @@ select{
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.form-checkbox:indeterminate{
|
||||
-webkit-appearance: auto;
|
||||
-moz-appearance: auto;
|
||||
appearance: auto;
|
||||
appearance: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1097,11 +1056,6 @@ input[type="search"]::-webkit-search-results-decoration {
|
||||
color: rgb(82 82 91 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.form-input::-moz-placeholder, .form-textarea::-moz-placeholder{
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(161 161 170 / var(--tw-placeholder-opacity));
|
||||
}
|
||||
|
||||
.form-input::placeholder,
|
||||
.form-textarea::placeholder{
|
||||
--tw-placeholder-opacity: 1;
|
||||
@@ -1185,14 +1139,6 @@ input[type="search"]::-webkit-search-results-decoration {
|
||||
transition: y 0.1s ease-out, transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), width 0.1s ease-out;
|
||||
}
|
||||
|
||||
.visible{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.collapse{
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
.absolute{
|
||||
position: absolute;
|
||||
}
|
||||
@@ -1418,13 +1364,8 @@ input[type="search"]::-webkit-search-results-decoration {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.transform{
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.select-none{
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
File renamed without changes.
@@ -1,151 +0,0 @@
|
||||
Output demo.mp4
|
||||
|
||||
Set Shell "bash"
|
||||
Set FontSize 15
|
||||
Set FontFamily "SauceCodePro Nerd Font"
|
||||
Set Width 1200
|
||||
Set Height 700
|
||||
Set WindowBar Colorful
|
||||
Set Theme "Solarized Dark Higher Contrast"
|
||||
Set Padding 20
|
||||
|
||||
Type "# 🚀 Uncloud demo: Docker simplicity with multi-machine power"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "# Let's deploy a highly available web app with automatic HTTPS in just a couple minutes"
|
||||
Enter
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "# First, let's initialise our first machine using a free Oracle Cloud VM"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "uc machine init --name oracle-vm ubuntu@152.67.101.197"
|
||||
Sleep 1s
|
||||
Enter
|
||||
# This takes time, so we wait for it to complete.
|
||||
Wait@1m
|
||||
Sleep 3s
|
||||
|
||||
Enter
|
||||
Type "# Let's see our machine in the cluster"
|
||||
Enter
|
||||
Type "uc machine ls"
|
||||
Enter
|
||||
Wait
|
||||
Sleep 3s
|
||||
|
||||
Ctrl+L
|
||||
|
||||
Type "# Now let's deploy a simple web app with automatic HTTPS called myapp"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "uc run -n myapp -p myapp.psviderski.name:80/https traefik/whoami"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 2s
|
||||
|
||||
Enter
|
||||
Type "# The -p flag publishes the container port 80 as HTTPS via reverse proxy Caddy using the provided domain"
|
||||
Enter
|
||||
Type "# Let's check it out! First using the auto-generated uncloud domain"
|
||||
Enter
|
||||
Sleep 1s
|
||||
|
||||
Hide
|
||||
Sleep 5s
|
||||
Show
|
||||
|
||||
Type "curl https://myapp.xuw3xd.cluster.uncloud.run"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 2s
|
||||
|
||||
Enter
|
||||
Type "# For the provided domain to work, we need to manually add a DNS record pointing to the machine IP"
|
||||
Enter
|
||||
Type "# To simplify IP management, I added a CNAME record: myapp.psviderski.name -> myapp.xuw3xd.cluster.uncloud.run"
|
||||
Enter
|
||||
Sleep 2s
|
||||
Type "curl https://myapp.psviderski.name"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 1s
|
||||
|
||||
Enter
|
||||
Type "# Sweet!"
|
||||
Enter
|
||||
Sleep 2s
|
||||
|
||||
Ctrl+L
|
||||
|
||||
Type "# Let's add redundancy by adding another machine, a Hetzner server in a different region"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "uc machine add --name hetzner-server root@5.223.45.199"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait@1m
|
||||
Sleep 3s
|
||||
|
||||
Enter
|
||||
Type "# Now the cool part - let's add a powerful server from my home network to the same cluster"
|
||||
Enter
|
||||
Type "# Uncloud lets you mix cloud VMs with your own hardware to save costs on resource-intensive workloads"
|
||||
Enter
|
||||
Sleep 2s
|
||||
Type "uc machine add --name home-server --public-ip none spy@192.168.40.243"
|
||||
Sleep 2s
|
||||
Enter
|
||||
Wait@1m
|
||||
Sleep 3s
|
||||
|
||||
Enter
|
||||
Type "# Let's see our hybrid cluster spanning cloud providers and home network"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "uc machine ls"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 3s
|
||||
|
||||
Ctrl+L
|
||||
|
||||
Type "# Time to scale our service across all machines"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "uc scale myapp 3"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 1s
|
||||
|
||||
Enter
|
||||
Type "uc inspect myapp"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 2s
|
||||
|
||||
Enter
|
||||
Type "# Let's see load balancing in action"
|
||||
Enter
|
||||
Sleep 1s
|
||||
Type "for i in {1..5}; do curl -s https://myapp.psviderski.name | grep Hostname; done"
|
||||
Sleep 1s
|
||||
Enter
|
||||
Wait
|
||||
Sleep 3s
|
||||
|
||||
Ctrl+L
|
||||
|
||||
Type "# ✨ And that's it! We've deployed a highly available web app across providers in just a couple minutes"
|
||||
Enter
|
||||
Type "# Your service stays up even if the home server and any cloud machine go down"
|
||||
Enter
|
||||
Type "# No master nodes to maintain, no complex cluster setup. Try Uncloud today! 🚀"
|
||||
Enter
|
||||
Sleep 1s
|
||||
@@ -1,138 +0,0 @@
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0" version="26.0.6">
|
||||
<diagram id="l8hXMBHkgcEJcSW0mbfh" name="Page-1">
|
||||
<mxGraphModel dx="2522" dy="1435" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;curved=1;startArrow=classic;startFill=1;strokeColor=#871619;strokeWidth=2;" edge="1" parent="1" source="anjOE1Lszn3xuFwhIM3--15" target="anjOE1Lszn3xuFwhIM3--47">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--15" value="" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=1;glass=0;shadow=0;sketch=1;curveFitting=1;jiggle=2;strokeColor=#71717A;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="110" width="200" height="230" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--16" value="<font face="Indie Flower">Virtual machine</font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="73" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--30" value="" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;strokeWidth=1;strokeColor=#71717A;" vertex="1" parent="1">
|
||||
<mxGeometry x="540" y="110" width="200" height="270" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--31" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=https://cdn.worldvectorlogo.com/logos/digitalocean-2.svg;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="40" width="177.34" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--32" value="<font face="Indie Flower">Dedicated server<br></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="540" y="73" width="170" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--35" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Logo_Hetzner.svg/512px-Logo_Hetzner.svg.png;" vertex="1" parent="1">
|
||||
<mxGeometry x="540" y="43.5" width="186.92" height="23" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--36" value="<div><font face="Indie Flower" style="font-size: 22px;"><b>Office / Homelab</b></font></div><div><font face="Indie Flower">Mac mini / PC<br></font></div>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="500" y="555" width="170" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--37" value="$ <font face="JetBrains Mono" data-font-src="https://fonts.googleapis.com/css?family=JetBrains+Mono">uc CLI<br></font>" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;strokeWidth=1;fontColor=#FFFFFF;fillColor=#27272A;fillStyle=solid;fontSize=16;" vertex="1" parent="1">
|
||||
<mxGeometry x="42" y="470" width="120" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--50" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;curved=1;startArrow=classic;startFill=1;strokeColor=#871619;strokeWidth=2;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="anjOE1Lszn3xuFwhIM3--47" target="anjOE1Lszn3xuFwhIM3--30">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--47" value="" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;strokeWidth=1;strokeColor=#71717A;" vertex="1" parent="1">
|
||||
<mxGeometry x="290" y="300" width="200" height="290" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--52" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=https://cdn.icon-icons.com/icons2/2699/PNG/512/wireguard_logo_icon_167956.png;" vertex="1" parent="1">
|
||||
<mxGeometry x="324" y="163" width="148" height="74" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--53" value="<font face="Indie Flower">Private network<br></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="338" y="230" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--74" value="https://app.example.com" style="text;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=18;fontStyle=1;html=1;fontFamily=Indie Flower;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DIndie%2BFlower;spacing=2;spacingTop=0;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="295.89" y="80" width="194.23" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--76" value="" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=1;dashed=1;shadow=0;glass=0;strokeColor=#71717A;" vertex="1" parent="1">
|
||||
<mxGeometry x="52.11" y="122" width="175.77" height="138" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--78" value="containers" style="shape=image;verticalLabelPosition=middle;labelBackgroundColor=default;verticalAlign=middle;aspect=fixed;imageAspect=0;image=https://static-00.iconduck.com/assets.00/docker-icon-1024x739-rivf80b4.png;labelPosition=right;align=left;fontFamily=Indie Flower;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DIndie%2BFlower;fontSize=16;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="84.99999999999994" y="127.55000000000001" width="34" height="24.55" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--79" value="<font face="Indie Flower">app</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;sketch=1;curveFitting=1;jiggle=2;fillColor=#e1d5e7;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;strokeColor=#9673a6;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="74.99999999999994" y="210" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--80" value="<font face="Indie Flower">caddy</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;fillColor=#d5e8d4;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;sketch=1;curveFitting=1;jiggle=2;strokeColor=#82b366;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="74.99999999999994" y="170" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--83" value="<font face="Indie Flower">uncloud daemon<br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=cross-hatch;sketch=1;curveFitting=1;jiggle=2;fillColor=#D6D6D6;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;strokeColor=#27272A;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="328" y="545" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--92" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;exitX=0.407;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#18181B;" edge="1" parent="1" source="anjOE1Lszn3xuFwhIM3--74" target="anjOE1Lszn3xuFwhIM3--80">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--69" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;curved=1;sketch=1;curveFitting=1;jiggle=2;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#18181B;" edge="1" parent="1" source="anjOE1Lszn3xuFwhIM3--37" target="anjOE1Lszn3xuFwhIM3--83">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="150.0000000000001" y="560.03" as="sourcePoint" />
|
||||
<mxPoint x="316.12" y="606" as="targetPoint" />
|
||||
<Array as="points" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--94" value="<div>Control the cluster and services</div><div>through the closest machine</div>" style="edgeLabel;html=1;align=left;verticalAlign=middle;resizable=0;points=[];fontFamily=Indie Flower;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DIndie%2BFlower;fontSize=16;fontColor=#18181B;" vertex="1" connectable="0" parent="anjOE1Lszn3xuFwhIM3--69">
|
||||
<mxGeometry x="0.312" y="-2" relative="1" as="geometry">
|
||||
<mxPoint x="-212" y="8" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--114" value="<div><font face="Indie Flower" data-font-src="https://fonts.googleapis.com/css?family=Indie+Flower">RPC over SSH</font></div>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];labelBackgroundColor=none;rotation=13;fontSize=14;fontColor=#18181B;" vertex="1" connectable="0" parent="anjOE1Lszn3xuFwhIM3--69">
|
||||
<mxGeometry x="-0.0843" y="-4" relative="1" as="geometry">
|
||||
<mxPoint x="-11" y="-20" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--97" value="" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=1;dashed=1;shadow=0;glass=0;strokeColor=#71717A;" vertex="1" parent="1">
|
||||
<mxGeometry x="552.69" y="122" width="175.77" height="178" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--98" value="containers" style="shape=image;verticalLabelPosition=middle;labelBackgroundColor=default;verticalAlign=middle;aspect=fixed;imageAspect=0;image=https://static-00.iconduck.com/assets.00/docker-icon-1024x739-rivf80b4.png;labelPosition=right;align=left;fontFamily=Indie Flower;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DIndie%2BFlower;fontSize=16;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="585.5799999999999" y="129.55" width="34" height="24.55" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--99" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.01;entryY=0.422;entryDx=0;entryDy=0;curved=1;startArrow=classic;startFill=1;strokeColor=#871619;strokeWidth=2;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryPerimeter=0;" edge="1" parent="1" source="anjOE1Lszn3xuFwhIM3--15" target="anjOE1Lszn3xuFwhIM3--30">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="323.75" y="183" as="sourcePoint" />
|
||||
<mxPoint x="473.75" y="307" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--102" value="<font face="Indie Flower">uncloud daemon<br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=cross-hatch;sketch=1;curveFitting=1;jiggle=2;fillColor=#D6D6D6;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;strokeColor=#27272A;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="575" y="330" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--103" value="<font face="Indie Flower">uncloud daemon<br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=cross-hatch;sketch=1;curveFitting=1;jiggle=2;fillColor=#D6D6D6;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;strokeColor=#27272A;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="75" y="290" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--104" value="<font face="Indie Flower">caddy</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;fillColor=#d5e8d4;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;sketch=1;curveFitting=1;jiggle=2;strokeColor=#82b366;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="574.9999999999999" y="170" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--105" value="<font face="Indie Flower">app</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;sketch=1;curveFitting=1;jiggle=2;fillColor=#e1d5e7;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;strokeColor=#9673a6;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="575" y="210" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--106" value="<font face="Indie Flower">app-db</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;sketch=1;curveFitting=1;jiggle=2;fillColor=#e1d5e7;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;strokeColor=#9673a6;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="575" y="250" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--107" value="" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=1;dashed=1;shadow=0;glass=0;strokeColor=#71717A;" vertex="1" parent="1">
|
||||
<mxGeometry x="302.12" y="312" width="175.77" height="218" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--108" value="containers" style="shape=image;verticalLabelPosition=middle;labelBackgroundColor=default;verticalAlign=middle;aspect=fixed;imageAspect=0;image=https://static-00.iconduck.com/assets.00/docker-icon-1024x739-rivf80b4.png;labelPosition=right;align=left;fontFamily=Indie Flower;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DIndie%2BFlower;fontSize=16;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="335.00999999999993" y="319.55" width="34" height="24.55" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--109" value="<font face="Indie Flower">caddy</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;fillColor=#d5e8d4;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;sketch=1;curveFitting=1;jiggle=2;strokeColor=#82b366;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="324.4299999999999" y="360" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--110" value="<font face="Indie Flower">app-staging</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;sketch=1;curveFitting=1;jiggle=2;fillColor=#ffe6cc;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;strokeColor=#d79b00;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="324.43" y="400" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--111" value="<font face="Indie Flower">app-db-staging</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;sketch=1;curveFitting=1;jiggle=2;fillColor=#ffe6cc;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;strokeColor=#d79b00;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="324.43" y="440" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--112" value="<font face="Indie Flower">monitoring stack<br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=1;fillStyle=hachure;sketch=1;curveFitting=1;jiggle=2;fillColor=#dae8fc;labelBackgroundColor=none;labelBorderColor=none;textShadow=0;fontSize=14;align=center;verticalAlign=middle;strokeColor=#6c8ebf;fontColor=#18181B;" vertex="1" parent="1">
|
||||
<mxGeometry x="325" y="480" width="130" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="anjOE1Lszn3xuFwhIM3--93" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;sketch=1;curveFitting=1;jiggle=2;exitX=0.608;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;strokeColor=#18181B;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="anjOE1Lszn3xuFwhIM3--74" target="anjOE1Lszn3xuFwhIM3--104">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="481" y="200" as="sourcePoint" />
|
||||
<mxPoint x="470" y="170" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
Generated
+17881
-448
File diff suppressed because it is too large.
Load diff
+39
-10
@@ -1,16 +1,45 @@
|
||||
{
|
||||
"name": "gray-html",
|
||||
"description": "Gray HTML template - Cruip.com",
|
||||
"version": "1.0.0",
|
||||
"homepage": "https://cruip.com",
|
||||
"author": "Pasquale Vitiello",
|
||||
"license": "https://cruip.com/terms/",
|
||||
"name": "docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npx tailwindcss -i ./css/style.css -o ./style.css --watch",
|
||||
"build": "npx tailwindcss -i ./css/style.css -o ./style.css"
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.7.0",
|
||||
"@docusaurus/preset-classic": "3.7.0",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.49.2",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"tailwindcss": "^3.3.6"
|
||||
"@docusaurus/module-type-aliases": "3.7.0",
|
||||
"@docusaurus/types": "3.7.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 3 chrome version",
|
||||
"last 3 firefox version",
|
||||
"last 5 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// @ts-check
|
||||
|
||||
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
|
||||
|
||||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
|
||||
@type {import('@docusaurus/plugin-content-docs').SidebarsConfig}
|
||||
*/
|
||||
const sidebars = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
sidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
|
||||
// But you can create a sidebar manually
|
||||
/*
|
||||
tutorialSidebar: [
|
||||
'intro',
|
||||
'hello',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorial',
|
||||
items: ['tutorial-basics/create-a-document'],
|
||||
},
|
||||
],
|
||||
*/
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap');
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-font-family-base: 'Inter', sans-serif;
|
||||
--ifm-heading-font-family: 'Inter', sans-serif;
|
||||
|
||||
--ifm-color-primary: #006be6;
|
||||
--ifm-color-primary-dark: #0060cf;
|
||||
--ifm-color-primary-darker: #005bc4;
|
||||
--ifm-color-primary-darkest: #004ba1;
|
||||
--ifm-color-primary-light: #0076fd;
|
||||
--ifm-color-primary-lighter: #0a7cff;
|
||||
--ifm-color-primary-lightest: #2c8eff;
|
||||
--ifm-code-font-size: 95%;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* For readability concerns, you should choose a lighter palette in dark mode. */
|
||||
[data-theme='dark'] {
|
||||
--ifm-color-primary: #3391ee;
|
||||
--ifm-color-primary-dark: #1883ec;
|
||||
--ifm-color-primary-darker: #137be3;
|
||||
--ifm-color-primary-darkest: #1066bb;
|
||||
--ifm-color-primary-light: #4e9ff0;
|
||||
--ifm-color-primary-lighter: #5ba7f1;
|
||||
--ifm-color-primary-lightest: #83bcf5;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.menu {
|
||||
font-size: 0.875rem;
|
||||
font-weight: var(--ifm-font-weight-normal);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import Layout from '@theme/Layout';
|
||||
|
||||
export default function Hello() {
|
||||
return (
|
||||
<Layout>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
// Import the original mapper
|
||||
import MDXComponents from '@theme-original/MDXComponents';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
export default {
|
||||
// Re-use the default mapping
|
||||
...MDXComponents,
|
||||
// Global import the <Tabs> and <TabItem> components
|
||||
Tabs,
|
||||
TabItem,
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
|
||||
<g>
|
||||
<rect x="0" y="0" width="80" height="80" rx="10" fill="#18181B"/>
|
||||
<path d="M20 32 L20 48 L36 48 L36 32 M60 32 L45 32 L45 48 L60 48" stroke="white" stroke-width="6" fill="none"
|
||||
stroke-linecap="square" stroke-linejoin="miter"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 341 B |
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
Reference in new issue
Block a user