feat: update docker-compose.yml for selfhost

This commit is contained in:
alyssa 2025-04-13 22:05:14 +00:00
parent 437ea72ed4
commit 292c182eb2
9 changed files with 68 additions and 84 deletions

View file

@ -19,5 +19,4 @@ public class CoreConfig
public LogEventLevel ConsoleLogLevel { get; set; } = LogEventLevel.Debug; public LogEventLevel ConsoleLogLevel { get; set; } = LogEventLevel.Debug;
public LogEventLevel ElasticLogLevel { get; set; } = LogEventLevel.Information; public LogEventLevel ElasticLogLevel { get; set; } = LogEventLevel.Information;
public LogEventLevel FileLogLevel { get; set; } = LogEventLevel.Information;
} }

View file

@ -73,30 +73,6 @@ public class LoggingModule: Module
.Destructure.AsScalar<SwitchId>() .Destructure.AsScalar<SwitchId>()
.Destructure.ByTransforming<ProxyTag>(t => new { t.Prefix, t.Suffix }) .Destructure.ByTransforming<ProxyTag>(t => new { t.Prefix, t.Suffix })
.Destructure.With<PatchObjectDestructuring>() .Destructure.With<PatchObjectDestructuring>()
.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 => .WriteTo.Async(a =>
a.Console( a.Console(
theme: AnsiConsoleTheme.Code, theme: AnsiConsoleTheme.Code,

View file

@ -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 PluralKit has a Discord server for support, feedback, and discussion: https://discord.gg/PczBt78
# Running # 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 # Development
See [the dev-docs/ directory](./dev-docs/README.md) See [the dev-docs/ directory](./dev-docs/README.md)

View file

@ -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 scheduled_tasks --release --target x86_64-unknown-linux-musl
RUN cargo build --bin gdpr_worker --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/api /api
COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/dispatch /dispatch COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/dispatch /dispatch

View file

@ -40,6 +40,19 @@ async fn real_main() -> anyhow::Result<()> {
.await?, .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 shard_state = discord::shard_state::new(redis.clone());
let cache = Arc::new(discord::cache::new()); let cache = Arc::new(discord::cache::new());
let awaiter = Arc::new(EventAwaiter::new()); let awaiter = Arc::new(EventAwaiter::new());

View file

@ -24,6 +24,9 @@ pub struct DiscordConfig {
#[serde(default = "_default_api_addr")] #[serde(default = "_default_api_addr")]
pub cache_api_addr: String, pub cache_api_addr: String,
#[serde(default)]
pub gateway_target: Option<String>,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]

View file

@ -188,9 +188,7 @@ pub async fn update_stats_api(ctx: AppCtx) -> anyhow::Result<()> {
let data = resp.json::<PrometheusResult>().await?; let data = resp.json::<PrometheusResult>().await?;
let error_handler = || { let error_handler = || anyhow::anyhow!("missing data at {}", $q);
anyhow::anyhow!("missing data at {}", $q)
};
data.data data.data
.result .result

View file

@ -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" version: "3"
services: services:
bot: bot:
image: pluralkit # This image is reused in the other containers due to the build: .
build: . # build instruction right here
command: ["bin/PluralKit.Bot.dll"] command: ["bin/PluralKit.Bot.dll"]
environment: environment:
- "PluralKit:Database=Host=db;Username=postgres;Password=postgres;Database=postgres;Maximum Pool Size=1000" - "PluralKit__Database=Host=db;Username=postgres;Password=postgres;Database=postgres"
- "PluralKit:RedisAddr=redis" - "PluralKit__RedisAddr=redis"
- "PluralKit:InfluxUrl=http://influx:8086" - "PluralKit__Bot__Token=${BOT_TOKEN}"
- "PluralKit:InfluxDb=pluralkit" - "PluralKit__Bot__ClientId=${CLIENT_ID}"
- "PluralKit:LogDir=/var/log/pluralkit" - "PluralKit__Bot__AdminRole=${ADMIN_ROLE}"
volumes: - "PluralKit__Bot__HttpCacheUrl=http://gateway:5000"
- "./pluralkit.conf:/app/pluralkit.conf:ro" - "PluralKit__Bot__HttpListenerAddr=0.0.0.0"
- "/var/log/pluralkit:/var/log/pluralkit" - "PluralKit__Bot__EventAwaiterTarget=http://bot:5002/events"
- "PluralKit__Bot__DisableGateway=true"
restart: unless-stopped restart: unless-stopped
api: gateway:
image: pluralkit build:
command: ["bin/PluralKit.API.dll"] context: .
dockerfile: ci/Dockerfile.rust
command: ["/gateway"]
environment: environment:
- "PluralKit:Database=Host=db;Username=postgres;Password=postgres;Database=postgres;Maximum Pool Size=1000" - RUST_LOG=info
- "PluralKit:RedisAddr=redis" - pluralkit__discord__client_id=${CLIENT_ID}
ports: - pluralkit__discord__bot_token=${BOT_TOKEN}
- "127.0.0.1:2838:5000" - pluralkit__discord__max_concurrency=1
restart: unless-stopped - pluralkit__discord__gateway_target=http://bot:5002/events
- pluralkit__db__data_db_uri=postgresql://postgres:postgres@db:5432/postgres
scheduled_tasks: - pluralkit__db__data_redis_addr=redis://redis:6379
image: pluralkit - pluralkit__api__temp_token2=1
command: ["bin/PluralKit.ScheduledTasks.dll"] - pluralkit__api__remote_url=1
environment: - pluralkit__api__ratelimit_redis_addr=1
- "PluralKit:Database=Host=db;Username=postgres;Password=postgres;Database=postgres;Maximum Pool Size=1000" - pluralkit__discord__client_secret=1
depends_on:
- redis
restart: unless-stopped restart: unless-stopped
db: db:
image: postgres:12-alpine image: postgres:17-alpine
volumes: volumes:
- "db_data:/var/lib/postgresql/data" - "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: environment:
- "POSTGRES_PASSWORD=postgres" - "POSTGRES_PASSWORD=postgres"
restart: unless-stopped restart: unless-stopped
@ -55,14 +49,5 @@ services:
image: redis:alpine image: redis:alpine
restart: unless-stopped 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: volumes:
db_data: db_data:
influx_data:

View file

@ -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"
}
}