Self-Hosting
Host the bot and its services yourself on a machine you own
Step 2: Prepare your server
To set up the bot and its services, we first need to prepare our server. The steps may vary slightly depending on your server's operating system. Choose the instructions that match your OS. This guide assumes you have basic command line and server-managing skills.
Step 3: Setup and configure the bot
Once our server is prepared, we can proceed to download and configure the bot by following these steps:
Clone the bot's repository to your server
Open a terminal window and paste in the following:
# Clone the GitHub repository to our local machine:
git clone -b main --single-branch --depth 1 https://github.com/ahmadk953/poixpixel-discord-bot.git
# Change-Directory into the bot's directory:
cd poixpixel-discord-botNow, we can start configuring the bot
Configure the bot
Run the following to copy the config.example.json file to a new file named config.json. This is where we'll store all our bot configuration options, including the bot's token.
# Copy and rename config.example.json to config.json:
cp config.example.json config.jsonNext, open the new config.json file in a text editor like vim or nano on Mac/Linux, or Visual Studio Code on Windows. When you open the file, it should look something like this:
{
"token": "DISCORD_BOT_TOKEN",
"clientId": "DISCORD_BOT_ID",
"guildId": "DISCORD_SERVER_ID",
"database": {
"dbConnectionString": "POSTGRESQL_CONNECTION_STRING",
"maxRetryAttempts": "MAX_RETRY_ATTEMPTS",
"retryDelay": "RETRY_DELAY_IN_MS"
},
"redis": {
"redisConnectionString": "REDIS_CONNECTION_STRING",
"retryAttempts": "RETRY_ATTEMPTS",
"initialRetryDelay": "INITIAL_RETRY_DELAY_IN_MS"
},
"channels": {
"welcome": "WELCOME_CHANNEL_ID",
"logs": "LOG_CHANNEL_ID",
"counting": "COUNTING_CHANNEL_ID",
"factOfTheDay": "FACT_OF_THE_DAY_CHANNEL_ID",
"factApproval": "FACT_APPROVAL_CHANNEL_ID",
"advancements": "ADVANCEMENTS_CHANNEL_ID"
},
"roles": {
"joinRoles": [
"JOIN_ROLE_IDS"
],
"levelRoles": [
{
"level": "LEVEL_NUMBER",
"roleId": "ROLE_ID"
},
{
"level": "LEVEL_NUMBER",
"roleId": "ROLE_ID"
},
{
"level": "LEVEL_NUMBER",
"roleId": "ROLE_ID"
}
],
"staffRoles": [
{
"name": "ROLE_NAME",
"roleId": "ROLE_ID"
},
{
"name": "ROLE_NAME",
"roleId": "ROLE_ID"
},
{
"name": "ROLE_NAME",
"roleId": "ROLE_ID"
}
],
"factPingRole": "FACT_OF_THE_DAY_ROLE_ID"
},
"leveling": {
"xpCooldown": "XP_COOLDOWN_IN_SECONDS",
"minXpAwarded": "MINIMUM_XP_AWARDED",
"maxXpAwarded": "MAXIMUM_XP_AWARDED"
}
}To configure your bot, follow these steps:
Replace
DISCORD_BOT_TOKENwith your bot's token.Replace
DISCORD_BOT_IDwith your bot's Client ID.Replace
DISCORD_SERVER_IDwith your server's ID.Replace the following with corresponding IDs you've collected:
WELCOME_CHANNEL_IDLOG_CHANNEL_IDJOIN_ROLE_IDS
After completing these replacements, your configuration should look like this:
{
"token": "MTM*****************************",
"clientId": "1361135180999561387",
"guildId": "1237197296714907678",
"database": {
"dbConnectionString": "POSTGRESQL_CONNECTION_STRING",
"maxRetryAttempts": "MAX_RETRY_ATTEMPTS",
"retryDelay": "RETRY_DELAY_IN_MS"
},
"redis": {
"redisConnectionString": "REDIS_CONNECTION_STRING",
"retryAttempts": "RETRY_ATTEMPTS",
"initialRetryDelay": "INITIAL_RETRY_DELAY_IN_MS"
},
"channels": {
"welcome": "1361198468340912319",
"logs": "1361198724864540693",
"counting": "COUNTING_CHANNEL_ID",
"factOfTheDay": "FACT_OF_THE_DAY_CHANNEL_ID",
"factApproval": "FACT_APPROVAL_CHANNEL_ID",
"advancements": "ADVANCEMENTS_CHANNEL_ID"
},
"roles": {
"joinRoles": [
"1361197760530874528",
"1362199066343375103"
],
"levelRoles": [
{
"level": "LEVEL_NUMBER",
"roleId": "ROLE_ID"
},
{
"level": "LEVEL_NUMBER",
"roleId": "ROLE_ID"
},
{
"level": "LEVEL_NUMBER",
"roleId": "ROLE_ID"
}
],
"staffRoles": [
{
"name": "ROLE_NAME",
"roleId": "ROLE_ID"
},
{
"name": "ROLE_NAME",
"roleId": "ROLE_ID"
},
{
"name": "ROLE_NAME",
"roleId": "ROLE_ID"
}
],
"factPingRole": "FACT_OF_THE_DAY_ROLE_ID"
},
"leveling": {
"xpCooldown": "XP_COOLDOWN_IN_SECONDS",
"minXpAwarded": "MINIMUM_XP_AWARDED",
"maxXpAwarded": "MAXIMUM_XP_AWARDED"
}
}We'll fill in the details for the caching and PostgreSQL databases later. Lastly, let's get the bot ready for when we eventually start it up.
Setup and compile the source code
Open a terminal window in the projects root directory and run the following commands to install dependencies and compile the source code.
# Install dependencies (if asked to continue, press 'y' and hit enter for yes):
yarn install --immutable
# Invoke build tools:
yarn prepare
# Compile source code:
yarn compileNow that we've finished preparing the bot, let's move onto setting up its resources
Step 4: Set up the PostgreSQL and caching databases
Now, it's time to set up the bot's services. Follow the steps below to set up the PostgreSQL and caching databases.
Generate SSL certificates
If on Windows, type the following into your terminal. If you're on Linux/MacOS, you can skip this step.
# Launch WSL:
wsl
# Head into the directory where the bot's files are located:
cd /mnt/DRIVELETTER/PATH/TO/DISCORD/BOT/DIRECTORYMake sure to replace DRIVELETTER/ATH/TO/DISCORD/BOT/DIRECTORY with the path to your bot's directory as you normally would. For example:
cd /mnt/c/Users/ahmad/Downloads/poixpixel-discord-botThere's already a shell script in the project's directory that'll generate the SSL certificates for you. Just run the following commands to execute the script:
# Make the script executable:
chmod +x generate-certs.sh
# Run the script:
./generate-certs.shNow that we have the SSL certificates set up, we can move onto configuring environment variables for our Docker containers. Windows users can now switch back to their normal terminals by simply closing and re-opening their terminals.
Set up environment variables
Run the following to copy the .env.example file to a new file named .env. This is where our database username and password, as well as our caching database's password will live.
# Copy and rename .env.example to .env:
cp .env.example .envNext, open the new .env file. You should see something like this:
POSTGRES_USER=your_postgres_user
POSTGRES_PASSWORD=your_postgres_password
POSTGRES_DB=your_database_name
VALKEY_PASSWORD=your_valkey_passwordTo configure your bot's resources, follow these steps:
Replace
your_postgres_userwith your desired username for connecting to the database.Replace
your_postgres_passwordwith a secure password for the database user you just specified.Substitute
your_database_namewith a name for the Postgres database that will store your bot's data.Replace
your_valkey_passwordwith a password for your Valkey database, which serves as a caching database.
When you're done, your config file should look like this:
POSTGRES_USER=bot-user
POSTGRES_PASSWORD=password
POSTGRES_DB=bot-db
VALKEY_PASSWORD=passwordWith our bot's resources configured, let's launch their Docker containers.
Spin up the Docker containers
This step is relatively simple; all you have to do is run the command below to start up the Docker containers
# Spin up the Docker containers:
docker compose up -dAnd in case you need to stop the containers:
# Stop the containers WITHOUT deleting and removing them:
docker compose stop
# Stop the containers and DELETE/REMOVE THEM. Note your DATA WILL BE SAFE. This just deletes the actual Docker containers:
docker compose downLastly, to restart the containers and view their logs, you can run the following commands:
# Restart the Docker containers:
docker compose restart
# View Docker container logs:
docker compose logsOnce all the bot's resources are operational, let's complete the configuration and start it up.
Step 5: Finish bot configuration
Now that we have the bot's resources up and running, let's finish configuring it. Open the config.json file again and scroll to the section that look like this:
"database": {
"dbConnectionString": "POSTGRESQL_CONNECTION_STRING",
"maxRetryAttempts": "MAX_RETRY_ATTEMPTS",
"retryDelay": "RETRY_DELAY_IN_MS"
},You can use the following template to obtain the PostgreSQL connection string: postgresql://username:password@localhost/database.
Since the bot and the Postgres instance run on the same server, the format should be: postgresql://username:password@localhost/database.
Fill out the format as follows:
Replace
usernamewith the value from thePOSTGRES_USERenvironment variable.Replace
passwordwith the value from thePOSTGRES_PASSWORDenvironment variable.Replace
databasewith the value from thePOSTGRES_DBenvironment variable.
Once updated, it should look like this example: postgresql://bot-user:password@localhost/bot-db. Replace POSTGRESQL_CONNECTION_STRING with this value.
Lastly, replace MAX_RETRY_ATTEMPTS with the desired maximum number of connection attempts. Then, change RETRY_DELAY_IN_MS to specify the wait time in milliseconds between retries. You should now have something that look like this:
"database": {
"dbConnectionString": "postgresql://bot-user:password@localhost/bot-db",
"maxRetryAttempts": "5",
"retryDelay": "2000"
},Next, scroll down to the section that looks like this:
"redis": {
"redisConnectionString": "REDIS_CONNECTION_STRING",
"retryAttempts": "RETRY_ATTEMPTS",
"initialRetryDelay": "INITIAL_RETRY_DELAY_IN_MS"
},You can use the following template to obtain the Redis (in our case, Valkey since they're compatible with each other) connection string: redis://username:password@host:port.
In our case, this is the format we'll be using: redis://default:password@localhost:6379. All you have to do is replace password with the value you set for the VALKEY_PASSWORD environment variable. Replace REDIS_CONNECTION_STRING with this value.
Lastly, replace RETRY_ATTEMPTS with the desired maximum number of connection attempts. Then, change INITIAL_RETRY_DELAY_IN_MS to specify the wait time in milliseconds between retries. You should now have something that look like this:
"redis": {
"redisConnectionString": "redis://default:password@localhost:6379",
"retryAttempts": "3",
"initialRetryDelay": "3000"
},Now, let's proceed to set up the tables in our database and start the bot.
Step 6: Set up database tables
To set up the database tables, all you have to do is run the following commands:
# Generate SQL migration file:
npx drizzle-kit generate
# Apply SQL migration to database:
npx drizzle-kit migrateNow, we can finally start the bot.
Step 7: Start the bot
To start the bot, simply run the following:
# Start the bot in production mode:
yarn start:prodTo view the bot's logs, type in this command:
# To view bot logs:
pm2 logsTo stop the bot, run this command:
# To stop the bot:
pm2 stop poixpixel-discord-botFinally, go to your Discord server and test out the bot's commands to make sure that it's working. Once you have verified that it is working, you can move onto reading about some of the bot's basic configuration options linked below.
Basic ConfigurationLast updated
Was this helpful?



