Compare commits
4 commits
6bc668c0b7
...
bbf4473659
| Author | SHA1 | Date | |
|---|---|---|---|
| bbf4473659 | |||
|
|
a4ae929c4e | ||
|
|
7576c1636e | ||
|
|
113888b22b |
12 changed files with 150 additions and 29 deletions
|
|
@ -38,4 +38,10 @@
|
||||||
group = "grafana";
|
group = "grafana";
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
age.secrets.minecraft-seed = {
|
||||||
|
file = ./secrets/minecraft-seed.age;
|
||||||
|
owner = "root";
|
||||||
|
mode = "0400";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
{ config, pkgs, inputs, ... }:
|
{ config, pkgs, inputs, modulesPath, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
./agenix.nix
|
./agenix.nix
|
||||||
./modules/minecraft.nix
|
./modules/minecraft.nix
|
||||||
./modules/hardening.nix
|
./modules/hardening.nix
|
||||||
|
|
@ -42,16 +43,6 @@
|
||||||
htop
|
htop
|
||||||
tmux
|
tmux
|
||||||
rsync
|
rsync
|
||||||
|
|
||||||
(writeShellScriptBin "mc-whitelist" ''
|
|
||||||
docker exec minecraft rcon-cli whitelist add "$1"
|
|
||||||
'')
|
|
||||||
(writeShellScriptBin "mc-cmd" ''
|
|
||||||
docker exec minecraft rcon-cli "$@"
|
|
||||||
'')
|
|
||||||
(writeShellScriptBin "mc-logs" ''
|
|
||||||
docker logs --tail "''${1:-100}" -f minecraft
|
|
||||||
'')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
users.users.root.openssh.authorizedKeys.keys = [
|
users.users.root.openssh.authorizedKeys.keys = [
|
||||||
|
|
|
||||||
45
flake.nix
45
flake.nix
|
|
@ -17,19 +17,25 @@
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
serverHost = "root@compsigh-minecraft";
|
|
||||||
|
|
||||||
deploy = pkgs.writeShellScriptBin "nhs" ''
|
deploy = pkgs.writeShellScriptBin "nhs" ''
|
||||||
nh os switch --hostname compsigh-minecraft --target-host root@compsigh-minecraft path:. "$@"
|
nh os switch --hostname compsigh-minecraft --target-host root@compsigh-minecraft path:. "$@"
|
||||||
'';
|
'';
|
||||||
mcWhitelist = pkgs.writeShellScriptBin "mc-whitelist" ''
|
|
||||||
ssh ${serverHost} "docker exec minecraft rcon-cli whitelist add $1"
|
|
||||||
'';
|
|
||||||
mcCmd = pkgs.writeShellScriptBin "mc-cmd" ''
|
|
||||||
ssh ${serverHost} "docker exec minecraft rcon-cli $*"
|
|
||||||
'';
|
|
||||||
mcLogs = pkgs.writeShellScriptBin "mc-logs" ''
|
mcLogs = pkgs.writeShellScriptBin "mc-logs" ''
|
||||||
ssh ${serverHost} "docker logs --tail ''${1:-100} -f minecraft"
|
ssh root@compsigh-minecraft "docker logs --tail ''${1:-100} -f minecraft"
|
||||||
|
'';
|
||||||
|
bootstrap = pkgs.writeShellScriptBin "mc-bootstrap" ''
|
||||||
|
set -euo pipefail
|
||||||
|
IP="''${1:?Usage: mc-bootstrap <server-ip>}"
|
||||||
|
echo "==> Installing NixOS (bootstrap config with port 22 open)..."
|
||||||
|
nix run github:nix-community/nixos-anywhere -- --flake path:.#compsigh-minecraft-bootstrap "root@$IP"
|
||||||
|
echo ""
|
||||||
|
echo "==> Removing old host key..."
|
||||||
|
ssh-keygen -R "$IP"
|
||||||
|
echo ""
|
||||||
|
echo "==> Fetching new server host key..."
|
||||||
|
echo "Run: ssh root@$IP cat /etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
echo "Then update secrets/secrets.nix with the new key and run: agenix -r"
|
||||||
|
echo "Then run: nhs"
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
@ -44,11 +50,25 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Bootstrap config: opens port 22 on public interface for initial setup
|
||||||
|
nixosConfigurations.compsigh-minecraft-bootstrap = nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
specialArgs = { inherit inputs; };
|
||||||
|
modules = [
|
||||||
|
disko.nixosModules.disko
|
||||||
|
inputs.agenix.nixosModules.default
|
||||||
|
./disk-config.nix
|
||||||
|
./configuration.nix
|
||||||
|
{
|
||||||
|
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
devShells.${system}.default = pkgs.mkShell {
|
devShells.${system}.default = pkgs.mkShell {
|
||||||
packages = [
|
packages = [
|
||||||
deploy
|
deploy
|
||||||
mcWhitelist
|
bootstrap
|
||||||
mcCmd
|
|
||||||
mcLogs
|
mcLogs
|
||||||
pkgs.nh
|
pkgs.nh
|
||||||
inputs.agenix.packages.${system}.default
|
inputs.agenix.packages.${system}.default
|
||||||
|
|
@ -56,9 +76,8 @@
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
echo "compsigh minecraft server"
|
echo "compsigh minecraft server"
|
||||||
|
echo " mc-bootstrap — first-time install (mc-bootstrap <ip>)"
|
||||||
echo " nhs — deploy to server"
|
echo " nhs — deploy to server"
|
||||||
echo " mc-whitelist — add a player (mc-whitelist PlayerName)"
|
|
||||||
echo " mc-cmd — run rcon command (mc-cmd whitelist list)"
|
|
||||||
echo " mc-logs — tail server logs"
|
echo " mc-logs — tail server logs"
|
||||||
echo " agenix — manage secrets"
|
echo " agenix — manage secrets"
|
||||||
'';
|
'';
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ in
|
||||||
# minecraft.compsigh.club → redirect to git repo
|
# minecraft.compsigh.club → redirect to git repo
|
||||||
"${domain}" = {
|
"${domain}" = {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
|
redir /terms ${gitRepo}/blob/main/terms.txt permanent
|
||||||
|
redir /privacy ${gitRepo}/blob/main/privacy.txt permanent
|
||||||
redir ${gitRepo} permanent
|
redir ${gitRepo} permanent
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,17 @@ in
|
||||||
"channelId": "1482486447591391285",
|
"channelId": "1482486447591391285",
|
||||||
"consoleLogChannelId": "1482487413153464330",
|
"consoleLogChannelId": "1482487413153464330",
|
||||||
"useWebhook": true,
|
"useWebhook": true,
|
||||||
|
"updateChannelTopic": true,
|
||||||
|
"channelTopicUpdateInterval": 300000,
|
||||||
|
"allowedMentions": ["users", "roles"],
|
||||||
|
"broadcastPlayerCommandExecution": false,
|
||||||
"announceServerStartStop": true,
|
"announceServerStartStop": true,
|
||||||
"announcePlayerJoinLeave": true,
|
"announcePlayerJoinLeave": true,
|
||||||
"announceDeathMessages": true,
|
"announceDeathMessages": true,
|
||||||
"announceAdvancements": true,
|
"announceAdvancements": true,
|
||||||
"broadcastChatMessages": true,
|
"broadcastChatMessages": true,
|
||||||
|
"notifyUpdates": false,
|
||||||
|
"mentionAdminsForUpdates": false,
|
||||||
"adminsIds": [
|
"adminsIds": [
|
||||||
"1008533670426050704",
|
"1008533670426050704",
|
||||||
"839601350865584158",
|
"839601350865584158",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
allowedTCPPorts = [ 80 443 25565 ]; # Caddy HTTP/HTTPS + Minecraft
|
allowedTCPPorts = [ 80 443 25565 ]; # Caddy HTTP/HTTPS + Minecraft
|
||||||
allowedUDPPorts = [ 24454 ]; # Simple Voice Chat
|
allowedUDPPorts = [ 24454 ]; # Simple Voice Chat
|
||||||
trustedInterfaces = [ "tailscale0" ]; # Full access over Tailscale (SSH, etc.)
|
trustedInterfaces = [ "tailscale0" ]; # Full access over Tailscale (SSH, etc.)
|
||||||
|
checkReversePath = "loose"; # Required for Tailscale
|
||||||
logRefusedConnections = true;
|
logRefusedConnections = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,12 @@ let
|
||||||
# QoL
|
# QoL
|
||||||
"oneplayersleep"
|
"oneplayersleep"
|
||||||
"netherportalfix"
|
"netherportalfix"
|
||||||
|
"blossomlib"
|
||||||
|
"blossomtpa"
|
||||||
|
"double-shulker-shell-drops"
|
||||||
|
"afkplus"
|
||||||
|
|
||||||
# Moderation
|
# Moderation
|
||||||
"luckperms"
|
|
||||||
"banhammer"
|
|
||||||
"ledger"
|
"ledger"
|
||||||
"styled-chat"
|
"styled-chat"
|
||||||
|
|
||||||
|
|
@ -103,15 +105,19 @@ in
|
||||||
MEMORY = "2560M";
|
MEMORY = "2560M";
|
||||||
MAX_PLAYERS = "10";
|
MAX_PLAYERS = "10";
|
||||||
DIFFICULTY = "hard";
|
DIFFICULTY = "hard";
|
||||||
|
PVP = "FALSE";
|
||||||
VIEW_DISTANCE = "10";
|
VIEW_DISTANCE = "10";
|
||||||
SIMULATION_DISTANCE = "10";
|
SIMULATION_DISTANCE = "10";
|
||||||
ENABLE_WHITELIST = "TRUE";
|
ENABLE_WHITELIST = "TRUE";
|
||||||
ENFORCE_WHITELIST = "TRUE";
|
ENFORCE_WHITELIST = "TRUE";
|
||||||
WHITELIST = "jetpham";
|
WHITELIST = "jetpham";
|
||||||
MOTD = "meet cool people \\u0026\\u0026 build cool things";
|
OPS = "jetpham";
|
||||||
|
MOTD = "meet cool people \\u00A7e\\u0026\\u0026\\u00A7r build cool things";
|
||||||
|
OVERRIDE_ICON = "TRUE";
|
||||||
MODRINTH_PROJECTS = modrinthMods;
|
MODRINTH_PROJECTS = modrinthMods;
|
||||||
JVM_XX_OPTS = jvmFlags;
|
JVM_XX_OPTS = jvmFlags;
|
||||||
};
|
};
|
||||||
|
environmentFiles = [ "/run/minecraft-seed.env" ];
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
"--memory=3g"
|
"--memory=3g"
|
||||||
"--cpus=2"
|
"--cpus=2"
|
||||||
|
|
@ -126,14 +132,26 @@ in
|
||||||
"d ${mcDataDir} 0755 root root -"
|
"d ${mcDataDir} 0755 root root -"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Copy Chunky config (concurrency: 1 for background generation)
|
# Write seed env file and copy mod configs before container starts
|
||||||
systemd.services.minecraft-mod-configs = {
|
systemd.services.minecraft-mod-configs = {
|
||||||
description = "Copy mod configs into Minecraft data volume";
|
description = "Set up mod configs and seed for Minecraft container";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "docker-minecraft.service" ];
|
before = [ "docker-minecraft.service" ];
|
||||||
|
after = [ "agenix.service" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = pkgs.writeShellScript "setup-mod-configs" ''
|
ExecStart = pkgs.writeShellScript "setup-mod-configs" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Write seed from agenix secret
|
||||||
|
SEED=$(cat ${config.age.secrets.minecraft-seed.path})
|
||||||
|
printf 'SEED=%s\n' "$SEED" > /run/minecraft-seed.env
|
||||||
|
chmod 600 /run/minecraft-seed.env
|
||||||
|
|
||||||
|
# Server icon
|
||||||
|
cp ${../server-icon.png} ${mcDataDir}/server-icon.png
|
||||||
|
|
||||||
|
# Mod configs
|
||||||
mkdir -p ${mcDataDir}/plugins/Chunky
|
mkdir -p ${mcDataDir}/plugins/Chunky
|
||||||
cp ${../configs/chunky.yml} ${mcDataDir}/plugins/Chunky/config.yml
|
cp ${../configs/chunky.yml} ${mcDataDir}/plugins/Chunky/config.yml
|
||||||
|
|
||||||
|
|
|
||||||
45
privacy.txt
Normal file
45
privacy.txt
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
compsigh Minecraft — Privacy Policy
|
||||||
|
|
||||||
|
Last updated: 2026-03-14
|
||||||
|
|
||||||
|
1. What We Collect
|
||||||
|
- Minecraft username and UUID (required to join the server)
|
||||||
|
- Discord username and user ID (used for chat bridging and admin
|
||||||
|
commands)
|
||||||
|
- Chat messages sent in-game and in the bridged Discord channel
|
||||||
|
(relayed between platforms in real time)
|
||||||
|
- In-game actions (block placement, breakage, chest access, etc.)
|
||||||
|
logged by the Ledger mod for grief prevention
|
||||||
|
- Server logs (connection IPs, join/leave times, errors)
|
||||||
|
|
||||||
|
2. How Data Is Used
|
||||||
|
- Chat messages are bridged between Minecraft and Discord and are
|
||||||
|
visible in both platforms.
|
||||||
|
- Action logs are used solely for grief investigation and rollback.
|
||||||
|
- Server logs are used for debugging and moderation.
|
||||||
|
- Admin Discord user IDs are stored in the bot configuration to
|
||||||
|
control who can run server commands from Discord.
|
||||||
|
|
||||||
|
3. Data Storage
|
||||||
|
- World data and action logs are stored on the server and backed up
|
||||||
|
to Backblaze B2 cloud storage.
|
||||||
|
- Chat messages are stored by Discord per their own retention
|
||||||
|
policies. The server does not independently archive chat.
|
||||||
|
- Server logs are stored on the server and rotate automatically.
|
||||||
|
|
||||||
|
4. Data Sharing
|
||||||
|
We do not sell, share, or provide your data to any third party.
|
||||||
|
Backblaze B2 is used solely for encrypted backup storage.
|
||||||
|
|
||||||
|
5. Data Retention
|
||||||
|
- World backups are retained per our Backblaze B2 lifecycle policy.
|
||||||
|
- Server logs are retained for up to 30 days.
|
||||||
|
- In-game action logs persist in the world data indefinitely.
|
||||||
|
|
||||||
|
6. Your Rights
|
||||||
|
You may request to see what data we have about you or ask for its
|
||||||
|
deletion by contacting a server admin on Discord. Deleting your
|
||||||
|
data may require removing you from the whitelist.
|
||||||
|
|
||||||
|
7. Contact
|
||||||
|
For privacy questions, reach out to a server admin on Discord.
|
||||||
BIN
secrets/minecraft-seed.age
Normal file
BIN
secrets/minecraft-seed.age
Normal file
Binary file not shown.
|
|
@ -9,4 +9,5 @@ in
|
||||||
"b2-application-key.age".publicKeys = [ server admin ];
|
"b2-application-key.age".publicKeys = [ server admin ];
|
||||||
"grafana-admin-password.age".publicKeys = [ server admin ];
|
"grafana-admin-password.age".publicKeys = [ server admin ];
|
||||||
"grafana-secret-key.age".publicKeys = [ server admin ];
|
"grafana-secret-key.age".publicKeys = [ server admin ];
|
||||||
|
"minecraft-seed.age".publicKeys = [ server admin ];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
server-icon.png
Normal file
BIN
server-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 601 B |
32
terms.txt
Normal file
32
terms.txt
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
compsigh Minecraft — Terms of Service
|
||||||
|
|
||||||
|
Last updated: 2026-03-14
|
||||||
|
|
||||||
|
1. Acceptance
|
||||||
|
By joining the compsigh Minecraft server or interacting with the
|
||||||
|
compsigh Minecraft Discord bot, you agree to these terms and the
|
||||||
|
compsigh Code of Conduct: https://compsigh.club/docs/code-of-conduct
|
||||||
|
|
||||||
|
2. Minecraft Server Rules
|
||||||
|
In addition to the compsigh Code of Conduct:
|
||||||
|
- No griefing, cheating, or exploiting.
|
||||||
|
- Server admins reserve the right to ban players at their discretion.
|
||||||
|
|
||||||
|
3. Access
|
||||||
|
The server is whitelist-only. Access may be granted or revoked at
|
||||||
|
any time without notice.
|
||||||
|
|
||||||
|
4. Availability
|
||||||
|
The server is provided as-is with no uptime guarantees. It may go
|
||||||
|
offline for maintenance, updates, or any other reason.
|
||||||
|
|
||||||
|
5. Data
|
||||||
|
See our Privacy Policy for details on what data is collected and how
|
||||||
|
it is used.
|
||||||
|
|
||||||
|
6. Changes
|
||||||
|
These terms may be updated at any time. Continued use of the server
|
||||||
|
constitutes acceptance of any changes.
|
||||||
|
|
||||||
|
7. Contact
|
||||||
|
For questions, reach out to a server admin on Discord.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue