docker-minecraft-server: If failure to auto-install CurseForge modpack, should continue if existing modpack already installed.

Enhancement Type

Improve an existing feature

Describe the enhancement

Server should try to use existing mod-packs installed if attempts to install mod-pack on startup fails (maybe with environment flag?)

Use case: Curse API (via cloudflare) is returning a 502 Bad Gateway after restarting the server and now server will not start up.

[init] Running as uid=1000 gid=1000 with /data as 'drwxrwxr-x 21 1000 1000 4096 Mar 28 16:55 /data'
[init] Resolved version given 1.19.2 into 1.19.2 and major version 1.19
[init] Resolving type given AUTO_CURSEFORGE
[mc-image-helper] 08:36:28.772 ERROR : 'install-curseforge' command failed. Version is 1.25.19
me.itzg.helpers.http.FailedRequestException: HTTP request of https://api.curse.tools/v1/cf/mods/search?gameId=432&slug=all-the-mods-8&classId=4471&latest=5600323 failed with 502 Bad Gateway: Fetching object content
	at me.itzg.helpers.http.FetchBuilderBase.lambda$failedRequestMono$1(FetchBuilderBase.java:151)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:132)
	at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:122)
	at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:128)
	at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:224)
	at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:113)
	at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:193)
	at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
	at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2071)
	at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:118)
	at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260)
	at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)
	at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:415)
	at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:431)
	at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:485)
	at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:712)
	at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:113)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1382)
	at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1245)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1294)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800)
	at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:499)
	at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:397)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Unknown Source)
	Suppressed: java.lang.Exception: #block terminated with an error
		at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99)
		at reactor.core.publisher.Mono.block(Mono.java:1710)
		at me.itzg.helpers.http.ObjectFetchBuilder.execute(ObjectFetchBuilder.java:34)
		at me.itzg.helpers.curseforge.CurseForgeInstaller.install(CurseForgeInstaller.java:128)
		at me.itzg.helpers.curseforge.InstallCurseForgeCommand.call(InstallCurseForgeCommand.java:145)
		at me.itzg.helpers.curseforge.InstallCurseForgeCommand.call(InstallCurseForgeCommand.java:23)
		at picocli.CommandLine.executeUserObject(CommandLine.java:2041)
		at picocli.CommandLine.access$1500(CommandLine.java:148)
		at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461)
		at picocli.CommandLine$RunLast.handle(CommandLine.java:2453)
		at picocli.CommandLine$RunLast.handle(CommandLine.java:2415)
		at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273)
		at picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
		at picocli.CommandLine.execute(CommandLine.java:2170)
		at me.itzg.helpers.McImageHelper.main(McImageHelper.java:132)
[init] ERROR failed to auto-install CurseForge modpack

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 24 (18 by maintainers)

Most upvoted comments

Right. In general it’s

  • performing an up to date check, if a file ID/matcher was not provided
  • resolving identifiers so that it can compare with the manifest file to see if that is already what is installed

So, sounds like there’s these pieces to address in the near term fix:

  • use CurseForge API directly, requiring API key
  • if no API key is provided, but any kind of manifest is present, then log a warning and continue anyway

The current image build includes the aspects discussed. Let me know if any new issues pop out from that.

Confirmed Temporary Workaround ✅

Set the following to the versions you need. In this case I have ATM8 1.0.15, Minecraft version 1.19.2, and Forge version 43.2.6

  environment:
      TYPE: FORGE
      VERSION: 1.19.2
      FORGEVERSION: 43.2.6

After setting that in my docker compose, the server started up and I was able to login to the server.

Make sure you have the correct versions here, or the server will likely crash due to version requirements.

https://github.com/itzg/docker-minecraft-server/issues/1576

“however, the code changes should allow for easily switching back if that proxy service goes away.” 😄 at least you knew it would be a problem eventually 🤣