E&K Labs
Published in

E&K Labs

Deploying the JDA discord bot with Docker

Recently, I am working on moving the web service I have developed so far to Docker. But even though Python is a scripting language, when an application developed with Python is built on my laptop, architecture errors often occur.

This is an unexpected and fatal issue for me, whose development laptop is an m1 MacBook, and even the Discord bot has more library functions than the code I wrote, so the project itself became unusable. (It was an issue with grpc of Google Translate API.)

For this reason, it was necessary to re-develop, and I was also interested in the JVM language, so I decided to move the chatbot application to Java.

However, there were a lot of difficulties in deploying the bot locally and moving it to Docker because of a lack of deployment materials and no experience in Java.

Modify build.gradle

The first thing I did was edit the build.gradle.

Unlike when using gradle for Android, there is no run script, so you need to create a jar, but there is an issue that there is no specific metadata or dependency library.

Gradle - no main manifest attribute

To solve this issue, I added a specific property for the jar directly to build.gradle.

tasks.jar {
manifest.attributes['Main-Class'] = 'BotEntry'
}

There is no package, so only the class name is there, just write the package path.

There was also an issue where the dependency class didn’t exist.

Exception in thread "main" java.lang.NoClassDefFoundError:

I looked for several ways to do this, but the most convenient task in the process of deployment was to include the dependency library, and for this, the shadowJar plugin was used.

plugins {
id 'java'
id "com.github.johnrengelman.shadow" version "7.1.2"
}

...

tasks.jar {
finalizedBy shadowJar
manifest.attributes['Main-Class'] = 'BotEntry'
}

When I let Jar have a lot of information and run it as a command, the bot works normally.

When using some of Google’s features, the following policy issues may occur.

Could not find policy 'pick_first'

To solve this, the mergeServiceFiles() below has been added.

shadowJar {
mergeServiceFiles()
}

Create a Docker image

Now that the build and execution are successful, the next step is to build the Docker image.

This is the full Dockerfile I used.

FROM gradle:7.4.2-jdk17 AS buildMAINTAINER "nv.noelvalent@gmail.com"COPY . /opt/gTranstateOnDiscord
WORKDIR /opt/gTranstateOnDiscord
RUN gradle jar --no-daemonFROM openjdk:17RUN mkdir /opt/appCOPY --from=build /opt/gTranstateOnDiscord/build/libs/gTranstateOnDiscord-1.0-SNAPSHOT-all.jar /opt/app/gTranstateOnDiscord-1.0-SNAPSHOT-all.jarENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-jar","/opt/app/gTranstateOnDiscord-1.0-SNAPSHOT-all.jar"]

I created a Jar file with the Gradle image, copied the built Jar file as a JDK image, and then ran the app using the java command.

Wrap-up

I know that JDA is also used for some Minecraft PaaS services, but I didn’t know the deployment guide for it, and I seem to have wandered a bit because I have no experience in deploying Java applications.

I hope this article is helpful to someone like me who wants to service a chatbot using Docker.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store