mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 08:45:38 +02:00
✨ feat: Host a relay on Hetzner (#114)
We are hosting a [MoQ](https://quic.video) relay on a remote (bare metal) server on Hetzner With a lot of help from @victorpahuus
This commit is contained in:
87
infra/RELAY.md
Normal file
87
infra/RELAY.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# How to Deploy Your Own MoQ Relay on a Server
|
||||
|
||||
This guide will walk you through the steps to deploy your own MoQ relay on a server.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Server Requirements:**
|
||||
- Ensure port 443 is open for both TCP and UDP (`:443/udp & :443/tcp`).
|
||||
- The server should have a minimum of **4GB RAM** and **2 vCPUs**.
|
||||
- Supports ARM or AMD64 architecture.
|
||||
|
||||
2. **Software Requirements:**
|
||||
- Docker and `docker-compose` must be installed on the server. You can use [this installation script](https://github.com/docker/docker-install) for Docker.
|
||||
- Git must be installed to clone the necessary repository.
|
||||
|
||||
3. **Certificates:**
|
||||
- You will need private and public certificates. It is recommended to use certificates from a trusted CA rather than self-signed certificates.
|
||||
|
||||
## Installation Steps
|
||||
|
||||
### Step 1: Clone the Repository
|
||||
|
||||
Clone the `kixelated/moq-rs` repository to your local machine:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kixelated/moq-rs moq
|
||||
```
|
||||
|
||||
### Step 2: Verify Port Availability
|
||||
|
||||
Check if port 443 is already in use on your server:
|
||||
|
||||
```bash
|
||||
sudo netstat -tulpn | grep ':443' | grep LISTEN
|
||||
```
|
||||
or
|
||||
```bash
|
||||
sudo lsof -i -P -n | grep LISTEN | grep 443
|
||||
```
|
||||
|
||||
If you find any processes using port 443, consider terminating them.
|
||||
|
||||
### Step 3: Configure Ports
|
||||
|
||||
Navigate to the cloned directory and edit the Docker compose file to use port 443:
|
||||
|
||||
```bash
|
||||
cd moq
|
||||
vim docker-compose.yml
|
||||
```
|
||||
|
||||
Change the ports section from lines 34 to 35 to:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
```
|
||||
|
||||
### Step 4: Prepare Certificates
|
||||
|
||||
Copy your generated certificates into the `moq/dev` directory and rename them:
|
||||
|
||||
```bash
|
||||
cp cert.pem moq/dev/localhost.crt
|
||||
cp key.pem moq/dev/localhost.key
|
||||
```
|
||||
|
||||
### Step 5: Start Docker Instances
|
||||
|
||||
Ensure you are in the root directory of the `moq` project, then start the Docker containers:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### Step 6: Link Domain to Server IP
|
||||
|
||||
Configure your DNS settings to connect your server's IP address to your domain:
|
||||
|
||||
```
|
||||
Record Type: A
|
||||
Subdomain: relay.fst.so
|
||||
IP Address: xx.xxx.xx.xxx
|
||||
```
|
||||
|
||||
Congratulations, your MoQ server is now set up! You can verify its functionality by using the [MoQ Checker](https://nestri.pages.dev/moq/checker).
|
||||
@@ -1,9 +1,9 @@
|
||||
export const domain =
|
||||
{
|
||||
production: "fst.so",
|
||||
dev: "dev.fst.so",
|
||||
}[$app.stage] || $app.stage + ".dev.fst.so";
|
||||
// export const domain =
|
||||
// {
|
||||
// production: "fst.so",
|
||||
// dev: "dev.fst.so",
|
||||
// }[$app.stage] || $app.stage + ".dev.fst.so";
|
||||
|
||||
export const zone = cloudflare.getZoneOutput({
|
||||
name: "fst.so",
|
||||
});
|
||||
// export const zone = cloudflare.getZoneOutput({
|
||||
// name: "fst.so",
|
||||
// });
|
||||
@@ -1,38 +0,0 @@
|
||||
import { isPermanentStage } from "./stage";
|
||||
|
||||
if (isPermanentStage) {
|
||||
const github = new aws.iam.OpenIdConnectProvider("GithubProvider", {
|
||||
url: "https://token.actions.githubusercontent.com",
|
||||
clientIdLists: ["sts.amazonaws.com"],
|
||||
thumbprintLists: [
|
||||
"6938fd4d98bab03faadb97b34396831e3780aea1",
|
||||
"1c58a3a8518e8759bf075b76b750d4f2df264fcd",
|
||||
],
|
||||
});
|
||||
|
||||
const githubRole = new aws.iam.Role("GithubRole", {
|
||||
name: [$app.name, $app.stage, "github"].join("-"),
|
||||
assumeRolePolicy: {
|
||||
Version: "2012-10-17",
|
||||
Statement: [
|
||||
{
|
||||
Effect: "Allow",
|
||||
Principal: {
|
||||
Federated: github.arn,
|
||||
},
|
||||
Action: "sts:AssumeRoleWithWebIdentity",
|
||||
Condition: {
|
||||
StringLike: github.url.apply((url) => ({
|
||||
[`${url}:sub`]: "repo:nestriness/nestri:*",
|
||||
})),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
new aws.iam.RolePolicyAttachment("GithubRolePolicy", {
|
||||
policyArn: "arn:aws:iam::aws:policy/AdministratorAccess",
|
||||
role: githubRole.name,
|
||||
});
|
||||
}
|
||||
22
infra/relay.ts
Normal file
22
infra/relay.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { resolve as pathResolve } from "node:path";
|
||||
import { readFileSync as readFile } from "node:fs";
|
||||
//Copy your (known) ssh public key to the remote machine
|
||||
//ssh-copy-id "-p $port" user@host
|
||||
|
||||
const domain = "fst.so"
|
||||
const ips = ["95.216.29.238"]
|
||||
|
||||
// Get the hosted zone
|
||||
const zone = aws.route53.getZone({ name: domain });
|
||||
|
||||
// Create an A record
|
||||
const record = new aws.route53.Record("Relay DNS Records", {
|
||||
zoneId: zone.then(zone => zone.zoneId),
|
||||
type: "A",
|
||||
name: `relay.${domain}`,
|
||||
ttl: 300,
|
||||
records: ips,
|
||||
});
|
||||
|
||||
// Export the URL
|
||||
export const url = $interpolate`https://${record.name}`;
|
||||
Reference in New Issue
Block a user