Skip to content

Commit

Permalink
Add guides for building container images, setting up Gradle, and addi…
Browse files Browse the repository at this point in the history
…ng a `runDev` Gradle task.

Also:
- Update dependencies
- Update Java references to 21
  • Loading branch information
FluxCapacitor2 committed Jun 1, 2024
1 parent ca955dd commit 3d357d9
Show file tree
Hide file tree
Showing 11 changed files with 5,098 additions and 4,850 deletions.
6 changes: 6 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export default defineConfig({
directory: "intro",
},
},
{
label: "Development",
autogenerate: {
directory: "development",
},
},
{
label: "Guides",
autogenerate: {
Expand Down
9,641 changes: 4,804 additions & 4,837 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.3.4",
"@astrojs/starlight": "^0.15.2",
"astro": "^4.0.1",
"@astrojs/check": "^0.7.0",
"@astrojs/starlight": "^0.23.2",
"astro": "^4.9.2",
"astro-favicons": "^2.0.2",
"astro-robots-txt": "^1.0.0",
"sharp": "^0.32.5",
"starlight-links-validator": "^0.6.0",
"typescript": "^5.3.3"
"sharp": "^0.33.4",
"starlight-links-validator": "^0.9.0",
"typescript": "^5.4.5"
}
}
7 changes: 3 additions & 4 deletions src/content/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { defineCollection } from 'astro:content';
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
import { docsSchema } from "@astrojs/starlight/schema";
import { defineCollection } from "astro:content";

export const collections = {
docs: defineCollection({ schema: docsSchema() }),
i18n: defineCollection({ type: 'data', schema: i18nSchema() }),
docs: defineCollection({ schema: docsSchema() }),
};
2 changes: 1 addition & 1 deletion src/content/docs/deployment/1_baremetal.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Running BlueDragon on baremetal is the simplest way to run BlueDragon software,
## Prerequisites

- This guide assumes you're running on Linux. Other operating systems are not supported; though, you may be able to get it working on WSL.
- You must have Java 17 or later installed on your system and accessible in your `PATH`.
- You must have Java 21 or later installed on your system and accessible in your `PATH`.

## Installation

Expand Down
14 changes: 13 additions & 1 deletion src/content/docs/deployment/2_docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,15 @@ You should be able to see the songs by typing `/play` in-game.
### MongoDB

```sh
docker run -d -p 27017:27017 mongo
docker run -d -p 27017:27017 -v bluedragon_mongo_data:/data/db mongo
```

