In your docker build try this sequence:

USER root
RUN apt-get clean -yq && apt-get update -yq && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openjdk-11-jdk
USER ${ISC_PACKAGE_MGRUSER}


Or install sudo (very bad practice in containers):

USER root
RUN apt-get clean -yq && apt-get update -yq && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata curl gnupg ca-certificates sudo
RUN /bin/echo -e ${ISC_PACKAGE_MGRUSER}\\tALL=\(ALL\)\\tNOPASSWD: ALL >> /etc/sudoers
RUN sudo -u ${ISC_PACKAGE_MGRUSER} sudo echo enabled passwordless sudo-ing for ${ISC_PACKAGE_MGRUSER}
USER ${ISC_PACKAGE_MGRUSER}

I think what you'll need is a write stream method below (I haven't had a chance to test this so the code comes with no guarantees). This will work for Non-Shared web-socket connections since I don't have the chance to test with shared pools at the moment.

Method Send(message As %Library.DynamicObject) As %Integer
{
    Set stream = ##class(%Stream.TmpCharacter).%New()
    Do message.Msg.%ToJSON(stream)
    Set sc = ..WriteStream(stream)
    If $$$ISERR(sc) $$$SysLog(2,"WebSocket","[Write] Error WRITE Stream on JSON Command",sc)
    quit 1
}

Method WriteStream(data As %Stream.Object) As %Status
{
	Set $ZTrap="WriteError"
	If i%WSClassProtocolVersion > 1 & i%WSDataFraming = 1 {
		Set head=$ZLChar(data.Size)
		If i%BinaryData = 1 {
			Set head=head_"8"
		} Else {
			Set head=head_"7"
		}
	} Else {
		Set head=""
	}
	#; As there is activity on this session reset the session timeout
	Set sc=$$updateTimeout^%SYS.cspServer(i%SessionId) If $$$ISERR(sc) $$$SysLog(2,"WebSocket","[Write] Error updating session timeout",sc)
	#; Only return an error status if there's an issue with the write itself.
	Set sc=$$$OK
	If (i%SharedConnection = 1) {
        // If you want to try and play with the shared pools and large payloads, move the commented code to the loop below

		#; Set sc=$$CSPGWClientRequest^%SYS.cspServer3(i%GWClientAddress,"WSW "_i%WebSocketID_" "_head_data1,-5,.response)
		#; If $$$ISERR(sc) $$$SysLog(2,"WebSocket","[Write] Error sending request",sc)
        $$$SysLog(2,"WebSocket","[Write] Shared Connections Don't Support Stream Sizes over 3.6MB",sc)
        Quit $$$Error($$$GeneralError, "[Write] Shared Connections Don't Support Stream Sizes over 3.6MB")
	} else {
        SET sc = $$$OK
        // Write header
		Write head
        // Rewind Stream
        Do data.Rewind()
        // Loop through stream and write 64kb chunks
        while (data.AtEnd = 0) {
            // Set Buffer to 64KB
            Set BUFSZ = 65536
            // Read Buffer
            SET BUFBLOCK = data.Read(.BUFSZ)
            // Convert UTF8 if we aren't using Binary Web Sockets
            If i%BinaryData '= 1 {
                Try {
                    Set BUFBLOCK=$zconvert(BUFBLOCK,"O","UTF8")
                } Catch exp {
                    $$$SysLog(2, "WebSocket", "[Write] Exception: "_exp.DisplayString(), data)
                    Set BUFBLOCK=BUFBLOCK
                }
            }
            // Use DEVICE WRITE method
            Write BUFBLOCK
            // Quit when done with stream
            BREAK:(BUFSZ < 65536)
        }
        // Send a flush command mnow
        Write *-3
        Quit sc
	}
	Quit sc
WriteError	
	#; No interrupts during cleanup or error processing
	Do event^%SYS.cspServer2("WebSocket Write Error: "_$ZError)
	$$$SetExternalInterrupts(0)
	Set $ZTrap="WriteHalt"
	Hang 5
	Close 0
WriteHalt 
	Halt
    
}

Have you tried wrapping your message call (Ens.Director and OnProcessInput) in a class on the target machine.

/// -------- This is on the source machine
/// Source (LIS) Method
ClassMethod ConnectAndCall(host, port, namespace, user, pwd) As %Status
{
    // Our object is defined somewhere
    #dim TRAN As %RegisteredObject = $$$NULLOREF
    Set sc = $$$OK
    // Connect to our HC machine
    set connection = ##class(%Net.DB.DataSource).CreateConnection(host, port, namespace, user, pwd)
    if 'connection.IsConnected set ERRTXT="NotConnected" quit $$$Error($$$GeneralError, "Couldn't connect")
    set irisC=connection.CreateIris()
 
    // Instead of multiple calling with response objects wrap everything on the client
    set response = irisC.ClassMethodValue("Helpers.Ens", "SendMessage", "ServiceName", TRAN)
    do connection.Disconnect()
 
    Return sc
}
 
/// ---------- This is on the target machine
/// healthconnect method (target machine)
/// Classname: "Helpers.Ens.SendMessage()"
ClassMethod SendMessage(servicename, message) As %RegisteredObject
{
    // Find running job of servicename
    Set sc = ##class(Ens.Director).CreateBusinessService(servicename, .serviceHandle)
    // Call that service
    Set sc = serviceHandle.OnProcessInput(message, .response)
    return response
}

As far as I know, they should be included in the output. If you want to force it you can add a property parameter on the relationship. https://docs.intersystems.com/irisforhealth20221/csp/docbook/DocBook.UI....

// Relationship to be includeed in JSONExport using JSON adaptor
Relationship Ingredients as Food.Item(%JSONINCLUDE = "inout", %JSONREFERENCE = "object") [ Cardinality = one, Inverse = Recipe ];