code: def deploy_to_container(
      node_type_enum: NodeType,
      deployment_type_enum: DeploymentType,
      node_side_type: NodeSideType,
      reset: bool,
      cmd: bool,
      tail: bool,
      verbose: bool,
      tag: str,
      render: bool,
      dev_mode: bool,
      port: Union[int, str],
      name: str,
      enable_warnings: bool,
      in_memory_workers: bool,
  ) -> Optional[NodeHandle]:
      if port == "auto" or port is None:
          if container_exists(name=name):
              port = port_from_container(name=name, deployment_type=deployment_type_enum)  # type: ignore
          else:
              port = find_available_port(
                  host="localhost", port=DEFAULT_PORT, search=True
              )
  
      # Currently by default we launch in dev mode
      if reset:
          Orchestra.reset(name, deployment_type_enum)
      else:
          if container_exists_with(name=name, port=port):
              return NodeHandle(
                  node_type=node_type_enum,
                  deployment_type=deployment_type_enum,
                  name=name,
                  port=port,
                  url="http://localhost",
                  node_side_type=node_side_type,
              )
  
      # Start a subprocess and capture its output
      commands = ["hagrid", "launch"]
  
      name = random_name() if not name else name
      commands.extend([name, node_type_enum.value])
  
      commands.append("to")
      commands.append(f"docker:{port}")
  
      if dev_mode:
          commands.append("--dev")
  
      if not enable_warnings:
          commands.append("--no-warnings")
  
      if in_memory_workers:
          commands.append("--in-mem-workers")
  
      # by default , we deploy as container stack
      if deployment_type_enum == DeploymentType.SINGLE_CONTAINER:
          commands.append("--deployment-type=single_container")
  
      if cmd:
          commands.append("--cmd")
  
      if tail:
          commands.append("--tail")
  
      if verbose:
          commands.append("--verbose")
  
      if tag:
          commands.append(f"--tag={tag}")
  
      if render:
          commands.append("--render")
  
      # needed for building containers
      USER = os.environ.get("USER", getpass.getuser())
      env = os.environ.copy()
      env["USER"] = USER
  
      process = subprocess.Popen(  # nosec
          commands,
          stdout=subprocess.PIPE,
          stderr=subprocess.PIPE,
          text=True,
          env=env,
      )
      # Start threads to read and print the output and error streams
      stdout_thread = Thread(target=read_stream, args=(process.stdout,))
      stderr_thread = Thread(target=read_stream, args=(process.stderr,))
      # todo, raise errors
      stdout_thread.start()
      stderr_thread.start()
      stdout_thread.join()
      stderr_thread.join()
  
      if not cmd:
          return NodeHandle(
              node_type=node_type_enum,
              deployment_type=deployment_type_enum,
              name=name,
              port=port,
              url="http://localhost",
              node_side_type=node_side_type,
          )
      return None
  
imports: from __future__ import annotations
  from enum import Enum
  import getpass
  import inspect
  import os
  import subprocess
  from threading import Thread
  from typing import Any
  from typing import Callable
  from typing import Optional
  from typing import Union
  from .cli import str_to_bool
  from .grammar import find_available_port
  from .names import random_name
  from .util import shell
label_desc: Use image node_id 12 for calling a global function with example usage: deploy_to_container(node_type_enum, deployment_type_enum, node_side_type, reset, cmd, tail, verbose, tag, render, dev_mode, port, name, enable_warnings, in_memory_workers) and returns: None, NodeHandle, NodeHandle