:::caution
This Docker command runs MongoDB without a password. In production, we recommend using the [MongoDB Community Kubernetes Operator](https://github.com/mongodb/mongodb-kubernetes-operator), which automatically creates credentials and stored them in a Secret.

At the very minimum, make sure port `27017` on your machine is not accessible from an external network.
:::

### LuckPerms

```sh
Expand Down Expand Up @@ -86,12 +92,18 @@ docker run -d \

### Minecraft Server

:::note
This command expects your minigames to be located in a directory called `games` inside your current working directory.
You can also [bake them into your image](/deployment/building-images) to make it more portable.
:::

```sh
git clone https://github.com/BlueDragonMC/Server
cd Server
docker build -t bluedragonmc/server:latest .
docker run \
-v /data/worlds:/data/worlds \
-v ./games:/server/games \
-e BLUEDRAGON_QUEUE_TYPE=IPC \
-e BLUEDRAGON_MONGO_CONNECTION_STRING=mongodb://mongo:27017 \
-e BLUEDRAGON_PUFFIN_HOSTNAME=puffin \
Expand Down
5 changes: 5 additions & 0 deletions src/content/docs/deployment/3_kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ Replace `<your registry url>` with your Docker registry, and apply the YAML to y

## Deploy Minecraft Server Fleet

:::note
This configuration assumes that your games are copied in to your container image.
For more information, see [this guide](/deployment/building-images).
:::

```yaml
apiVersion: "agones.dev/v1"
kind: Fleet
Expand Down
46 changes: 46 additions & 0 deletions src/content/docs/deployment/4_building_images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
slug: deployment/building-images
title: Building Container Images
---

When deploying BlueDragon with Docker or Kubernetes, you will need to create
a container image for your Minecraft server application.

To add your games to the base `BlueDragonMC/Server` image, you can create a basic Dockerfile that looks something like this:

```dockerfile
# Build the project into an executable JAR
FROM docker.io/library/gradle:8.6-jdk21 as build
# Copy build files and source code
COPY . /work
WORKDIR /work
# Run gradle in the /work directory
RUN /usr/bin/gradle --console=plain --info --stacktrace --no-daemon build

# Use each built game to make a new image on top of the base "server" image
FROM ghcr.io/bluedragonmc/server:latest

# Copy built game JARs
COPY --from=build /work/build/all-jars/*.jar /server/games/
```

Then, you can build your project and push the image to your registry:

```bash
docker build . -t <your registry url>/bluedragonmc/server-full:latest
docker push <your registry url>/bluedragonmc/server-full:latest
```

Finally, you can start containers using this image which will have your games preinstalled.

:::note
This Dockerfile example assumes your project has a Gradle configuration similar to the one in [this guide](/development/gradle-run-task#copy-jars-to-a-central-location), where the JARs are copied to the `all-jars` directory after the project is built. If not, you can replace the `COPY --from=build` line with something like this:

```dockerfile
COPY --from=build /work/<yourgame1>/build/libs/*.jar /server/games/
COPY --from=build /work/<yourgame2>/build/libs/*.jar /server/games/
COPY --from=build /work/<yourgame3>/build/libs/*.jar /server/games/
# ...
```

:::
107 changes: 107 additions & 0 deletions src/content/docs/development/0_gradle-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
slug: development/gradle-setup
title: Gradle Setup
---

This guide will walk you through the way we recommend setting up Gradle for your games.
This is also how we created our Games repository internally.

:::note
This guide assumes you're using the [Kotlin DSL syntax](https://docs.gradle.org/current/userguide/kotlin_dsl.html) for Gradle.
If you are using Groovy, you will have to convert our examples to match your project.
:::

## Version Catalogs

If you use subprojects (mentioned later in this guide), we recommend setting up a Gradle [version catalog](https://docs.gradle.org/current/userguide/platforms.html).
This allows you to share dependency versions between multiple subprojects, and [Minestom uses it internally](https://github.com/Minestom/Minestom/blob/master/gradle/libs.versions.toml).

To set up a version catalog, follow [this guide](https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml) from the Gradle documentation.

## Subprojects

If you plan on making multiple games for your server (even a lobby and one minigame),
we recommend placing them all in one project so that they can share common code.

You should create a `common` Gradle subproject which your games can depend on. In that project,
you can write utilities, like methods that create packets or format chat messages.
You can also place common [game modules](/intro/example-game/#creating-a-game-module) in the `common` subproject. That way, all of your games can
import and `use` them.

Learn more about Gradle subprojects [here](https://docs.gradle.org/current/userguide/multi_project_builds.html).

### Setting up subprojects

1. Create a folder in the root of your project. Name it according to the name of your minigame.
2. Inside that folder, create two files: `build.gradle.kts` and `settings.gradle.kts`. These define the build configuration for the subproject.
3. In `build.gradle.kts`, configure your subproject to build its own JAR. For example:

```kotlin
group = "com.bluedragonmc.games"
version = "1.0-SNAPSHOT"

repositories {
mavenCentral()
maven(url = "https://jitpack.io")
}

dependencies {
// `libs.<name>` comes from the version catalog we set up earlier.
// See the "Version Catalogs" section of this guide for more information.
implementation(libs.server) // The BlueDragon core `Server` library, which provides a runtime and some common game modules
implementation(libs.bundles.configurate) // Sponge's `Configurate` library, which provides a configuration loader and some common (de)serializers
implementation(libs.minestom) // Include Minestom to compile against
}

tasks.getByName<Test>("test") { // Optional
useJUnitPlatform()
}
```

4. Configure your Gradle build settings.
```kotlin
// your-game/settings.gradle.kts
project.name = "yourgamename" // Should be the same name as the directory you created in Step 1.
// If you are using version catalogs, you may have to add something like this:
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
```
5. Include your subproject in your main project's build step. To do this, add the following to your root project's `settings.gradle.kts`:
```kotlin
// settings.gradle.kts
includeBuild(":<your project name>")
// Replace <your project name> with the name of the directory you created in Step 1.
// Make sure to keep the colon (:)
```
6. Create the source files for your project. In your subproject folder you created in Step 1, create the following directory structure:
```
Your Project Root/
(yourgamename)/
src/
main/
java/ <-- If you're using Java
com.yourcompany.yourproject/ <-- Your package name
Main.java <-- Your main class
kotlin/ <-- If you're using Kotlin
com.yourcompany.yourproject/ <-- Your package name
Main.kt <-- Your main class
resources/
game.properties
```
7. Open up the `game.properties` file and add this to it:
```properties
# Fill in these variables with your game's display name and its main class's fully-qualified name.
# For example, the `main-class` for ArenaPvP is `com.bluedragonmc.games.arenapvp.ArenaPvpGame`.
name=Your Game Name
main-class=com.yourcompany.yourproject.Main
```
8. In your `src` folder, create the package and main class you defined in Step 7. Make sure it extends the `com.bluedragonmc.server.Game` class.
9. Follow the [Creating a Game](/guides/creating-a-game) guide to start building your first game!

When you run a Gradle build on your root project, the subproject's JARs will be placed in `build/libs` inside your subproject's directory.
If you want them to be automatically copied to the root project or want a Gradle task to run a development server, see the [Gradle run task](/development/gradle-run-task) guide.
106 changes: 106 additions & 0 deletions src/content/docs/development/1_gradle-run-task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
slug: development/gradle-run-task
title: Gradle Run Task
---

BlueDragon projects currently have a lot of moving parts. You can automate most of the repetitive file copying with Gradle tasks. This guide provides a few examples to help you get a development environment up and running quickly.

:::note
This guide assumes you're using the [Kotlin DSL syntax](https://docs.gradle.org/current/userguide/kotlin_dsl.html) for Gradle.
If you are using Groovy, you will have to convert our examples to match your project.
:::

## Copy JARs to a central location

Here is an example of a Gradle task that will copy your subprojects' JARs after building.
Use this in conjunction with the [Subprojects section of the Gradle Setup guide](/development/gradle-setup#setting-up-subprojects).

```kotlin
// build.gradle.kts
// Copy all built game JARs to the root build folder
tasks.register("copyJars", Copy::class) {
subprojects.forEach { subproject ->
if (subproject.name == "testing" || subproject.name == "common") return@forEach // Exclude the `testing` and `common` projects
dependsOn(subproject.tasks.build) // Ensure this task runs after the subproject builds
from(subproject.buildDir.path + "/libs/" + subproject.name + "-1.0-SNAPSHOT.jar")
}
into("${buildDir}/all-jars")
}

// After the whole project is built, run the task we just created to copy the JARs
tasks.build.configure {
finalizedBy(tasks["copyJars"])
}
```

## Runnning a development server

The easiest way to run a dev server is using a Gradle task to copy the JARs and start the server for you.

### Developing the `Server` project

After adding the `copyJars` task from the prior section, add the following tasks to your Gradle build script.
This assumes you have cloned the [BlueDragonMC/Server](https://github.com/BlueDragonMC/Server/) project in a sibling directory to your games Gradle project.

```kotlin
// build.gradle.kts
// For development: copy build game JARs into the `run` folder
tasks.register("copyDev", Copy::class) {
dependsOn("copyJars")
from("${buildDir}/all-jars")
into("${projectDir}/run/games/")
}

// For development: build the sibling `Server` project
tasks.register("buildServerDev", Exec::class) {
workingDir = File(projectDir.parent, "Server")
commandLine = listOf("../Server/gradlew", "build", "-x", "test")
}

// For development: copy the `Server` project artifact to the `run` folder
tasks.register("copyServerDev", Copy::class) {
dependsOn("buildServerDev")
from("${projectDir}/../Server/build/libs/Server-1.0-SNAPSHOT-all.jar")
into("${projectDir}/run")
rename { "server.jar" }
}

tasks.register("cleanRunFolder", Delete::class) {
delete("${projectDir}/run/games", "${projectDir}/run/server.jar")
}

tasks.clean.configure {
dependsOn(tasks["cleanRunFolder"])
}

// For development: uses the outputs of the above tasks to start a dev server
tasks.register("runDev", Exec::class) {
dependsOn(tasks["copyServerDev"])
dependsOn(tasks["copyDev"])
workingDir = File(projectDir, "run")
commandLine = listOf("java", "-jar", "${projectDir}/run/server.jar")
}
```

Then, whenever you want to start a dev server, you can run `gradle runDev` or add it as an IntelliJ [run configuration](https://www.jetbrains.com/help/idea/run-debug-configuration.html).

### Using the prebuilt `Server` project

If you want to use the prebuilt `Server` project instead of cloning it locally, take the code from the last section and make the following modifications:

1. Delete the `buildServerDev` and `copyServerDev` task definitions
2. Remove the `dependsOn` call for `copyServerDev` in the `runDev` task definition.
3. In the `cleanRunFolder` task definition, remove `"${projectDir}/run/server.jar"` from the `delete` call.
4. Copy a compiled [BlueDragonMC/Server](https://github.com/BlueDragonMC/Server/) JAR into the `run` directory in your project. Rename it to `server.jar`.
5. You can now run `gradle runDev` to start a dev server using a precompiled BlueDragonMC/Server JAR!

### Runtime requirements

When you run the development server, you will need to start up two external services:

1. **MongoDB** for storing player data and permissions
2. **LuckPerms** for querying and updating player permissions

The easiest way to do this is with Docker. Follow [this guide](/deployment/docker#mongodb) to start them up, and make sure they are running when you use the `runDev` Gradle task. If not, the development server will fail to start.

If you do not have any permissions, follow [this guide](/deployment/docker#permissions) to give them to yourself.
2 changes: 1 addition & 1 deletion src/content/docs/intro/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sidebar:

## Requirements

1. You must have Java 17 or later installed.
1. You must have Java 21 or later installed.
2. This guide assumes you're using a Bash-like shell. Use Linux for best results; on Windows, you can modify the scripts or use [WSL](https://learn.microsoft.com/en-us/windows/wsl/).
3. [Docker](https://docs.docker.com/desktop/) is recommended to quickly run the required MongoDB and LuckPerms services.

Expand Down

0 comments on commit 3d357d9

Please sign in to comment.