This project allows you to run as many Minecraft server instances on AWS ECS Fargate (Elastic Container Service) as you like. You can interact with these instances using a Telegram Chat Bot hosted serverless on AWS Lambda to start and stop your Minecraft server.
Using IaC (Infrastructure-as-code) by Pulumi all you need is to run 1 command from your command line and everything is created automatically. Same goes for removal of the resources: You can remove everything by one simple command after you are done with your server.
🔥 Run as many Minecraft server instances with individual configuration as you can afford
☁️ Hosted on AWS
🤖 Start and stop your servers using a serverless Telegram Chat Bot
📂 Use S3 Datasync to interact with files in your server instance.
💰 Optionally: Use Fargate Spot instances to save up to 70% compared to regular ECS Fargate Deployment. In fact, an involuntarily conducted test showed me that a spot server costs about 0,63$ per day (1 vCPU | 8 GB) and was not interrupted once during 7 days.
- You have an AWS Account available
- Your CLI session is authorized to this AWS Account (How-To).
- You have installed Pulumi on your machine.
- You have cloned this git repository to your machine.
- You have
- created a Telegram Bot and copied it's Bot Token.
- Added this bot to a Telegram Group and extracted the chat id using GetUpdates on the Telegram API
To quickly get started with this project, follow these steps:
- Clone the repository:
git clone https://github.com/hghtwr/minecraft-ecs-telegram.git
cd minecraft-ecs-telegram
- Set the required environment variables:
export TELEGRAM_API_TOKEN=<Telegram BOT Token>
export TELEGRAM_CHAT_ID=<Telegram chat id>
- Install the Pulumi dependencies:
npm install
- Deploy the infrastructure using Pulumi:
pulumi up
After Pulumi is done with deployment, it automatically try to set the corresponding webhook of your Telegram bot.
The output should look something like this:
Outputs:
+ webhookResult: (json) {
+ description: "Webhook is set"
+ ok : true
+ result : true
}
Now you can start and stop your Minecraft server instances using the Telegram Chat Bot hosted on AWS Lambda:
- /start: Scales the server instances for this service to 1. Will print the IP of the server once it's ready to accept connections.
- /stop: Scales the server instance to 0. Will notify you once the server is shutdown.
- /status: Will print the IP of the server given it's up and running.
Customization of your servers is possible using the stack files in the repository (Pulumi..yaml).
You need to provide a unique awsmc:deploymentId
for each stack.
Configuration values are read from the stack file (Pulumi.<env>.yaml
) in the index.ts
file.
You have to use the prefix awsmc
for the configuration keys.
Important
You dont necessesarily have to set any values. All of them default to reasonable values.
config:
aws:region: eu-central-1 ## Use region of your choice -- Decide based on costs and latency :)
awsmc:deploymentId: "mc-ecs-dev" ## THIS MUST BE UNIQUE IN YOUR ACCOUNT!
awsmc:image: "itzg/minecraft-server:stable" ## Check the docker image doc's for more info on this: https://github.com/itzg/docker-minecraft-server
awsmc:cpu: "1024" ## See here for supported combinations of cpu and memory on Fargate: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html
awsmc:memory: "4096"
awsmc:useSpotInstance: "true"
awsmc:gameMode: "survival"
awsmc:difficulty: "normal"
awsmc:onlineMode: "false"
awsmc:serverName: "Pulumi Minecraft Server"
awsmc:modt: "Welcome to Pulumi Minecraft Server :)"
awsmc:version: "1.20.2"
[...] ## add more from the list below
Attribute | Explanation |
---|---|
modt | Message of the Day (MOTD) displayed in the Minecraft server list |
difficulty | Difficulty level of the Minecraft server (e.g., "peaceful", "easy", "normal", "hard") |
gameMode | Game mode of the Minecraft server (e.g., "survival", "creative", "adventure", "spectator") |
onlineMode | Determines if the Minecraft server checks player usernames with Mojang's servers (true/false) |
serverName | Name of the Minecraft server |
maxPlayers | Maximum number of players allowed on the Minecraft server |
version | Version of Minecraft server to use |
rcon | Remote Console (RCON) password for managing the Minecraft server |
icon | Path to the server icon displayed in the Minecraft server list |
maxWorldSize | Maximum size of the Minecraft world in blocks |
allowNether | Determines if the Nether dimension is enabled (true/false) |
announcePlayerAchievements | Determines if player achievements are announced in chat (true/false) |
enableCommandBlock | Determines if command blocks are enabled (true/false) |
forceGameMode | Determines if players are forced into the server's game mode (true/false) |
generateStructures | Determines if structures (e.g., villages, dungeons) are generated in the Minecraft world |
snooperEnabled | Determines if server data is sent to Mojang for statistics (true/false) |
maxBuildHeight | Maximum height in blocks that can be built in the Minecraft world |
spawnAnimals | Determines if animals spawn in the Minecraft world (true/false) |
spawnMonsters | Determines if monsters spawn in the Minecraft world (true/false) |
spawnNpcs | Determines if NPCs (Non-Player Characters) spawn in the Minecraft world (true/false) |
viewDistance | Maximum number of chunks that clients can see from the server (higher values require more memory) |
levelSeed | Seed used to generate the Minecraft world |
pvp | Determines if player versus player combat is allowed (true/false) |
levelType | Type of Minecraft world to generate (e.g., "default", "flat", "largeBiomes") |
resourcePack | URL or file path to a resource pack to use in the Minecraft server |
resourcePackSHA1 | SHA-1 hash of the resource pack file for verification |
resourcePackEnforce | Determines if the resource pack is enforced for all players (true/false) |
level | Name of the Minecraft world to load |
allowFlight | Determines if players can fly in the Minecraft world (true/false) |
customServerProperties | Additional custom server properties |
- Copy & Paste the
Pulumi.dev.yaml
file and rename it toPulumi.test.yaml
- Customize the values to your needs
- Run
pulumi stack select
and create a new stack namedtest
. - Run
pulumi up
to create a complete new and independent set of infrastructure for your servers.
Most of the files can be edited by using the values described above. To fiddle around with the file system the package automatically creates S3 Datasync tasks and an S3 Bucket to shift data around. Go to S3 DataSync and use the corresponding tasks to copy data from the EFS file system to the S3 bucket and vice versa.
You can use RCON on port 25575, a password is automatically created during creation. You can find it in the environment variables of the task definition (I'm too lazy to implement AWS Secrets Manager for this right now, feel free to do so).
Feel free to open issues and PR's :)
Big shoutout to Minecraft Docker