mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 17:55:36 +00:00
Merge pull request #85 from greatest-ape/docker-2022-07-19
Add some Dockerfiles to make it easier to get started
This commit is contained in:
commit
ce418feb5d
8 changed files with 137 additions and 4 deletions
5
.dockerignore
Normal file
5
.dockerignore
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
target
|
||||||
|
docker
|
||||||
|
.git
|
||||||
|
tmp
|
||||||
|
documents
|
||||||
3
TODO.md
3
TODO.md
|
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
## High priority
|
## High priority
|
||||||
|
|
||||||
* ws
|
|
||||||
* add integration test for non-TLS configuration, maybe behind reverse proxy
|
|
||||||
|
|
||||||
## Medium priority
|
## Medium priority
|
||||||
|
|
||||||
* quit whole program if any thread panics
|
* quit whole program if any thread panics
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ impl AccessListMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, TomlConfig, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, TomlConfig, Deserialize)]
|
||||||
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct AccessListConfig {
|
pub struct AccessListConfig {
|
||||||
pub mode: AccessListMode,
|
pub mode: AccessListMode,
|
||||||
/// Path to access list file consisting of newline-separated hex-encoded info hashes.
|
/// Path to access list file consisting of newline-separated hex-encoded info hashes.
|
||||||
|
|
@ -39,7 +40,7 @@ pub struct AccessListConfig {
|
||||||
impl Default for AccessListConfig {
|
impl Default for AccessListConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
path: "".into(),
|
path: "./access-list.txt".into(),
|
||||||
mode: AccessListMode::Off,
|
mode: AccessListMode::Off,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,6 +64,11 @@ impl AccessList {
|
||||||
|
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
let line = line?;
|
let line = line?;
|
||||||
|
let line = line.trim();
|
||||||
|
|
||||||
|
if line.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
new_list
|
new_list
|
||||||
.insert_from_line(&line)
|
.insert_from_line(&line)
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ impl Options {
|
||||||
"-h" | "--help" => {
|
"-h" | "--help" => {
|
||||||
return Err(None);
|
return Err(None);
|
||||||
}
|
}
|
||||||
|
"" => (),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Some("Unrecognized argument".to_string()));
|
return Err(Some("Unrecognized argument".to_string()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ pub fn run(config: Config) -> ::anyhow::Result<()> {
|
||||||
executors.push(executor);
|
executors.push(executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::log::info!("spawned socket workers");
|
||||||
|
|
||||||
for i in 0..(config.swarm_workers) {
|
for i in 0..(config.swarm_workers) {
|
||||||
let sentinel = sentinel.clone();
|
let sentinel = sentinel.clone();
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
|
|
@ -129,6 +131,8 @@ pub fn run(config: Config) -> ::anyhow::Result<()> {
|
||||||
executors.push(executor);
|
executors.push(executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::log::info!("spawned swarm workers");
|
||||||
|
|
||||||
if config.cpu_pinning.active {
|
if config.cpu_pinning.active {
|
||||||
set_affinity_for_util_worker(
|
set_affinity_for_util_worker(
|
||||||
&config.cpu_pinning,
|
&config.cpu_pinning,
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ pub async fn run_socket_worker(
|
||||||
|
|
||||||
let listener = create_tcp_listener(&config, priv_dropper).expect("create tcp listener");
|
let listener = create_tcp_listener(&config, priv_dropper).expect("create tcp listener");
|
||||||
|
|
||||||
|
::log::info!("created tcp listener");
|
||||||
|
|
||||||
let (control_message_senders, _) = control_message_mesh_builder
|
let (control_message_senders, _) = control_message_mesh_builder
|
||||||
.join(Role::Producer)
|
.join(Role::Producer)
|
||||||
.await
|
.await
|
||||||
|
|
@ -86,6 +88,8 @@ pub async fn run_socket_worker(
|
||||||
out_message_mesh_builder.join(Role::Consumer).await.unwrap();
|
out_message_mesh_builder.join(Role::Consumer).await.unwrap();
|
||||||
let out_message_consumer_id = ConsumerId(out_message_receivers.consumer_id().unwrap());
|
let out_message_consumer_id = ConsumerId(out_message_receivers.consumer_id().unwrap());
|
||||||
|
|
||||||
|
::log::info!("joined channels");
|
||||||
|
|
||||||
let connection_slab = Rc::new(RefCell::new(Slab::new()));
|
let connection_slab = Rc::new(RefCell::new(Slab::new()));
|
||||||
|
|
||||||
// Periodically clean connections
|
// Periodically clean connections
|
||||||
|
|
@ -718,28 +722,42 @@ fn create_tcp_listener(
|
||||||
socket2::Domain::IPV6
|
socket2::Domain::IPV6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
::log::info!("creating socket..");
|
||||||
|
|
||||||
let socket = socket2::Socket::new(domain, socket2::Type::STREAM, Some(socket2::Protocol::TCP))
|
let socket = socket2::Socket::new(domain, socket2::Type::STREAM, Some(socket2::Protocol::TCP))
|
||||||
.with_context(|| "create socket")?;
|
.with_context(|| "create socket")?;
|
||||||
|
|
||||||
if config.network.only_ipv6 {
|
if config.network.only_ipv6 {
|
||||||
|
::log::info!("setting socket to ipv6 only..");
|
||||||
|
|
||||||
socket
|
socket
|
||||||
.set_only_v6(true)
|
.set_only_v6(true)
|
||||||
.with_context(|| "socket: set only ipv6")?;
|
.with_context(|| "socket: set only ipv6")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::log::info!("setting SO_REUSEPORT on socket..");
|
||||||
|
|
||||||
socket
|
socket
|
||||||
.set_reuse_port(true)
|
.set_reuse_port(true)
|
||||||
.with_context(|| "socket: set reuse port")?;
|
.with_context(|| "socket: set reuse port")?;
|
||||||
|
|
||||||
|
::log::info!("binding socket..");
|
||||||
|
|
||||||
socket
|
socket
|
||||||
.bind(&config.network.address.into())
|
.bind(&config.network.address.into())
|
||||||
.with_context(|| format!("socket: bind to {}", config.network.address))?;
|
.with_context(|| format!("socket: bind to {}", config.network.address))?;
|
||||||
|
|
||||||
|
::log::info!("listening on socket..");
|
||||||
|
|
||||||
socket
|
socket
|
||||||
.listen(config.network.tcp_backlog)
|
.listen(config.network.tcp_backlog)
|
||||||
.with_context(|| format!("socket: listen {}", config.network.address))?;
|
.with_context(|| format!("socket: listen {}", config.network.address))?;
|
||||||
|
|
||||||
|
::log::info!("running PrivilegeDropper::after_socket_creation..");
|
||||||
|
|
||||||
priv_dropper.after_socket_creation()?;
|
priv_dropper.after_socket_creation()?;
|
||||||
|
|
||||||
|
::log::info!("casting socket to glommio TcpListener..");
|
||||||
|
|
||||||
Ok(unsafe { TcpListener::from_raw_fd(socket.into_raw_fd()) })
|
Ok(unsafe { TcpListener::from_raw_fd(socket.into_raw_fd()) })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
44
docker/aquatic_udp.Dockerfile
Normal file
44
docker/aquatic_udp.Dockerfile
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
# aquatic_udp
|
||||||
|
#
|
||||||
|
# Customize by setting CONFIG_FILE_CONTENTS and
|
||||||
|
# ACCESS_LIST_CONTENTS environment variables.
|
||||||
|
#
|
||||||
|
# By default runs tracker on port 3000 without info hash access control.
|
||||||
|
#
|
||||||
|
# Run from repository root directory with:
|
||||||
|
# $ DOCKER_BUILDKIT=1 docker build -t aquatic-udp -f docker/aquatic_udp.Dockerfile .
|
||||||
|
# $ docker run -it -p 0.0.0.0:3000:3000/udp --name aquatic-udp aquatic-udp
|
||||||
|
#
|
||||||
|
# Pass --network="host" to run command for much better performance.
|
||||||
|
|
||||||
|
FROM rust:latest AS builder
|
||||||
|
|
||||||
|
WORKDIR /usr/src/aquatic
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN . ./scripts/env-native-cpu-without-avx-512 && cargo build --release -p aquatic_udp
|
||||||
|
|
||||||
|
FROM debian:stable-slim
|
||||||
|
|
||||||
|
ENV CONFIG_FILE_CONTENTS "log_level = 'warn'"
|
||||||
|
ENV ACCESS_LIST_CONTENTS ""
|
||||||
|
|
||||||
|
WORKDIR /root/
|
||||||
|
|
||||||
|
COPY --from=builder /usr/src/aquatic/target/release/aquatic_udp ./
|
||||||
|
|
||||||
|
# Create entry point script for setting config and access
|
||||||
|
# list file contents at runtime
|
||||||
|
COPY <<-"EOT" ./entrypoint.sh
|
||||||
|
#!/bin/bash
|
||||||
|
echo -e "$CONFIG_FILE_CONTENTS" > ./config.toml
|
||||||
|
echo -e "$ACCESS_LIST_CONTENTS" > ./access-list.txt
|
||||||
|
exec ./aquatic_udp -c ./config.toml "$@"
|
||||||
|
EOT
|
||||||
|
|
||||||
|
RUN chmod +x ./entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
58
docker/aquatic_ws.Dockerfile
Normal file
58
docker/aquatic_ws.Dockerfile
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
# aquatic_ws
|
||||||
|
#
|
||||||
|
# WORK IN PROGRESS: currently doesn't work due to issues with spawning worker
|
||||||
|
# threads, possibly related to https://github.com/DataDog/glommio/issues/547
|
||||||
|
#
|
||||||
|
# Customize by setting CONFIG_FILE_CONTENTS and
|
||||||
|
# ACCESS_LIST_CONTENTS environment variables.
|
||||||
|
#
|
||||||
|
# If no changes are made to configuration, aquatic_ws is run:
|
||||||
|
# - on port 3000
|
||||||
|
# - without TLS
|
||||||
|
# - with http health checks enabled
|
||||||
|
# - only allowing announces for hashes in access list, e.g., contained
|
||||||
|
# in ACCESS_LIST_CONTENTS env var
|
||||||
|
#
|
||||||
|
# Run from root directory of aquatic repository with:
|
||||||
|
# $ DOCKER_BUILDKIT=1 docker build -t aquatic-ws -f docker/aquatic_ws.Dockerfile .
|
||||||
|
# $ docker run -it --ulimit memlock=65536:65536 -p 0.0.0.0:3000:3000 --name aquatic-ws aquatic-ws
|
||||||
|
#
|
||||||
|
# Pass --network="host" to run command for much better performance.
|
||||||
|
|
||||||
|
FROM rust:latest AS builder
|
||||||
|
|
||||||
|
WORKDIR /usr/src/aquatic
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN . ./scripts/env-native-cpu-without-avx-512 && cargo build --release -p aquatic_ws
|
||||||
|
|
||||||
|
FROM debian:stable-slim
|
||||||
|
|
||||||
|
ENV CONFIG_FILE_CONTENTS "\
|
||||||
|
log_level = 'info'\n\
|
||||||
|
[network]\n\
|
||||||
|
enable_http_health_checks = true\n\
|
||||||
|
[access_list]\n\
|
||||||
|
mode = 'allow'\n\
|
||||||
|
"
|
||||||
|
ENV ACCESS_LIST_CONTENTS "0f0f0f0f0f1f1f1f1f1f2f2f2f2f2f3f3f3f3f3f"
|
||||||
|
|
||||||
|
WORKDIR /root/
|
||||||
|
|
||||||
|
COPY --from=builder /usr/src/aquatic/target/release/aquatic_ws ./
|
||||||
|
|
||||||
|
# Create entry point script for setting config and access
|
||||||
|
# list file contents at runtime
|
||||||
|
COPY <<-"EOT" ./entrypoint.sh
|
||||||
|
#!/bin/bash
|
||||||
|
echo -e "$CONFIG_FILE_CONTENTS" > ./config.toml
|
||||||
|
echo -e "$ACCESS_LIST_CONTENTS" > ./access-list.txt
|
||||||
|
exec ./aquatic_ws -c ./config.toml "$@"
|
||||||
|
EOT
|
||||||
|
|
||||||
|
RUN chmod +x ./entrypoint.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["./entrypoint.sh"]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue