Skip to content

Image Templates — Code-Driven Approach

Problem

The itzg/minecraft-server image requires MAX_MEMORY and INIT_MEMORY env vars to respect the order's provisioned memory. Without them, the JVM defaults to 1 GB regardless of how much memory was allocated. The flow had no access to order.resources, so there was no place to inject these.

Solution

Move all deployment-level concerns out of the flow and into the blueprint, which already receives order: &Order.

Flow's responsibility: capture user choices only — loader, difficulty, online_mode, use_optimization_flags.

Blueprint's responsibility: turn those choices + order resources into the full deployment spec — image tag, entrypoint, all env vars (including resource-derived ones).

This keeps the system consistent: blueprints, flows, and service kinds are all code. There is no separate "template" entity or DB table.

What Changed

  • MinecraftConfiguration now stores only user choices. The image and env fields are kept as Option with #[serde(default)] for backwards-compatible deserialization of orders already in the DB.

  • MinecraftSetupFlow::into_output() is now trivial — it just copies the relevant state fields into MinecraftConfiguration.

  • MinecraftBlueprint now owns all image/env logic:

  • resolve_image(): derives the itzg image tag from java_for_minecraft_version(). Falls back to the stored mc.image for legacy orders.
  • build_env_from_config(): builds the full env map from user choices.
  • build_env(): calls build_env_from_config() (or uses the legacy stored env), then always overwrites MAX_MEMORY and INIT_MEMORY from current order.resources.memory (with a 128 MB headroom for JVM overhead).

Legacy Backwards-Compatibility

Orders already provisioned have MinecraftConfiguration.image and .env populated in their stored JSONB. The blueprint uses them as a base and then overwrites the resource-derived vars on top, so existing orders get the fix automatically on their next reprovisioning without requiring a data migration.

Once all active orders have been reprovisioned under the new system, the image and env fields can be removed from MinecraftConfiguration.

Adding a New Game Type

The pattern to follow:

  1. Define TerrariaConfiguration with user-facing choices only.
  2. Add Terraria(TerrariaConfiguration) to OrderServiceConfig and CatalogServiceKind.
  3. Implement TerrariaSetupFlow — gathers user choices, into_output() just captures them.
  4. Implement TerrariaBlueprint — resolves image, builds env, returns Vec<ProvisionSpec>.

No DB tables, no migrations, no separate template entity.