Fixed docker containers
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# =========
|
||||
# Builder
|
||||
# =========
|
||||
FROM rust:bookworm as builder
|
||||
FROM rust:bookworm AS builder
|
||||
WORKDIR /builder
|
||||
|
||||
COPY migrations ./migrations
|
||||
@@ -14,7 +14,7 @@ RUN cargo build --release
|
||||
# ==========
|
||||
# Packages
|
||||
# ==========
|
||||
FROM debian:bookworm-slim as packages
|
||||
FROM debian:bookworm-slim AS packages
|
||||
WORKDIR /packages
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
@@ -36,7 +36,7 @@ RUN apt-get update && apt-get install -y python3 curl tar xz-utils && \
|
||||
# =========
|
||||
# Runtime
|
||||
# =========
|
||||
FROM debian:bookworm-slim as runtime
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
WORKDIR /siren
|
||||
USER root
|
||||
|
||||
|
||||
27
Makefile
27
Makefile
@@ -1,57 +1,56 @@
|
||||
#!make
|
||||
SHELL := /bin/bash
|
||||
|
||||
include .env
|
||||
-include .env.local
|
||||
export
|
||||
ENV := ./scripts/apply_env.sh
|
||||
|
||||
.PHONY: help
|
||||
|
||||
export VERSION=$(if $(v),$(v),latest)
|
||||
|
||||
help: ## Help command
|
||||
@echo
|
||||
@cat Makefile | grep -E '^[a-zA-Z\/_-]+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
@echo
|
||||
|
||||
backend-up: ## Start the backend containers
|
||||
@docker compose --profile backend up -d
|
||||
@$(ENV) docker compose --profile backend up -d
|
||||
|
||||
up-backend: backend-up
|
||||
|
||||
backend-down: ## Stop the backend containers
|
||||
@docker compose --profile backend down
|
||||
@$(ENV) docker compose --profile backend down
|
||||
|
||||
down-backend: backend-down
|
||||
|
||||
run: ## Run the project
|
||||
@echo "Running project..."
|
||||
@cargo run
|
||||
@$(ENV) cargo run
|
||||
@echo "Run complete"
|
||||
|
||||
format: ## Format code
|
||||
@echo "Formatting code..."
|
||||
@cargo fmt
|
||||
@$(ENV) cargo fmt
|
||||
@echo "Format complete"
|
||||
|
||||
clean: ## Clean the project
|
||||
@echo "Cleaning project..."
|
||||
@cargo clean
|
||||
@$(ENV) cargo clean
|
||||
@echo "Clean complete"
|
||||
|
||||
docker-up: ## Start the app
|
||||
@docker compose --profile backend --profile bot up -d
|
||||
@$(ENV) docker compose --profile backend --profile bot up -d
|
||||
|
||||
docker-down: ## Stop the app
|
||||
@docker compose --profile backend --profile bot down
|
||||
@$(ENV) docker compose --profile backend --profile bot down
|
||||
|
||||
docker-build: ## Build the docker image
|
||||
@docker compose build
|
||||
@$(ENV) docker build -f Dockerfile -t siren:${VERSION} .
|
||||
|
||||
docker-clean: ## Stop the docker containers and remove volumes
|
||||
@echo "Stopping docker container and removing volumes..."
|
||||
@docker compose --profile backend --profile bot down -v
|
||||
@$(ENV) docker compose --profile backend --profile bot down -v
|
||||
@echo "Docker container stopped and volumes removed"
|
||||
|
||||
docker-refresh: docker-clean backend-up ## Refresh the docker containers
|
||||
|
||||
psql: ## Connect to the database
|
||||
@docker exec -it siren-postgres psql -U ${DATABASE_USER} -P pager=off
|
||||
@$(ENV) docker exec -it siren-postgres psql -U ${DATABASE_USER} -P pager=off
|
||||
53
README.md
53
README.md
@@ -4,8 +4,10 @@
|
||||
</div>
|
||||
|
||||
Siren is a D&D Bot built for Discord, written in Rust. Features include:
|
||||
- Play tracks from Youtube or locally hosted files
|
||||
- Assistant DM tools to be defined later
|
||||
- Music commands from Youtube and locally hosted files
|
||||
- Database for D&D 5e content
|
||||
- Session scheduling
|
||||
- Backend API
|
||||
- ChatGPT integration
|
||||
|
||||
## Requirements
|
||||
@@ -80,6 +82,7 @@ Siren utilizes Discord slash commands. To view the commands, run `/help` in a se
|
||||
| `/resume` | Resume the current track |
|
||||
| `/skip` | Skip the current track |
|
||||
| `/stop` | Stop the current track |
|
||||
| `/mute` | Mute the current track |
|
||||
| `/queue` | ***TODO*** - Display the current queue |
|
||||
| `/clear` | ***TODO*** - Clear the current queue |
|
||||
| `/shuffle` | ***TODO*** - Shuffle the current queue |
|
||||
@@ -111,48 +114,16 @@ Siren utilizes Discord slash commands. To view the commands, run `/help` in a se
|
||||
| `/help` | ***TODO*** - Display a list of commands |
|
||||
|
||||
## Contributing
|
||||
[Rust](https://www.rust-lang.org/) must be installed to run locally. See [serenity-rs/serenity](https://github.com/serenity-rs/serenity) for more information about Rust Discord API Library.
|
||||
|
||||
The following packages must be installed for [serenity-rs/songbird](https://github.com/serenity-rs/songbird). View the repository for additional installation and setup information on other operating systems.
|
||||
<details>
|
||||
<summary>Unix Installation</summary>
|
||||
Notes:
|
||||
|
||||
- [yt-dlp](https://github.com/yt-dlp/yt-dlp/releases) is preferred over youtube-dl.
|
||||
|
||||
```
|
||||
sudo apt install libopus-dev
|
||||
sudo apt install ffmpeg
|
||||
sudo apt apt install youtube-dl # See notes above
|
||||
# PostgreSQL Headers
|
||||
sudo apt install libpq5
|
||||
sudo apt install libpq-dev
|
||||
```
|
||||
|
||||
- Potentially requires [yt-dlp](https://github.com/yt-dlp/yt-dlp#installation) and [yt-dlp FFmpeg Static Auto-Builds](https://github.com/yt-dlp/FFmpeg-Builds).
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>Mac Installation</summary>
|
||||
Notes:
|
||||
|
||||
- [Homebrew](https://brew.sh/) must be installed to run the following commands.
|
||||
- [youtube-dl](https://formulae.brew.sh/formula/youtube-dl#default) is deprecated, [yt-dlp](https://formulae.brew.sh/formula/yt-dlp) is preferred
|
||||
|
||||
```
|
||||
brew install opus
|
||||
brew install ffmpeg
|
||||
brew install yt-dlp # See notes above
|
||||
brew install postgresql
|
||||
```
|
||||
</details>
|
||||
- [Rust](https://www.rust-lang.org/)
|
||||
- [yt-dlp](https://github.com/yt-dlp/yt-dlp)
|
||||
- [ffmpeg](https://github.com/yt-dlp/FFmpeg-Builds)
|
||||
|
||||
### Running Locally
|
||||
1. Start the backend containers with `make docker-refresh`
|
||||
2. Start the application with `make run`
|
||||
1. Start the backend containers with `make backend-up`
|
||||
2. Run the application locally with `make run`
|
||||
|
||||
The application can also be tested from within a Docker container:
|
||||
```
|
||||
docker build -t siren:latest .
|
||||
docker run --env-file .env -it --rm --name siren siren:latest
|
||||
make docker-build
|
||||
make docker-up
|
||||
```
|
||||
|
||||
@@ -7,13 +7,8 @@ x-env_file: &env
|
||||
name: siren
|
||||
services:
|
||||
bot:
|
||||
image: siren-service:${SIREN_VERSION:-latest}
|
||||
container_name: siren-bot
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./Dockerfile
|
||||
args:
|
||||
- VERSION=${SIREN_VERSION:-latest}
|
||||
image: siren:${SIREN_VERSION:-latest}
|
||||
container_name: siren
|
||||
env_file: *env
|
||||
environment:
|
||||
DATABASE_HOST: postgres
|
||||
@@ -34,7 +29,7 @@ services:
|
||||
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: siren-postgres
|
||||
container_name: postgres
|
||||
env_file: *env
|
||||
environment:
|
||||
POSTGRES_USER: ${DATABASE_USER}
|
||||
|
||||
19
scripts/apply_env.sh
Executable file
19
scripts/apply_env.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
# Enable exporting variables
|
||||
set -a
|
||||
|
||||
# Source the default env variables
|
||||
echo "Sourcing build environment"
|
||||
source .env
|
||||
|
||||
# If there is a .env.local present, source it
|
||||
echo "Sourcing custom environment"
|
||||
if [ -f .env.local ]; then
|
||||
source ./.env.local
|
||||
fi
|
||||
|
||||
# Disable exporting variables
|
||||
set +a
|
||||
|
||||
# Run the given command
|
||||
exec "$@"
|
||||
@@ -3,7 +3,7 @@ use serenity::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use super::{create_response, edit_response, get_songbird, process_message};
|
||||
use super::{edit_response, get_songbird, process_message};
|
||||
|
||||
pub async fn run(ctx: &Context, command: &CommandInteraction) {
|
||||
// Create the initial response
|
||||
|
||||
@@ -56,7 +56,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) {
|
||||
Ok(channel_id) => {
|
||||
log::debug!("<{guild_id}> Play command executed on {channel_id} with track: {track_url:?}");
|
||||
// Handle the track url
|
||||
match enqueue_track(ctx, manager, guild_id.to_owned(), track_url, true).await {
|
||||
match enqueue_track(ctx, manager, guild_id.to_owned(), track_url).await {
|
||||
Ok(count) => {
|
||||
let mut message = format!("Playing {} tracks", count);
|
||||
if count == 0 {
|
||||
@@ -84,7 +84,6 @@ pub async fn enqueue_track(
|
||||
manager: Arc<Songbird>,
|
||||
guild_id: GuildId,
|
||||
track_url: &str,
|
||||
play_now: bool,
|
||||
) -> SirenResult<i32> {
|
||||
let mut track_count = 0;
|
||||
if let Some(handler_lock) = manager.get(guild_id) {
|
||||
@@ -140,7 +139,6 @@ pub async fn enqueue_track(
|
||||
}
|
||||
};
|
||||
let track_handle: TrackHandle;
|
||||
let is_queue_empty = handler.queue().is_empty();
|
||||
track_handle = handler.enqueue_input(input).await;
|
||||
// Set the volume
|
||||
let _ = track_handle.set_volume(volume);
|
||||
@@ -156,8 +154,8 @@ pub async fn enqueue_track(
|
||||
);
|
||||
track_count += 1;
|
||||
}
|
||||
if play_now && !handler.queue().is_empty() {
|
||||
handler.queue().resume();
|
||||
if handler.queue().is_empty() {
|
||||
let _ = handler.queue().resume();
|
||||
}
|
||||
}
|
||||
Ok(track_count)
|
||||
|
||||
@@ -3,7 +3,7 @@ use serenity::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use super::{create_response, edit_response, get_songbird, process_message};
|
||||
use super::{edit_response, get_songbird, process_message};
|
||||
|
||||
pub async fn run(ctx: &Context, command: &CommandInteraction) {
|
||||
// Create the initial response
|
||||
|
||||
@@ -3,7 +3,7 @@ use serenity::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use super::{get_songbird, create_response, edit_response};
|
||||
use super::{edit_response, get_songbird, process_message};
|
||||
|
||||
pub async fn run(ctx: &Context, command: &CommandInteraction) {
|
||||
// Create the initial response
|
||||
|
||||
@@ -3,7 +3,7 @@ use serenity::{
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use super::{get_songbird, create_response, edit_response};
|
||||
use super::{edit_response, get_songbird, process_message};
|
||||
|
||||
pub async fn run(ctx: &Context, command: &CommandInteraction) {
|
||||
// Create the initial response
|
||||
|
||||
@@ -48,12 +48,7 @@ pub async fn run(ctx: &Context, command: &CommandInteraction) {
|
||||
// Set the volume
|
||||
set_volume(&manager, guild_id, volume).await;
|
||||
log::debug!("<{guild_id}> Setting the volume to {}", volume);
|
||||
edit_response(
|
||||
&ctx,
|
||||
&command,
|
||||
format!("Setting the volume to {}", volume),
|
||||
)
|
||||
.await;
|
||||
edit_response(&ctx, &command, format!("Setting the volume to {}", volume)).await;
|
||||
}
|
||||
|
||||
pub async fn set_volume(manager: &Arc<Songbird>, guild_id: &GuildId, volume: i32) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use log::{warn, info, error};
|
||||
use serenity::all::Interaction;
|
||||
use serenity::async_trait;
|
||||
use serenity::model::gateway::Ready;
|
||||
@@ -36,7 +35,7 @@ impl EventHandler for Handler {
|
||||
commands::chat::generate_response(&ctx, &msg, oai).await;
|
||||
}
|
||||
}
|
||||
Err(why) => warn!("Could not check mentions: {:?}", why),
|
||||
Err(why) => log::warn!("Could not check mentions: {:?}", why),
|
||||
};
|
||||
}
|
||||
None => {}
|
||||
@@ -71,8 +70,9 @@ impl EventHandler for Handler {
|
||||
|
||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||
if ready.guilds.is_empty() {
|
||||
warn!("No ready guilds found");
|
||||
log::warn!("No ready guilds found");
|
||||
}
|
||||
log::trace!("Handling {} guilds", ready.guilds.len());
|
||||
for guild in ready.guilds {
|
||||
// Check if guild exists in database
|
||||
let guild_id = guild.id.get() as i64;
|
||||
@@ -103,12 +103,12 @@ impl EventHandler for Handler {
|
||||
)
|
||||
.await;
|
||||
match commands {
|
||||
Ok(c) => info!(
|
||||
Ok(c) => log::info!(
|
||||
"Registered {} commands for guild {}",
|
||||
c.len(),
|
||||
guild.id.get()
|
||||
),
|
||||
Err(why) => error!(
|
||||
Err(why) => log::error!(
|
||||
"Could not register commands for guild {}: {:?}",
|
||||
guild.id.get(),
|
||||
why
|
||||
|
||||
Reference in New Issue
Block a user