feat(rust): automated deployment to fly.io (#91)

* Automated deployment to fly.io

* Automatically connect to boostrap node

* Allow specifying addresses to connect to on startup

* Make logs a bit prettier

* Fmt
This commit is contained in:
Thomas Eizinger
2023-10-04 22:22:15 +11:00
committed by GitHub
parent bcb8df7265
commit 2e80cf5bba
6 changed files with 95 additions and 38 deletions

17
.github/workflows/deploy-rust-peer.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
on:
push:
branches:
- "main"
jobs:
deploy_to_fly_io:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./rust-peer
steps:
- uses: actions/checkout@v3
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

View File

@@ -64,39 +64,21 @@ npm run dev
## Getting started: Rust
### 1. Start your own Rust peer
If you are the first peer in the network, simply run:
```
cd rust-peer
cargo run
```
However, for this repo, we have a rust server already running in the cloud, and you can add your own Rust server peer to the chat network with `cargo run` from the `rust-peer` directory.
This will automatically connect you to the bootstrap node running on [fly.io](https://fly.io).
To connect your rust peer to the rest of the network, you need to add the remote multiaddress of any peer already running as a the command line argument.
Below we have added our already running Rust peer as the arg `remote-address`:
To explore more advanced configurations if you e.g. want to set up our own network, try:
```
cd rust-peer
cargo run -- --remote-address=/ip4/18.195.246.16/udp/9091/quic-v1/p2p/12D3KooWSmtsbL2ukwVwf8gDoTYZHnCd7sVNNVdMnCa4MkWjLujm
cargo run -- --help
```
This will bootstrap your peer to the rest of the network, so you will see all messages sent on the chat topic in your own peer. It needs to connect via `quic-v1` because it works with all servers.
You should see the multiaddr of the peer once its loaded, e.g.
```
Listen address: "/ip4/127.0.0.1/udp/49350/webrtc/certhash/uEiAs1mQgRDVdSqMsQAuEnpMW0sSj6qc5jNvx2d0r3bQoiA/p2p/12D3KooWMzXTNGDLCKy6i6eAgJPMGCxuu7NJz33T9oC5kjByY27W
```
## Getting started: Go
### 1. Start peer
```
cd go-peer
go run .

View File

@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0"
clap = { version = "4.1.11", features = ["derive"] }
clap = { version = "4.1.11", features = ["derive", "env"] }
env_logger = "0.10.0"
futures = "0.3.27"
futures-timer = "3.0.2"

View File

@@ -1,9 +1,24 @@
FROM rust:1.68 as builder
WORKDIR /usr/src/universal-chat
COPY . .
RUN cargo install --path .
# syntax=docker/dockerfile:1.5-labs
FROM rust:1.72.0 as builder
FROM debian:bullseye-slim
RUN apt-get update && apt-get install && rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/local/cargo/bin/rust-libp2p-webrtc-peer /usr/local/bin/rust-libp2p-webrtc-peer
CMD ["rust-libp2p-webrtc-peer"]
RUN rustup target add x86_64-unknown-linux-musl
RUN --mount=type=cache,target=/var/cache/apt apt-get update && apt-get install -y musl-dev musl-tools
# Run with access to the target cache to speed up builds
WORKDIR /workspace
ADD . .
RUN --mount=type=cache,target=./target \
--mount=type=cache,target=/usr/local/cargo/registry \
cargo build --release --target x86_64-unknown-linux-musl
RUN --mount=type=cache,target=./target \
mv ./target/x86_64-unknown-linux-musl/release/rust-libp2p-webrtc-peer /usr/local/bin/rust-libp2p-webrtc-peer
FROM alpine:3
WORKDIR /app
COPY --from=builder /usr/local/bin/rust-libp2p-webrtc-peer /usr/bin/rust-libp2p-webrtc-peer
RUN --mount=type=cache,target=/var/cache/apk apk add bind-tools
ENV RUST_BACKTRACE=1
CMD ["rust-libp2p-webrtc-peer"]

28
rust-peer/fly.toml Normal file
View File

@@ -0,0 +1,28 @@
# fly.toml app configuration file generated for universal-connectivity-rust-peer on 2023-09-24T16:20:25+10:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#
app = "universal-connectivity-rust-peer"
primary_region = "syd"
[experimental]
# Resolve the special `fly-global-services` address before starting the container, see https://fly.io/docs/app-guides/udp-and-tcp/#the-fly-global-services-address.
cmd = ["/bin/sh", "-c", "set -ex; LISTEN_ADDRESS=$(getent hosts fly-global-services | cut -d' ' -f1) && rust-libp2p-webrtc-peer"]
[env]
EXTERNAL_ADDRESS="149.248.215.31" # TODO: Remove this in favor of an AutoNAT setup.
[[services]]
internal_port = 9090
protocol = "udp"
[[services.ports]]
port = "9090"
[[services]]
internal_port = 9091
protocol = "udp"
[[services.ports]]
port = "9091"

View File

@@ -50,9 +50,16 @@ struct Opt {
#[clap(long, default_value = "0.0.0.0")]
listen_address: IpAddr,
/// Address of a remote peer to connect to.
#[clap(long)]
remote_address: Option<Multiaddr>,
/// If known, the external address of this node. Will be used to correctly advertise our external address across all transports.
#[clap(long, env)]
external_address: Option<IpAddr>,
/// Nodes to connect to on startup. Can be specified several times.
#[clap(
long,
default_value = "/dns/universal-connectivity-rust-peer.fly.dev/udp/9091/quic-v1"
)]
connect: Vec<Multiaddr>,
}
/// An example WebRTC peer that will accept connections
@@ -85,10 +92,10 @@ async fn main() -> Result<()> {
.listen_on(address_quic.clone())
.expect("listen on quic");
if let Some(remote_address) = opt.remote_address {
swarm
.dial(remote_address)
.expect("a valid remote address to be provided");
for addr in opt.connect {
if let Err(e) = swarm.dial(addr.clone()) {
debug!("Failed to dial {addr}: {e}");
}
}
let chat_topic_hash = gossipsub::IdentTopic::new(GOSSIPSUB_CHAT_TOPIC).hash();
@@ -101,8 +108,16 @@ async fn main() -> Result<()> {
match select(swarm.next(), &mut tick).await {
Either::Left((event, _)) => match event.unwrap() {
SwarmEvent::NewListenAddr { address, .. } => {
if let Some(external_ip) = opt.external_address {
let external_address = address
.replace(0, |_| Some(external_ip.into()))
.expect("address.len > 1 and we always return `Some`");
swarm.add_external_address(external_address);
}
let p2p_address = address.with(Protocol::P2p(*swarm.local_peer_id()));
info!("Listen p2p address: {p2p_address:?}");
info!("Listening on {p2p_address}");
}
SwarmEvent::ConnectionEstablished { peer_id, .. } => {
info!("Connected to {peer_id}");