private async Task CreateContainer(Server server) { _logger.LogInformation($"About to create container for server. ServerID: {server.ID}, ImageID: {server.Image.ID}"); var worldPath = _environment.BuildPath(_pathOptions.WorldDirectory, server.World.Path); var serverPropertiesPath = _environment.BuildPath(_pathOptions.ServerPropertiesDirectory, $"{server.ID}-server.properties"); var heapMax = server.MemoryAllocationMB; var heapStart = Convert.ToInt32(server.MemoryAllocationMB * 0.6); var javaOpts = $"JAVA_OPTS=-Xmx{heapMax}m -Xms{heapStart}m"; WriteServerProperties(server); var binds = new List <string> { $"{worldPath}:/server/world", $"{serverPropertiesPath}:/server/server.properties" }; if (server.Image.SupportsMods && server.Mods != null) { foreach (var mod in server.Mods) { var containerPath = $"/server/{server.Image.ModDirectory}/{mod.Path}"; var localPath = _environment.BuildPath(_pathOptions.ModDirectory, mod.Path); binds.Append($"{localPath}:{containerPath}"); } } var response = await _dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters { Image = server.Image.DockerId, Env = new List <string> { javaOpts }, ExposedPorts = new Dictionary <string, EmptyStruct>() { { "25565/tcp", new EmptyStruct() }, { "26565/udp", new EmptyStruct() }, { "27565/tcp", new EmptyStruct() } }, Labels = new Dictionary <string, string>() { { "creator", "mineman" } }, HostConfig = new HostConfig { Binds = binds, PortBindings = new Dictionary <string, IList <PortBinding> > { { "25565/tcp", new List <PortBinding> { new PortBinding { HostIP = "0.0.0.0", HostPort = server.MainPort.ToString() } } }, { "26565/udp", new List <PortBinding> { new PortBinding { HostIP = "0.0.0.0", HostPort = server.QueryPort.ToString() } } }, { "27565/tcp", new List <PortBinding> { new PortBinding { HostIP = "0.0.0.0", HostPort = server.RconPort.ToString() } } } }, RestartPolicy = new RestartPolicy { Name = RestartPolicyKind.UnlessStopped } } }); server.ContainerID = response.ID; server.NeedsRecreate = false; _context.Update(server); await _context.SaveChangesAsync(); await _infoClient.ImageBuildComplete(server.ID); }