- Go 82%
- Makefile 16%
- Dockerfile 1.4%
- Shell 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .devcontainer | ||
| .forgejo/workflows | ||
| .github/workflows | ||
| api/v1alpha1 | ||
| cmd | ||
| config | ||
| hack | ||
| internal | ||
| test | ||
| .dockerignore | ||
| .gitignore | ||
| .golangci.yml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| PROJECT | ||
| README.md | ||
minecraftinator
// TODO(user): Add simple overview of use/purpose
Description
// TODO(user): An in-depth paragraph about your project and overview of use
Getting Started
Prerequisites
- go version v1.26.0+
- docker version 17.03+.
- kubectl version v1.11.3+.
- Access to a Kubernetes v1.11.3+ cluster.
To Deploy on the cluster
Build and push your image to the location specified by IMG:
make docker-build docker-push IMG=<some-registry>/minecraftinator:tag
NOTE: This image ought to be published in the personal registry you specified. And it is required to have access to pull the image from the working environment. Make sure you have the proper permission to the registry if the above commands don’t work.
Install the CRDs into the cluster:
make install
Deploy the Manager to the cluster with the image specified by IMG:
make deploy IMG=<some-registry>/minecraftinator:tag
NOTE: If you encounter RBAC errors, you may need to grant yourself cluster-admin privileges or be logged in as admin.
Create instances of your solution You can apply the samples (examples) from the config/sample:
kubectl apply -k config/samples/
NOTE: Ensure that the samples has default values to test it out.
To Uninstall
Delete the instances (CRs) from the cluster:
kubectl delete -k config/samples/
Delete the APIs(CRDs) from the cluster:
make uninstall
UnDeploy the controller from the cluster:
make undeploy
Project Distribution
Following the options to release and provide this solution to the users.
By providing a bundle with all YAML files
- Build the installer for the image built and published in the registry:
make build-installer IMG=<some-registry>/minecraftinator:tag
NOTE: The makefile target mentioned above generates an 'install.yaml' file in the dist directory. This file contains all the resources built with Kustomize, which are necessary to install this project without its dependencies.
- Using the installer
Users can just run 'kubectl apply -f ' to install the project, i.e.:
kubectl apply -f https://raw.githubusercontent.com/<org>/minecraftinator/<tag or branch>/dist/install.yaml
By providing a Helm Chart
- Build the chart using the optional helm plugin
operator-sdk edit --plugins=helm/v1-alpha
- See that a chart was generated under 'dist/chart', and users can obtain this solution from there.
NOTE: If you change the project, you need to update the Helm Chart using the same command above to sync the latest changes. Furthermore, if you create webhooks, you need to use the above command with the '--force' flag and manually ensure that any custom configuration previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml' is manually re-applied afterwards.
Contributing
// TODO(user): Add detailed information on how you would like others to contribute to this project
NOTE: Run make help for more information on all potential make targets
More information can be found via the Kubebuilder Documentation
License
Copyright 2026.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Minecraft console over SSH
The optional SSH gateway is a separate deployment with one shared LoadBalancer
Service (minecraftinator-ssh) for all servers and namespaces. The operator
continues to manage Minecraft resources independently; the gateway has read-only
Kubernetes permissions and routes authorized commands to each server's private
RCON port. Adding a MinecraftServer does not create another SSH Service.
Each login selects one MinecraftServer using <namespace>.<resource-name> as the SSH username. Add the
user's public key to that resource:
spec:
sshAuthorizedKeys:
- "ssh-ed25519 AAAA... user@laptop"
Use complete public keys, without authorized_keys options or certificates. An
empty list disables access. Every authorized key grants full Minecraft command
access, including stop, op, and world administration. Authorization is checked
again before each command, so removing a key revokes existing sessions too.
Create a persistent SSH host key once, and store it in a Kubernetes Secret:
kubectl create namespace minecraftinator-system --dry-run=client -o yaml | kubectl apply -f -
ssh-keygen -t ed25519 -N '' -f ./ssh_host_ed25519_key
kubectl -n minecraftinator-system create secret generic minecraftinator-ssh-host-key \
--from-file=ssh_host_ed25519_key=./ssh_host_ed25519_key
ssh-keygen -lf ./ssh_host_ed25519_key.pub
Keep the private key out of source control. Retain the Secret across deployments so that users see a stable SSH host identity. Verify the host fingerprint above when connecting for the first time.
Build and push the controller image as described above, set its reference, and
apply the SSH overlay (in place of make deploy):
(cd config/ssh && ../../bin/kustomize edit set image controller=<registry>/minecraftinator:<tag>)
bin/kustomize build config/ssh | kubectl apply -f -
kubectl -n minecraftinator-system get service minecraftinator-ssh
Connect to that Service's external IP or hostname:
ssh -i ~/.ssh/id_ed25519 -l default.minecraftserver-sample <ssh-host>
# minecraft> list
# minecraft> say Hello from SSH
# minecraft> exit
# Single commands also work:
ssh -i ~/.ssh/id_ed25519 -l default.minecraftserver-sample <ssh-host> 'list'
For a local Kind cluster without a LoadBalancer implementation, forward the SSH Service to your machine, then use port 22222:
kubectl -n minecraftinator-system port-forward service/minecraftinator-ssh 22222:22
# In another terminal:
ssh -p 22222 -i ~/.ssh/id_ed25519 -l default.minecraftserver-sample 127.0.0.1
Allow at least 4 GiB RAM for the container VM when running Kind and Minecraft locally; a 2 GiB VM ran out of memory during the integration test.
All users connect to the same <ssh-host>:22; only their username and authorized
key change. For example, these consoles share the same endpoint:
ssh -l games.survival <ssh-host>
ssh -l games.creative <ssh-host>
ssh -l another-namespace.survival <ssh-host>
Minecraft game Services are unchanged and remain separate from this SSH endpoint. The proxy does not expose a raw RCON port or require client-side RCON software.
The gateway forwards commands to the selected server's private RCON port and reads
its password from the existing <resource-name>-rcon Secret. Users do not need
Kubernetes credentials or the RCON password. SSH encrypts the client-to-gateway
connection; the RCON hop stays inside the cluster and is not encrypted. Allow the
gateway to reach Minecraft pods on TCP 25575 when using NetworkPolicies. The public
Minecraft Service continues to expose only the game port.
The console provides command responses, not a live server-log stream. exit or
Ctrl-D disconnects. OS shells, SFTP and SSH port forwarding are disabled. A failed
command is never retried automatically because it may already have executed.
For local development:
go run ./cmd/gateway --ssh-bind-address=:2222 \
--ssh-host-key=/path/to/ssh_host_ed25519_key
The gateway needs Kubernetes credentials and network access to Minecraft pod IPs. The operator binary does not accept SSH connections.
To migrate from an older deployment that served SSH inside the operator, apply the
updated config/ssh overlay with an image containing both binaries. The existing
Service name, SSH host-key Secret, usernames, and authorized keys stay the same;
existing SSH sessions disconnect during the rollout.