From 292c182eb22d7a8254ae45b70dd9ef7a24f60731 Mon Sep 17 00:00:00 2001 From: alyssa Date: Sun, 13 Apr 2025 22:05:14 +0000 Subject: [PATCH] feat: update docker-compose.yml for selfhost --- PluralKit.Core/CoreConfig.cs | 1 - PluralKit.Core/Modules/LoggingModule.cs | 24 -------- README.md | 22 +++++++- ci/Dockerfile.rust | 2 +- crates/gateway/src/main.rs | 13 +++++ crates/libpk/src/_config.rs | 3 + crates/scheduled_tasks/src/tasks.rs | 4 +- docker-compose.yml | 73 ++++++++++--------------- pluralkit.conf.example | 10 ---- 9 files changed, 68 insertions(+), 84 deletions(-) delete mode 100644 pluralkit.conf.example diff --git a/PluralKit.Core/CoreConfig.cs b/PluralKit.Core/CoreConfig.cs index 4adf815b..1e77271b 100644 --- a/PluralKit.Core/CoreConfig.cs +++ b/PluralKit.Core/CoreConfig.cs @@ -19,5 +19,4 @@ public class CoreConfig public LogEventLevel ConsoleLogLevel { get; set; } = LogEventLevel.Debug; public LogEventLevel ElasticLogLevel { get; set; } = LogEventLevel.Information; - public LogEventLevel FileLogLevel { get; set; } = LogEventLevel.Information; } \ No newline at end of file diff --git a/PluralKit.Core/Modules/LoggingModule.cs b/PluralKit.Core/Modules/LoggingModule.cs index 18ffa58b..f02bfe69 100644 --- a/PluralKit.Core/Modules/LoggingModule.cs +++ b/PluralKit.Core/Modules/LoggingModule.cs @@ -73,30 +73,6 @@ public class LoggingModule: Module .Destructure.AsScalar() .Destructure.ByTransforming(t => new { t.Prefix, t.Suffix }) .Destructure.With() - .WriteTo.Async(a => - { - // Both the same output, except one is raw compact JSON and one is plain text. - // Output simultaneously. May remove the JSON formatter later, keeping it just in cast. - // Flush interval is 50ms (down from 10s) to make "tail -f" easier. May be too low? - a.File( - (config.LogDir ?? "logs") + $"/pluralkit.{_component}.log", - outputTemplate: outputTemplate, - retainedFileCountLimit: 10, - rollingInterval: RollingInterval.Day, - fileSizeLimitBytes: null, - flushToDiskInterval: TimeSpan.FromMilliseconds(50), - restrictedToMinimumLevel: config.FileLogLevel, - formatProvider: new UTCTimestampFormatProvider(), - buffered: true); - - a.File( - new RenderedCompactJsonFormatter(new ScalarFormatting.JsonValue()), - (config.LogDir ?? "logs") + $"/pluralkit.{_component}.json", - rollingInterval: RollingInterval.Day, - flushToDiskInterval: TimeSpan.FromMilliseconds(50), - restrictedToMinimumLevel: config.FileLogLevel, - buffered: true); - }) .WriteTo.Async(a => a.Console( theme: AnsiConsoleTheme.Code, diff --git a/README.md b/README.md index af6d24fe..84cc3f56 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,27 @@ PluralKit is a Discord bot meant for plural communities. It has features like me PluralKit has a Discord server for support, feedback, and discussion: https://discord.gg/PczBt78 # Running -See [RUNNING.md](./RUNNING.md). +In production, we run PluralKit using Kubernetes (soon). The configuration can be found in the infra repo. + +For self-hosting, it's simpler to use Docker, with the provided [docker-compose](./docker-compose.yml) file. + +Create a `.env` file with the Discord client ID and bot token: +``` +CLIENT_ID=198622483471925248 +BOT_TOKEN=MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs +``` + +If you want to use `pk;admin` commands (to raise member limits and such), set `ADMIN_ROLE` to a Discord role ID: + +``` +ADMIN_ROLE=682632767057428509 +``` + +Run `docker compose build`, then `docker compose up -d`. + +To view logs, use `docker compose logs`. + +Postgres data is stored in a `pluralkit_data` [Docker volume](https://docs.docker.com/engine/storage/volumes/). # Development See [the dev-docs/ directory](./dev-docs/README.md) diff --git a/ci/Dockerfile.rust b/ci/Dockerfile.rust index fdc276c9..b035cfcf 100644 --- a/ci/Dockerfile.rust +++ b/ci/Dockerfile.rust @@ -33,7 +33,7 @@ RUN cargo build --bin avatar_cleanup --release --target x86_64-unknown-linux-mus RUN cargo build --bin scheduled_tasks --release --target x86_64-unknown-linux-musl RUN cargo build --bin gdpr_worker --release --target x86_64-unknown-linux-musl -FROM scratch +FROM alpine:latest COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/api /api COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/dispatch /dispatch diff --git a/crates/gateway/src/main.rs b/crates/gateway/src/main.rs index ab679c06..7a2a0721 100644 --- a/crates/gateway/src/main.rs +++ b/crates/gateway/src/main.rs @@ -40,6 +40,19 @@ async fn real_main() -> anyhow::Result<()> { .await?, ); + // hacky, but needed for selfhost for now + if let Some(target) = libpk::config + .discord + .as_ref() + .unwrap() + .gateway_target + .clone() + { + runtime_config + .set(RUNTIME_CONFIG_KEY_EVENT_TARGET.to_string(), target) + .await?; + } + let shard_state = discord::shard_state::new(redis.clone()); let cache = Arc::new(discord::cache::new()); let awaiter = Arc::new(EventAwaiter::new()); diff --git a/crates/libpk/src/_config.rs b/crates/libpk/src/_config.rs index b182f359..aa6a1f3b 100644 --- a/crates/libpk/src/_config.rs +++ b/crates/libpk/src/_config.rs @@ -24,6 +24,9 @@ pub struct DiscordConfig { #[serde(default = "_default_api_addr")] pub cache_api_addr: String, + + #[serde(default)] + pub gateway_target: Option, } #[derive(Deserialize, Debug)] diff --git a/crates/scheduled_tasks/src/tasks.rs b/crates/scheduled_tasks/src/tasks.rs index bdcb51be..98396a3f 100644 --- a/crates/scheduled_tasks/src/tasks.rs +++ b/crates/scheduled_tasks/src/tasks.rs @@ -188,9 +188,7 @@ pub async fn update_stats_api(ctx: AppCtx) -> anyhow::Result<()> { let data = resp.json::().await?; - let error_handler = || { - anyhow::anyhow!("missing data at {}", $q) - }; + let error_handler = || anyhow::anyhow!("missing data at {}", $q); data.data .result diff --git a/docker-compose.yml b/docker-compose.yml index 161fd133..41468461 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,52 +1,46 @@ -# API port: 2838, InfluxDB port: 2839, both listen on localhost only -# Reads `pluralkit.conf` from current directory, and logs to `/var/log/pluralkit`. - version: "3" services: bot: - image: pluralkit # This image is reused in the other containers due to the - build: . # build instruction right here + build: . command: ["bin/PluralKit.Bot.dll"] environment: - - "PluralKit:Database=Host=db;Username=postgres;Password=postgres;Database=postgres;Maximum Pool Size=1000" - - "PluralKit:RedisAddr=redis" - - "PluralKit:InfluxUrl=http://influx:8086" - - "PluralKit:InfluxDb=pluralkit" - - "PluralKit:LogDir=/var/log/pluralkit" - volumes: - - "./pluralkit.conf:/app/pluralkit.conf:ro" - - "/var/log/pluralkit:/var/log/pluralkit" + - "PluralKit__Database=Host=db;Username=postgres;Password=postgres;Database=postgres" + - "PluralKit__RedisAddr=redis" + - "PluralKit__Bot__Token=${BOT_TOKEN}" + - "PluralKit__Bot__ClientId=${CLIENT_ID}" + - "PluralKit__Bot__AdminRole=${ADMIN_ROLE}" + - "PluralKit__Bot__HttpCacheUrl=http://gateway:5000" + - "PluralKit__Bot__HttpListenerAddr=0.0.0.0" + - "PluralKit__Bot__EventAwaiterTarget=http://bot:5002/events" + - "PluralKit__Bot__DisableGateway=true" restart: unless-stopped - api: - image: pluralkit - command: ["bin/PluralKit.API.dll"] + gateway: + build: + context: . + dockerfile: ci/Dockerfile.rust + command: ["/gateway"] environment: - - "PluralKit:Database=Host=db;Username=postgres;Password=postgres;Database=postgres;Maximum Pool Size=1000" - - "PluralKit:RedisAddr=redis" - ports: - - "127.0.0.1:2838:5000" - restart: unless-stopped - - scheduled_tasks: - image: pluralkit - command: ["bin/PluralKit.ScheduledTasks.dll"] - environment: - - "PluralKit:Database=Host=db;Username=postgres;Password=postgres;Database=postgres;Maximum Pool Size=1000" + - RUST_LOG=info + - pluralkit__discord__client_id=${CLIENT_ID} + - pluralkit__discord__bot_token=${BOT_TOKEN} + - pluralkit__discord__max_concurrency=1 + - pluralkit__discord__gateway_target=http://bot:5002/events + - pluralkit__db__data_db_uri=postgresql://postgres:postgres@db:5432/postgres + - pluralkit__db__data_redis_addr=redis://redis:6379 + - pluralkit__api__temp_token2=1 + - pluralkit__api__remote_url=1 + - pluralkit__api__ratelimit_redis_addr=1 + - pluralkit__discord__client_secret=1 + depends_on: + - redis restart: unless-stopped db: - image: postgres:12-alpine + image: postgres:17-alpine volumes: - "db_data:/var/lib/postgresql/data" - - "/var/run/postgresql:/var/run/postgresql" - command: ["postgres", - "-c", "max-connections=1000", - "-c", "timezone=Etc/UTC", - "-c", "max_wal_size=1GB", - "-c", "min_wal_size=80MB", - "-c", "shared_buffers=128MB"] environment: - "POSTGRES_PASSWORD=postgres" restart: unless-stopped @@ -55,14 +49,5 @@ services: image: redis:alpine restart: unless-stopped - influx: - image: influxdb:1.8 - volumes: - - "influx_data:/var/lib/influxdb" - ports: - - 127.0.0.1:2839:8086 - restart: unless-stopped - volumes: db_data: - influx_data: diff --git a/pluralkit.conf.example b/pluralkit.conf.example deleted file mode 100644 index a705265b..00000000 --- a/pluralkit.conf.example +++ /dev/null @@ -1,10 +0,0 @@ -{ - "PluralKit": { - "Bot": { - "Token": "BOT_TOKEN_GOES_HERE", - "ClientId": 466707357099884544, - }, - "Database": "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=pluralkit", - "RedisAddr": "127.0.0.1:6379" - } -} \ No newline at end of file