in samcli/local/docker/container.py [0:0]
def create(self, context):
"""
Calls Docker API to creates the Docker container instance. Creating the container does *not* run the container.
Use ``start`` method to run the container
context: samcli.local.docker.container.ContainerContext
Context for the container management to run (build, invoke)
:return string: ID of the created container
:raise RuntimeError: If this method is called after a container already has been created
"""
if self.is_created():
raise RuntimeError("This container already exists. Cannot create again.")
_volumes = {}
if self._host_dir:
mount_mode = "rw,delegated" if self._mount_with_write else "ro,delegated"
LOG.info("Mounting %s as %s:%s, inside runtime container", self._host_dir, self._working_dir, mount_mode)
if self._resolve_symlinks_in_context(context) or self._mount_symlinks:
mapped_symlinks = self._create_mapped_symlink_files()
else:
mapped_symlinks = {}
_volumes = {
self._host_dir: {
# Mount the host directory inside container at working_dir
# https://docs.docker.com/storage/bind-mounts
"bind": self._working_dir,
"mode": mount_mode,
},
**mapped_symlinks,
}
kwargs = {
"command": self._cmd,
"working_dir": self._working_dir,
"volumes": _volumes,
# We are not running an interactive shell here.
"tty": False,
# Set proxy configuration from global Docker config file
"use_config_proxy": True,
}
# Get effective user when building lambda and mounting with write permissions
# Pass effective user to docker run CLI as "--user" option in the format of uid[:gid]
# to run docker as current user instead of root
# Skip if current user is root on posix systems or non-posix systems
effective_user = EffectiveUser.get_current_effective_user().to_effective_user_str()
if self._mount_with_write and effective_user and effective_user != ROOT_USER_ID:
LOG.debug("Detect non-root user, will pass argument '--user %s' to container", effective_user)
kwargs["user"] = effective_user
if self._container_opts:
kwargs.update(self._container_opts)
if self._additional_volumes:
kwargs["volumes"].update(self._additional_volumes)
# Make sure all mounts are of posix path style.
kwargs["volumes"] = {to_posix_path(host_dir): mount for host_dir, mount in kwargs["volumes"].items()}
if self._env_vars:
kwargs["environment"] = self._env_vars
kwargs["ports"] = {self.RAPID_PORT_CONTAINER: (self._container_host_interface, self.rapid_port_host)}
if self._exposed_ports:
kwargs["ports"].update(
{
container_port: (self._container_host_interface, host_port)
for container_port, host_port in self._exposed_ports.items()
}
)
if self._entrypoint:
kwargs["entrypoint"] = self._entrypoint
if self._memory_limit_mb:
# Ex: 128m => 128MB
kwargs["mem_limit"] = "{}m".format(self._memory_limit_mb)
if self._extra_hosts:
kwargs["extra_hosts"] = self._extra_hosts
try:
real_container = self.docker_client.containers.create(self._image, **kwargs)
except DockerAPIError as ex:
raise DockerContainerCreationFailedException(
f"Container creation failed: {ex.explanation}, check template for potential issue"
)
self.id = real_container.id
self._logs_thread = None
self._logs_thread_event = None
if self.network_id and self.network_id != "host":
try:
network = self.docker_client.networks.get(self.network_id)
network.connect(self.id)
except DockerNetworkNotFound:
# stop and delete the created container before raising the exception
real_container.remove(force=True)
raise
return self.id