├── .gitignore ├── 1. Setting Up.md ├── 2. Creating The Project.md ├── 3. Creating the Dockerfile and Running!.md ├── 4. docker-compose installation!.md ├── 5. Bot, Meet Redis.md ├── 6. Bot, meet PostgreSQL.md ├── 7. Bot needs a web panel!.md ├── README.md └── _config.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | -------------------------------------------------------------------------------- /1. Setting Up.md: -------------------------------------------------------------------------------- 1 | ### Welcome! 2 | In this guide, I will walk you through on how to get a bot started with Docker. The following example will be a simple bot that responds with a ping/pong command. 3 | 4 | This tutorial assumes you have some knowledge of a Unix-based operating system, terminal/command prompt commands, and a basic knowledge of creating a Discord bot using [discord.js](https://github.com/hydrabolt/discord.js). 5 | 6 |
7 | This tutorial uses the following: 8 | 9 | - NodeJS (7.6.x and above) 10 | - Docker (17.04.0 and above) 11 | 12 |
13 | 14 | ### What is Docker? 15 | Docker is a project that automates the deployment of application inside of software containers. This means it will have it's own kernel, system, operating system, etc without directly effecting the host operating system. To put it in easier terms: You put your application inside a mini-fridge. Take that mini-fridge and put it inside of the big refrigerator. The fridge being the server. It has no effect on the fridge's internal mechanisms, and it keeps it "running" inside it's own happy little world. 16 | 17 | 18 | 19 | Let's get you setup with both! 20 | 21 | ### Installing Docker and NodeJS 22 | > If you have Windows 10 Pro: [Docker CE For Windows](https://store.docker.com/editions/community/docker-ce-desktop-windows) 23 | 24 | > If you have Windows 10 Home: [Docker Toolbox for Windows](https://www.docker.com/products/docker-toolbox) 25 | 26 | > If you have Mac: [Docker CE For Mac OS](https://store.docker.com/editions/community/docker-ce-desktop-mac) 27 | 28 | > If you have Mac (All-in-one installer): [Docker Toolbox for Mac OS](https://www.docker.com/products/docker-toolbox) 29 | 30 | > If you use Debian/Ubuntu: ``sudo apt install docker`` 31 | 32 | > If you use a Pacman-based Distro: ``sudo pacman -S docker`` 33 | 34 | > If you use a RHEL-based Distro: ``sudo yum install docker`` 35 | 36 | 37 | 38 | I personally use NVM on Linux, but on Windows/Mac make sure you have the latest version of NodeJS (not LTS at the moment) installed as features used with ``discord.js`` are not supported fully as I will be taking advantage of them. 39 | 40 | > Windows: [NodeJS For Windows](https://nodejs.org/) 41 | 42 | > Other: [NodeJS](https://nodejs.org/) 43 | 44 | You can verify the versions you installed by executing the following: 45 | 46 | 47 | > Docker: ``docker -v`` 48 | 49 | > Node: ``node -v`` 50 | 51 | 52 | Once you have the latest of both for your system installed, let's move on to creating the bot! 53 | -------------------------------------------------------------------------------- /2. Creating The Project.md: -------------------------------------------------------------------------------- 1 | ## Creating the project. 2 | Let's get started on creating the bot itself. For this, you will need to create a project folder, install dependencies, etc. 3 | 4 | Let's do that now! (You will need to know how to ) 5 | 6 | ### Creating the project 7 | 8 | #### Linux, Mac, WSL (Bash for Windows) 9 | 1. ``mkdir my-discord-bot && cd my-discord-bot/`` - This will create the folder for the project and enter in to it. 10 | 2. ``touch index.js && npm init --yes`` - This creates a file called ``index.js`` and initializes the project using NPM. 11 | 3. ``touch Dockerfile`` - This creates a file for Docker to read from. I will get into this in a later step. 12 | 4. ``npm install hydrabolt/discord.js --save`` - This installs the later master branch of discord.js which is recommended. 13 | 5. ``touch settings.json`` - This creates a configuration file that stores our bot's token. 14 | 15 | #### Windows 16 | 1. ``mkdir my-discord-bot && cd my-discord-bot/`` - This will create the folder for the project and enter in to it. 17 | 2. ``type nul > index.js && npm init --yes`` - This creates a file called ``index.js`` and initializes the project using NPM. 18 | 3. ``type nul > Dockerfile`` - This creates a file for Docker to read from. I will get into this in a later step. 19 | 4. ``npm install hydrabolt/discord.js --save`` - This installs the later master branch of discord.js which is recommended. 20 | 5. ``type nul > settings.json`` - This creates a configuration file that stores our bot's token. 21 | 22 |
23 | 24 | ### Opening the project 25 | You will now open our new project in your favorite IDE/editor. I personally use Visual Studio Code, but use whatever you want to make yourself more comfortable. 26 | 27 | 28 | Now open your new settings.json. This is the format we will be using: 29 | ```json 30 | { 31 | "token": "--your bots token--" 32 | } 33 | ``` 34 | and save that. This will store our bot's information to be used on startup. 35 | 36 | 37 | ### Creating the bot itself! 38 | 39 | Inside of ``index.js``, we will create the bot. Here is an example I will be using: 40 | 41 | ```js 42 | const { Client } = require('discord.js'); 43 | const { token } = require('./settings'); 44 | const client = new Client(); 45 | 46 | client.on('ready', () => console.log('Ready!')); 47 | 48 | client.on('message', (msg) => { 49 | if (msg.author.bot) return; 50 | 51 | if (msg.content.startsWith('!ping')) { 52 | msg.channel.send('!gnip'); 53 | } 54 | }); 55 | 56 | client.login(token); 57 | ``` 58 | 59 | Now running the bot with ``node index.js`` inside our console, the bot should now respond with ``!gnip`` when presented with ``!ping``! 60 | 61 | Great! Now everything is up and running, let's put this inside a container. 62 | -------------------------------------------------------------------------------- /3. Creating the Dockerfile and Running!.md: -------------------------------------------------------------------------------- 1 | ### Creating the Dockerfile 2 | Remember in the last tutorial when we had ran ``touch Dockerfile`` to create a file in our project called ``Dockerfile``? Well this is where Docker gets the information it needs to create a new container for our bot. 3 | 4 | Opening the ``Dockerfile``, it should be blank. Well, let's get started! 5 | 6 | The first thing we need to do is define the image (or operating system/project) our bot will be using. 7 | 8 | Since we use the latest from NodeJS, our first line should be: 9 | ```Dockerfile 10 | FROM node:latest 11 | ``` 12 | 13 | Now we need to create a directory from our bot to run inside (which is called the working directory) 14 | ```Dockerfile 15 | # Create the directory! 16 | RUN mkdir -p /usr/src/bot 17 | WORKDIR /usr/src/bot 18 | ``` 19 | 20 | That's great and all, but we also need to tell Docker where our bot is. 21 | ```Dockerfile 22 | # Copy and Install our bot 23 | COPY package.json /usr/src/bot 24 | RUN npm install 25 | ``` 26 | 27 | But.. that just installs the packages. We need to now copy our project over as well. So let's add that as well! 28 | ```Dockerfile 29 | # Our precious bot 30 | COPY . /usr/src/bot 31 | ``` 32 | 33 | Our bot is now inside a container! Nyah!~~~~ 34 | 35 | .. but wait. Where and how is it going to run? Well now, we need to tell docker how to run the bot. Duh! 36 | Inside the Dockerfile, you'll add the following: 37 | ```Dockerfile 38 | # Start me! 39 | CMD ["node", "index.js"] 40 | ``` 41 | 42 | Huzzah! We have successfully created a docker file for our bot. Now our bot container will know what to do on startup and be all happy and plush. 43 | 44 | 45 | Now let's take a look at the finished product! 46 | ```Dockerfile 47 | FROM node:latest 48 | 49 | # Create the directory! 50 | RUN mkdir -p /usr/src/bot 51 | WORKDIR /usr/src/bot 52 | 53 | # Copy and Install our bot 54 | COPY package.json /usr/src/bot 55 | RUN npm install 56 | 57 | # Our precious bot 58 | COPY . /usr/src/bot 59 | 60 | # Start me! 61 | CMD ["node", "index.js"] 62 | ``` 63 | 64 | ### Building our container 65 | Now, inside our bot's directory we need to now build this nice little cozy container for our bot. 66 | 67 | We will be executing: 68 | ``` 69 | $ docker build -t my-bot . 70 | ``` 71 | 72 | If you want a sanity check, you can run ``docker images`` and it should be visible under that list. 73 | 74 | 75 | ### Running our container 76 | Running our bot with ``-d`` runs the container in detatched mode (as in it runs in the background). If you want to see what is happening, remove that option. 77 | Let's get to it! Running the following: 78 | ``` 79 | $ docker run -d my-bot 80 | ``` 81 | Will deploy our bot to it's own nice little server to play with. 82 | 83 | ### More information 84 | If you want more of a sanity check here are some following commands you can run! 85 | 86 | ``` 87 | # Get the container! 88 | $ docker ps 89 | 90 | # Print the logs 91 | $ docker logs 92 | ``` 93 | 94 | That will give us our information and current running logs. 95 | 96 | If you need to get inside the container (and it's tempting, I know) you can run: 97 | ``` 98 | $ docker exec -it /bin/bash 99 | ``` 100 | 101 | That will put us inside our bot's little world so we can play around with it. 102 | 103 | In the next tutorial, I will cover ``docker-compose`` and setting up our bot with it's own private little PostgreSQL container! -------------------------------------------------------------------------------- /4. docker-compose installation!.md: -------------------------------------------------------------------------------- 1 | ## docker-compose 2 | 3 | 4 | ### What is it?! 5 | docker-compose is a tool used to create, define, and "orchastrate" many docker containers at once. That way your bot can have some friends! 6 | They will not be inside the same container as the bot, but more like neighbors. 7 | We will be using it to give our bot a database using PostgreSQL. You can fill free to use any database you want, just visit [Docker Hub](https://hub.docker.com) to search for your particular option. 8 | 9 | 10 | ### Installation 11 | You have a few choices here. You can use the one provided by your distributions repos (or Windows), or get the latest source by installing ``python3-pip``. 12 | 13 | 14 | > python3-pip: ``pip install docker-compose`` 15 | 16 | > Ubuntu/Debian: ``sudo apt install docker-compose`` 17 | 18 | > RHEL: ``sudo yum install docker-compose`` 19 | 20 | > Pacman: ``sudo pacman -S docker-compose`` 21 | 22 | > cURL: ``curl -L https://github.com/docker/compose/releases/download/1.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose`` 23 | 24 | > Windows: [docker-compose x86](https://github.com/docker/compose/releases/download/1.12.0/docker-compose-Windows-x86_64.exe) 25 | 26 | > Mac: Use cURL. 27 | 28 | 29 | ### Check if it's installed 30 | You can check if docker-compose is installed by running ``docker-compose --version`` 31 | 32 | 33 | ### What is docker-compose.yml? 34 | Ah, that will be covered in the next tutorial when I explain it throughly, give an example and show you how to orchastrate your own docker-compose file to fit your needs. 35 | 36 | 37 | [ CHECK BACK SOON! ] -------------------------------------------------------------------------------- /5. Bot, Meet Redis.md: -------------------------------------------------------------------------------- 1 | ## Bot, meet Redis! 2 | 3 | ### What's going on here?! 4 | Okay so, let's say you want an administrative panel (or a rest api) for your bot. What's the best way to access all that information? Having express embedded in my app? No. Don't be silly! Seperate them! That way, your bot can focus on being a bot, and your web project doesn't interfere with any operations. 5 | 6 | ### What are we going to make? 7 | We're going to use that simple ping-pong bot, and add something called ``discord.js-redis`` to it. We don't want to install a redis server on our operating system, but we would like to keep the data in place. So that way we can transfer it to our hosting platform (not heroku) after we think it's good! 8 | 9 | ### Re-creating the bot and Dockerfile 10 | First things first, you'll need to install and create the bot again so let's do that now. Let's setup the project, you can modify everything like the ``package.json`` later. 11 | 12 | ``` 13 | $ npm init --yes 14 | $ npm install discord.js spec-tacles/discord.js-redis --save 15 | $ touch Dockerfile docker-compose.yml bot.js settings.json 16 | ``` 17 | 18 |
19 | 20 | Before we hit the bot, I want to discuss something. We created the ``Dockerfile`` in Part 3, that used an image call 'node' from [Docker Hub](https://hub.docker.com/), this time around we're going to go with the ``alpine`` image. The reason is it is smaller and gives you more control of what you want (image manipulation libraries, ffmpeg, etc) in your container, so let's do that now. 21 | 22 | ```Dockerfile 23 | FROM alpine:latest 24 | 25 | # Setup Work directory. 26 | WORKDIR /usr/src/bot 27 | COPY package.json settings.json ./ 28 | 29 | # Let's install everything! 30 | RUN apk add --update \ 31 | && apk add --no-cache nodejs-current nodejs-npm \ 32 | && apk add --no-cache --virtual .build git curl build-base g++ \ 33 | && npm install \ 34 | && apk del .build 35 | 36 | # Copy project to our WORKDIR 37 | COPY . . 38 | 39 | # Let's run it! 40 | CMD [ "node", "bot.js" ] 41 | ``` 42 | 43 |
44 | 45 | The main reason we went this route is for more control as I said, now we will begin modifying and creating a brand new bot with a settings file we touched earlier (``settings.json``) 46 | 47 | ```json 48 | { 49 | "token": "TOKEN HERE", 50 | "prefix": "?" 51 | } 52 | ``` 53 | 54 |
55 | 56 | Now that that's over, let's work on the bot a bit from the example in Part 2. I'll explain what's happening within the code itself as it's easier that way. 57 | 58 | In the file ``bot.js``, we're going to go ahead and do this: 59 | 60 | ```js 61 | /** 62 | This is the requirement / dependency setup. 63 | I did it this way to create a cleaner look. 64 | Although, absolutely not required. 65 | */ 66 | const { token, prefix } = require('settings.json'); 67 | const { Client } = require('discord.js'); 68 | const { RedisClient } = require('discord.js-redis'); 69 | 70 | /** 71 | We're now setting up both our Bot client and our Redis 72 | client here. 73 | */ 74 | const client = new Client(); 75 | 76 | /** 77 | Redis client using discord.js-redis. 78 | When using the constructor for discord.js-redis you can specific options for 79 | node-redis as well (such as amount of databases, host, port, password, etc) 80 | */ 81 | const redis = new RedisClient(client, {}); 82 | 83 | /** 84 | Fire events! 85 | */ 86 | redis.on('ready', () => console.log('Redis ready!')); 87 | client.on('ready', () => console.log('Discord ready!')); 88 | 89 | /* 90 | Message Handler 91 | */ 92 | client.on('message', (msg) => { 93 | if (msg.author.bot) return; 94 | 95 | if (message.content.startsWith(prefix + 'ping')) { 96 | msg.channel.send('!gnip'); 97 | } 98 | }); 99 | 100 | /** 101 | Start and login. 102 | */ 103 | client.login(token); 104 | ``` 105 | 106 | Okay so, I know that using ``.startsWith(prefix + command)`` isn't the best, but just go with it for now. :p 107 | 108 |
109 | Okay, so now that we have that in order, we still need to create the ``docker-compose`` file. I'll explain each step here like I did with the ``Dockerfile`` in Part 3. 110 | 111 | First, open it (duh.). Once inside you'll notice that it's not JSON or XML, it's YAML. YAML is a basic whitespace markup language (so be mindful of your tabs and spaces). I use version 3, but you might need to use version 2 depending on how you installed docker-compose. 112 | 113 | ```yml 114 | version: '3' 115 | services: 116 | bot: 117 | build: . 118 | restart: always 119 | depends_on: 120 | - redis 121 | ``` 122 | 123 | Okay, so, what exactly is going on here? We're seperating everything into services (might require some modification on your part) to keep everything seperate. 124 | 125 | > ``version: '3'`` -> This is the docker-compose version, like I said, you might need to change this depending on install method. 126 | 127 | > ``services: bot:`` -> This is our service bot name. 128 | 129 | > ``build: .`` -> This will build our Dockerfile from scratch 130 | 131 | > ``restart: always`` -> If something say breaks on the container-level, or something fails, it will restart, always under any circumstance (other options: "no", on-failure, unless-stopped) 132 | 133 | > ``depends_on:`` -> What our bot will depend and link with, in our case redis. 134 | 135 | But Nomsy, we didn't setup redis yet, what's up with that? 136 | Okay yeah, we haven't. So let's do that now taking the ``docker-compose.yml`` file we have just created: 137 | 138 | ```yml 139 | version: '3' 140 | services: 141 | bot: 142 | build: . 143 | restart: always 144 | depends_on: 145 | - redis 146 | redis: 147 | image: redis:3.0-alpine 148 | ``` 149 | 150 | Yup, that's it. You can setup and use environmental variables and even where storage goes as well. You can see more here: [Compose-file Manual](https://docs.docker.com/compose/compose-file/) 151 | 152 | ### Build, run. 153 | Now that we have done all of this work to sandbox our bot with it's own database, let's give it a shot! 154 | 155 | ``` 156 | $ docker-compose up 157 | ``` 158 | 159 | You'll notice that you'll be instantly teleported into an installer, then the instance and bot itself. If you want to run it as a "background service", add the option ``-d`` after ``up`` which daemonizes the container(s) to the background. 160 | 161 | 162 | That's it! I'll provide more information and add more to the guide at a later date. If you need me I'm on various servers around the net, just ping me (Nomsy). 163 | 164 | > AUTHORS NOTE: Will add environmental variable setups instead of a configuration file as it's easier to maintain and change and it _just works_. Will also add PostgreSQL and a rest server setup using this setup in a later tutorial. Will also add modifying and viewing to the redis db to the bot in the future. STAY TUNED! 165 | 166 | Thanks for reading! See ya soon! 167 | -------------------------------------------------------------------------------- /6. Bot, meet PostgreSQL.md: -------------------------------------------------------------------------------- 1 | # COMING SOON 2 | -------------------------------------------------------------------------------- /7. Bot needs a web panel!.md: -------------------------------------------------------------------------------- 1 | # COMING SOON 2 | (maybe) 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Welcome! 2 | In this guide, I will walk you through on how to get a bot started with Docker. The following example will be a simple bot that responds with a ping/pong command. 3 | 4 | This tutorial assumes you have some knowledge of a Unix-based operating system, terminal/command prompt commands, and a basic knowledge of creating a Discord bot using [discord.js](https://github.com/hydrabolt/discord.js). 5 | 6 |
7 | This tutorial uses the following: 8 | 9 | - NodeJS (7.6.x and above) 10 | - Docker (17.04.0 and above) 11 | 12 |
13 | 14 | ### Guide 15 | 16 | 1. Step 1: [Setting Up](https://github.com/truency/docker-discordjs-tutorial/blob/master/1.%20Setting%20Up.md) 17 | 2. Step 2: [Creating The Project](https://github.com/truency/docker-discordjs-tutorial/blob/master/2.%20Creating%20The%20Project.md) 18 | 3. Step 3: [Creating the Dockerfile and Running!](https://github.com/truency/docker-discordjs-tutorial/blob/master/3.%20Creating%20the%20Dockerfile%20and%20Running!.md) 19 | 4. Step 4: [Using Docker Compose](https://github.com/truency/docker-discordjs-tutorial/blob/master/4.%20docker-compose%20installation!.md) 20 | 5. Step 5: [Bot, Meet Redis](https://github.com/truency/docker-discordjs-tutorial/blob/master/5.%20Bot%2C%20Meet%20Redis.md) 21 | 6. * More tutorials may be coming soon! 22 | 23 | ### What is Docker? 24 | Docker is a project that automates the deployment of application inside of software containers. This means it will have it's own kernel, system, operating system, etc without directly effecting the host operating system. To put it in easier terms: You put your application inside a mini-fridge. Take that mini-fridge and put it inside of the big refrigerator. The fridge being the server. It has no effect on the fridge's internal mechanisms, and it keeps it "running" inside it's own happy little world. -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal --------------------------------------------------------------------------------