├── .github ├── redbot-arguments.txt └── workflows │ ├── build.yml │ ├── pr-image-cleanup.yml │ └── redbot-args-update.yml ├── .gitignore ├── Dockerfile ├── README.md ├── docker-compose-example.yml ├── redbot ├── entrypoint.sh ├── requirements.txt └── start-red.sh └── renovate.json /.github/redbot-arguments.txt: -------------------------------------------------------------------------------- 1 | Red V3 2 | Current Version: 3.5.20 3 | 4 | usage: redbot [arguments] 5 | 6 | Red - Discord Bot 7 | 8 | positional arguments: 9 | instance_name Name of the bot instance created during `redbot- 10 | setup`. 11 | 12 | options: 13 | -h, --help show this help message and exit 14 | --version, -V Show Red's current version 15 | --debuginfo Show debug information. 16 | --list-instances List all instance names setup with 'redbot-setup' 17 | --edit Edit the instance. This can be done without console 18 | interaction by passing --no-prompt and arguments that 19 | you want to change (available arguments: --edit- 20 | instance-name, --edit-data-path, --copy-data, --owner, 21 | --token, --prefix). 22 | --edit-instance-name EDIT_INSTANCE_NAME 23 | New name for the instance. This argument only works 24 | with --edit argument passed. 25 | --overwrite-existing-instance 26 | Confirm overwriting of existing instance when changing 27 | name. This argument only works with --edit argument 28 | passed. 29 | --edit-data-path EDIT_DATA_PATH 30 | New data path for the instance. This argument only 31 | works with --edit argument passed. 32 | --copy-data Copy data from old location. This argument only works 33 | with --edit and --edit-data-path arguments passed. 34 | --owner OWNER ID of the owner. Only who hosts Red should be owner, 35 | this has serious security implications if misused. 36 | --co-owner CO_OWNER [CO_OWNER ...] 37 | ID of a co-owner. Only people who have access to the 38 | system that is hosting Red should be co-owners, as 39 | this gives them complete access to the system's data. 40 | This has serious security implications if misused. Can 41 | be multiple. 42 | --prefix PREFIX, -p PREFIX 43 | Global prefix. Can be multiple 44 | --no-prompt Disables console inputs. Features requiring console 45 | interaction could be disabled as a result 46 | --no-cogs Starts Red with no cogs loaded, only core 47 | --load-cogs LOAD_COGS [LOAD_COGS ...] 48 | Force loading specified cogs from the installed 49 | packages. Can be used with the --no-cogs flag to load 50 | these cogs exclusively. 51 | --unload-cogs UNLOAD_COGS [UNLOAD_COGS ...] 52 | Force unloading specified cogs. 53 | --dry-run Makes Red quit with code 0 just before the login. This 54 | is useful for testing the boot process. 55 | -v, --verbose, --debug 56 | Increase the verbosity of the logs, each usage of this 57 | flag increases the verbosity level by 1. 58 | --dev Enables developer mode 59 | --mentionable Allows mentioning the bot as an alternative to using 60 | the bot prefix 61 | --rpc Enables the built-in RPC server. Please read the docs 62 | prior to enabling this! 63 | --rpc-port RPC_PORT The port of the built-in RPC server to use. Default to 64 | 6133. 65 | --token TOKEN Run Red with the given token. 66 | --no-instance Run Red without any existing instance. The data will 67 | be saved under a temporary folder and deleted on next 68 | system restart. 69 | --team-members-are-owners, --team-developers-are-owners 70 | Treat application team members as owners, if their 71 | team role is Owner, Admin, or Developer. This is off 72 | by default. Owners can load and run arbitrary code. Do 73 | not enable if you would not trust all of your team 74 | members with all of the data on the host machine. 75 | --message-cache-size MESSAGE_CACHE_SIZE 76 | Set the maximum number of messages to store in the 77 | internal message cache. 78 | --no-message-cache Disable the internal message cache. 79 | --disable-intent {guilds,members,moderation,bans,emojis,emojis_and_stickers,expressions,integrations,webhooks,invites,voice_states,presences,messages,guild_messages,dm_messages,reactions,guild_reactions,dm_reactions,typing,guild_typing,dm_typing,message_content,guild_scheduled_events,auto_moderation,auto_moderation_configuration,auto_moderation_execution,polls,guild_polls,dm_polls} 80 | Unsupported flag that allows disabling the given 81 | intent. Currently NOT SUPPORTED (and not covered by 82 | our version guarantees) as Red is not prepared to work 83 | without all intents. Go to https://discordpy.readthedo 84 | cs.io/en/v2.5.2/api.html#discord.Intents to see what 85 | each intent does. This flag can be used multiple times 86 | to specify multiple intents. 87 | --force-rich-logging Forcefully enables the Rich logging handlers. This is 88 | normally enabled for supported active terminals. 89 | --force-disable-rich-logging 90 | Forcefully disables the Rich logging handlers. 91 | --rich-traceback-extra-lines RICH_TRACEBACK_EXTRA_LINES 92 | Set the number of additional lines of code before and 93 | after the executed line that should be shown in 94 | tracebacks generated by Rich. Useful for development. 95 | --rich-traceback-show-locals 96 | Enable showing local variables in tracebacks generated 97 | by Rich. Useful for development. 98 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build/Push Image 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | inputs: 10 | push: 11 | description: 'Push' 12 | required: false 13 | type: boolean 14 | default: true 15 | 16 | env: 17 | IMAGE_NAME: red-discordbot 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | - name: Get Red version and define tags 26 | id: build_info 27 | run: | 28 | RED_VERSION=$(cat ./redbot/requirements.txt | grep 'Red-DiscordBot' | sed -e 's/Red-DiscordBot\s\?==\s\?//g') 29 | echo "red_version=$RED_VERSION" >> $GITHUB_OUTPUT 30 | 31 | - name: Set up Docker Buildx 32 | uses: docker/setup-buildx-action@v3 33 | 34 | - name: Login to DockerHub 35 | uses: docker/login-action@v3 36 | with: 37 | username: ${{ secrets.DOCKERHUB_USERNAME }} 38 | password: ${{ secrets.DOCKERHUB_TOKEN }} 39 | 40 | - name: Login to GitHub Container Registry 41 | uses: docker/login-action@v3 42 | with: 43 | registry: ghcr.io 44 | username: ${{ github.repository_owner }} 45 | password: ${{ secrets.GITHUB_TOKEN }} 46 | 47 | - name: Gather Docker metadata 48 | uses: docker/metadata-action@v5 49 | id: meta 50 | env: 51 | DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index 52 | with: 53 | images: | 54 | ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} 55 | ${{ github.repository_owner }}/${{ env.IMAGE_NAME }} 56 | tags: | 57 | type=raw,value=latest,enable={{is_default_branch}} 58 | type=semver,pattern={{version}},value=${{ steps.build_info.outputs.red_version }},enable={{is_default_branch}} 59 | type=semver,pattern={{major}}.{{minor}},value=${{ steps.build_info.outputs.red_version }},enable={{is_default_branch}} 60 | type=semver,pattern={{major}},value=${{ steps.build_info.outputs.red_version }},enable={{is_default_branch}} 61 | type=ref,event=pr 62 | 63 | - name: Build and push image 64 | uses: docker/build-push-action@v6 65 | with: 66 | push: ${{ inputs.push != 'false' }} 67 | tags: ${{ steps.meta.outputs.tags }} 68 | labels: ${{ steps.meta.outputs.labels }} 69 | annotations: ${{ steps.meta.outputs.annotations }} 70 | platforms: linux/amd64,linux/arm64 71 | # Build cache is scoped to branches by default. 72 | # We use the main branch as a fallback if there's no cache for the existing branch. 73 | # https://stackoverflow.com/a/77127188/5209106 74 | cache-from: | 75 | type=gha 76 | type=gha,scope=main 77 | cache-to: type=gha,mode=max 78 | provenance: false 79 | -------------------------------------------------------------------------------- /.github/workflows/pr-image-cleanup.yml: -------------------------------------------------------------------------------- 1 | name: 'Cleanup PR images' 2 | 3 | on: 4 | pull_request: 5 | types: [closed] 6 | 7 | jobs: 8 | purge-image: 9 | name: Delete ${{ matrix.tag }} image from ghcr.io 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Delete image 13 | uses: bots-house/ghcr-delete-image-action@v1.1.0 14 | with: 15 | owner: rhomelab 16 | name: red-discordbot 17 | token: ${{ secrets.IMAGE_CLEANUP_PAT }} 18 | tag: pr-${{ github.event.pull_request.number }} 19 | -------------------------------------------------------------------------------- /.github/workflows/redbot-args-update.yml: -------------------------------------------------------------------------------- 1 | name: Update redbot-arguments.txt 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | update-red-args: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | - name: Get Python version 15 | id: build_info 16 | run: | 17 | pyver=$(cat Dockerfile | grep FROM | grep -oP '(\d(\.\d\d?)?)') 18 | echo "$pyver" 19 | echo "python_version=$pyver" >> "$GITHUB_OUTPUT" 20 | 21 | - uses: actions/setup-python@v5 22 | with: 23 | python-version: ${{ steps.build_info.outputs.python_version }} 24 | 25 | - name: Install dependencies 26 | run: pip install -r redbot/requirements.txt 27 | 28 | - name: Update redbot-arguments.txt 29 | run: | 30 | : > "$ARGS_FILE" 31 | redbot --version >> "$ARGS_FILE" 32 | echo >> "$ARGS_FILE" 33 | redbot --help >> "$ARGS_FILE" 34 | 35 | if git status | grep -q 'Changes not staged for commit' ; then 36 | git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" 37 | git config --local user.name "github-actions[bot]" 38 | git add "$ARGS_FILE" 39 | git commit -m "Update ${ARGS_FILE##*/}" 40 | git push 41 | 42 | echo "${ARGS_FILE##*/} has been updated." >> $GITHUB_STEP_SUMMARY 43 | else 44 | echo "${ARGS_FILE##*/} did not need to be updated." >> $GITHUB_STEP_SUMMARY 45 | fi 46 | env: 47 | ARGS_FILE: .github/redbot-arguments.txt 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dev 2 | venv -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-slim-bullseye 2 | 3 | ARG DEBIAN_FRONTEND=noninteractive 4 | 5 | ENV PYTHONUNBUFFERED=1 6 | ENV PIP_DISABLE_PIP_VERSION_CHECK=1 7 | 8 | ENV RED_HOME=/redbot 9 | ENV RED_USER=reduser 10 | ARG RED_UID=1024 11 | ARG RED_GID=1024 12 | ENV PATH="${RED_HOME}/.local/bin:${PATH}" 13 | 14 | RUN groupadd -r -g $RED_GID ${RED_USER} && \ 15 | useradd -rm -g $RED_GID -u ${RED_UID} -d ${RED_HOME} ${RED_USER} && \ 16 | mkdir -pv ${RED_HOME}/data ${RED_HOME}/.config && \ 17 | ln -sv ${RED_HOME}/data ${RED_HOME}/.config/Red-DiscordBot && \ 18 | chown -Rv ${RED_USER}:${RED_USER} $RED_HOME 19 | 20 | COPY redbot/requirements.txt ${RED_HOME}/ 21 | 22 | RUN apt update && \ 23 | apt --no-install-recommends -y install build-essential git openjdk-11-jre-headless units && \ 24 | su $RED_USER -c "python -m pip install --no-cache-dir --user -r ${RED_HOME}/requirements.txt" && \ 25 | apt remove -y build-essential && \ 26 | apt autoremove -y && \ 27 | rm -rf /var/lib/apt/lists/* 28 | 29 | COPY --chmod=755 redbot/*.sh ${RED_HOME}/ 30 | 31 | VOLUME ["${RED_HOME}/data"] 32 | 33 | ENTRYPOINT ["/redbot/entrypoint.sh"] 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Red Discord Bot Docker 2 | 3 | ![Docker Hub Pulls](https://img.shields.io/docker/pulls/rhomelab/red-discordbot?logo=docker&label=docker%20hub%20pulls&style=for-the-badge) 4 | ![Docker Image Version (tag latest semver)](https://img.shields.io/docker/v/rhomelab/red-discordbot/latest?label=red%20version&logo=discord&style=for-the-badge) 5 | 6 | [Red Discord Bot](https://discord.red), now containerised. 7 | 8 | > [!NOTE] 9 | > This is an unsupported deployment method for Red. Do not expect support from the developers of Red Discord Bot if you run into any issues. 10 | 11 | > [!WARNING] 12 | > BREAKING CHANGE: Additional `redbot` arguments passed via `EXTRA_ARGS` must now be passed as described in [Additional Options](#additional-options). 13 | 14 | * [Tags](#tags) 15 | * [Environment Variables](#environment-variables) 16 | * [Additional Options](#additional-options) 17 | * [Setup](#setup) 18 | * [Prerequisites](#prerequisites) 19 | * [Running the bot with `docker compose`](#running-the-bot-with-docker-compose) 20 | * [Running the bot with `docker run`](#running-the-bot-with-docker-run) 21 | * [Migrating from `rhomelab:labbot`](#migrating-from-rhomelablabbot) 22 | 23 | ## Tags 24 | 25 | | **Tags** | **Red version** | 26 | |:------------:|:--------------------------------------------------------------------------------:| 27 | | `latest` | [Latest release](https://github.com/Cog-Creators/Red-DiscordBot/releases/latest) | 28 | | x.x.x | See tag | 29 | 30 | ## Environment Variables 31 | 32 | | Name | Description | Type | Default | 33 | |---------------------------|-----------------------------------------------------------------------------------------|---------|----------| 34 | | `INSTANCE_NAME` | The name of your Red Bot instance.
Example: `MyBot` | string | `RedBot` | 35 | | `PREFIX` | Your bot's command prefix.
Example: `!` | string | | 36 | | `TOKEN` | Your bot token from Discord Developers. | string | | 37 | | `RPC_ENABLED` | Whether [RPC](https://docs.discord.red/en/stable/framework_rpc.html) is enabled or not. | boolean | `false` | 38 | | `RPC_PORT` | The port used by Red's RPC server, if enabled. | string | `6133` | 39 | | `TEAM_MEMBERS_ARE_OWNERS` | Treat Discord Developers application team members as owners. | boolean | `false` | 40 | | `PIP_REQUIREMENTS` | Optional space-separated list of pip packages to install. | string | | 41 | 42 | ### Additional Options 43 | 44 | If you wish to pass additional options to the `redbot` command, these can be added to the `command` option in [`docker-compose.yml`](docker-compose-example.yml) or appended to the `docker run` command. 45 | 46 | > [!WARNING] 47 | > Do not add arguments which conflict with existing environment variables, such as `--prefix`, `--rpc`, etc. 48 | 49 | > [!TIP] 50 | > You can see a full list of `redbot` options [here](https://github.com/rHomelab/Red-DiscordBot-Docker/blob/main/.github/redbot-arguments.txt). 51 | 52 | ## Setup 53 | 54 | See the [`docker-compose-example.yml`](docker-compose-example.yml) for a basic example of a working bot with Docker Compose. 55 | 56 | After running the steps below, your Red Discord Bot will be alive! 57 | 58 | ### Running the bot with Docker Compose 59 | 60 | Create a `docker-compose.yml` file based on the [example](docker-compose-example.yml) and configure the environment variables to suit your desired configuration. 61 | 62 | Be sure to update the `/opt/redbot` path if you wish your bot's persistent data to be stored elsewhere. 63 | 64 | Now run `docker compose up -d` and see your bot come alive! 65 | 66 | To retrieve the invitation URL, run `docker compose logs RedBot`. If you only started the container a few moments ago, you may need to wait a few seconds for the bot to be created, started, and connected. 67 | 68 | ### Running the bot with `docker run` 69 | 70 | Basic setup: 71 | 72 | ```bash 73 | docker run -d \ 74 | --name 'RedBot' \ 75 | -v /opt/redbot:/redbot/data \ 76 | -e "INSTANCE_NAME=RedBot" \ 77 | -e "PREFIX=^" \ 78 | -e "TOKEN=yourBotToken" \ 79 | ghcr.io/rhomelab/red-discordbot:latest 80 | ``` 81 | 82 | With extra command arguments (see [Additional Options](#additional-options) above), for example to allow mentioning the bot as an alternative to using the bot prefix: 83 | 84 | ```bash 85 | docker run -d \ 86 | --name 'RedBot' \ 87 | -v /opt/redbot:/redbot/data \ 88 | -e "INSTANCE_NAME=RedBot" \ 89 | -e "PREFIX=^" \ 90 | -e "TOKEN=yourBotToken" \ 91 | ghcr.io/rhomelab/red-discordbot:latest \ 92 | --mentionable 93 | ``` 94 | 95 | To retrieve the invitation URL, run `docker logs RedBot`. If you only started the container a few moments ago, you may need to wait a few seconds for the bot to be created, started, and connected. 96 | -------------------------------------------------------------------------------- /docker-compose-example.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | services: 3 | red-bot: 4 | image: ghcr.io/rhomelab/red-discordbot:latest 5 | container_name: RedBot 6 | restart: always 7 | # command: "" # Optional, default empty, e.g. --owner 8 | environment: 9 | INSTANCE_NAME: "RedBot" 10 | PREFIX: "^" 11 | TOKEN: "yourBotToken" 12 | # RPC_ENABLED: "false" # Optional, default false 13 | # RPC_PORT: "6133" # Optional, default 6133 14 | # TEAM_MEMBERS_ARE_OWNERS: "false" # Optional, default false 15 | # PIP_REQUIREMENTS: "" # Optional, space-separated list of pip requirements, default empty 16 | volumes: 17 | - /opt/redbot:/redbot/data 18 | -------------------------------------------------------------------------------- /redbot/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | chown -R ${RED_USER}:${RED_USER} ${RED_HOME}/data 5 | 6 | # Install pip packages and start Red as specified user 7 | exec runuser -u $RED_USER -- ${RED_HOME}/start-red.sh $@ 8 | -------------------------------------------------------------------------------- /redbot/requirements.txt: -------------------------------------------------------------------------------- 1 | pip 2 | wheel 3 | setuptools 4 | Red-DiscordBot==3.5.20 5 | -------------------------------------------------------------------------------- /redbot/start-red.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | # Define redbot arguments 5 | if [ -z "$INSTANCE_NAME" ]; then 6 | INSTANCE_NAME="RedBot" 7 | fi 8 | 9 | [ -z "$TOKEN" ] && echo "ERROR: Missing TOKEN environment variable" && exit 1 10 | [ -z "$PREFIX" ] && echo "ERROR: Missing PREFIX environment variable" && exit 1 11 | 12 | ARGS="$INSTANCE_NAME --token $TOKEN --prefix $PREFIX --no-prompt" 13 | 14 | if [ "$RPC_ENABLED" = 'true' ]; then 15 | ARGS="$ARGS --rpc" 16 | 17 | if [ -z "$RPC_PORT" ]; then 18 | ARGS="$ARGS --rpc-port 6133" 19 | else 20 | ARGS="$ARGS --rpc-port $RPC_PORT" 21 | fi 22 | fi 23 | 24 | if [ "$TEAM_MEMBERS_ARE_OWNERS" = 'true' ]; then 25 | ARGS="$ARGS --team-members-are-owners" 26 | fi 27 | 28 | # Append any arguments passed from cmdline 29 | [ -n "$EXTRA_ARGS" ] && echo "ERROR: EXTRA_ARGS is no longer supported. See https://github.com/rHomelab/Red-DiscordBot-Docker#additional-options" && exit 1 30 | ARGS="$ARGS $@" 31 | 32 | if [ -n "$PIP_REQUIREMENTS" ]; then 33 | echo "Installing pip packages: $PIP_REQUIREMENTS" 34 | python3 -m pip install --no-cache-dir --user $PIP_REQUIREMENTS 35 | echo 36 | fi 37 | 38 | # Ensure Red instance exists 39 | echo "Checking for existing Red instances..." 40 | if redbot --list-instances | grep -qe '^No instances have been configured!'; then 41 | echo "No Red instance found. Creating instance '$INSTANCE_NAME'..." 42 | 43 | { 44 | redbot-setup --instance-name "$INSTANCE_NAME" --no-prompt --data-path /redbot/data && \ 45 | echo "Red instance '$INSTANCE_NAME' created successfully. Starting...\n" 46 | } || { 47 | echo "Failed to create Red instance '$INSTANCE_NAME'." 48 | exit 1 49 | } 50 | else 51 | echo "Found Red instance '$INSTANCE_NAME'. Starting..." 52 | fi 53 | 54 | redbot $ARGS 55 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "docker-compose": { 7 | "digest": { 8 | "enabled": false 9 | } 10 | } 11 | } 12 | --------------------------------------------------------------------------------