Docker containers are usually treated as immutable once they’ve started running. You can update some configuration parameters dynamically though, such as the container’s name and its hardware resource limits.

In this guide, we’ll show you how to use built-in Docker commands to modify selected parameters of running containers. We’ll also look at what you shouldn’t change and a workaround you can use if you believe you must.

Renaming a Container

The simplest modification is renaming a created container. Names are assigned via the --name flag for docker run. When no name is supplied, the Docker daemon assigns a random one. You can use names to reference containers in Docker CLI commands; choosing an appropriate memorable one avoids running docker ps to find a container’s auto-assigned name or ID.

The docker rename command is used to change container names after creation. It takes two arguments, the target container’s ID or current name, and the new name to assign:

# docker rename <target ID or name> <new name>
docker rename old_name new_name

Changing the Restart Policy

Restart policies determine whether containers should start automatically after your host reboots or the Docker daemon launches. The four available policies let you force the container to start, make it stay stopped, or conditionally start based on the container’s previous exit code or running state.

Docker supports changing restart policies on-the-fly. This is useful if you’re planning to reboot your host or the Docker daemon and want a certain container to stay stopped – or automatically start – after the specific event.

docker update --restart unless-stopped demo_container

The above example changes the restart policy of demo_container to unless-stopped. This policy makes the container start with the daemon unless it was stopped manually before the daemon last exited.

Changing Hardware Resource Limits

The docker update command can also be used to alter the resource limits applied to containers. You must pass one or more container IDs or names, along with a list of flags defining the limits to set on those containers.

Flags are available for all the resource limits supported by docker run. Here’s a condensed list of the options you can use:

  • --blkio-weight – Change the container’s Block IO relative weight.
  • --cpus – Set the number of CPUs available to the container.
  • --cpu-shares – Set the CPU share relative weight.
  • --memory – Change the container’s memory limit (e.g. 1024M).
  • --memory-swap – Configure the amount of memory the container can swap to disk; use a size such as 1024M to set a specific limit, or -1 for unlimited swap.
  • --kernel-memory – Change the container’s kernel memory limit. Containers starved of kernel memory can negatively impact other workloads on the host machine.
  • --pids-limit – Configure the maximum number of process IDs allowed inside the container, restricting the number of processes that can be started.

Here’s an example of using docker update to change the memory limit and CPU count for two of your containers:

docker update --cpus 4 --memory 1024M first_container second_container

All of the available flags except --kernel-memory can be used with running Linux containers. To change the kernel memory limit, you must stop the container with docker stop first.

Beware that none of these flags are currently supported for Windows-based containers. They will work with Linux containers running on a Windows host machine though.

When Not To Use These Commands?

The docker update and docker rename commands should be used with containers you’ve manually created via docker run. Be wary of using them with containers that originate from other tools such as docker-compose.

Changing a container’s name could leave it undetectable by the source tool, potentially breaking other components of your stack. In addition, if you’re declaratively defining resource limits in a docker-compose.yml file, running the docker-compose up command again will re-apply those original limits to your container.

Therefore you should stick to your existing container management solution if you’re using one. For Compose, that means changing container names and resource limits in your docker-compose.yml file, then running docker-compose up -d to automatically apply the change. This ensures you won’t unintentionally orphan containers or cause unintended side effects.

What About Other Properties (Image/Ports/Volumes)?

Hardware limits, resource policies, and container names are the only config parameters the Docker CLI lets you change. You can’t modify the image of a running container; neither can you easily alter other options such as port bindings and volumes.

You should create another container if these values become outdated. Destroy your current instance and use docker run to start a replacement with your new image and corrected settings.

As containers are meant to be stateless and ephemeral, you should be able to replace them at any time. Use volumes to store persistent container data; this mechanism lets you reattach stateful files to the new container by repeating the -v flags passed to the original docker run command:

docker run -v config-volume:/usr/lib/config --name demo example-image:v1

docker rm demo

# Existing data in /usr/lib/config retained
docker run -v config-volume:/usr/lib/config --name demo2 example-image:v2

Danger Zone: Changing Other Container Properties

Although you should aim to replace containers wherever possible, it is possible to modify the properties of existing ones by directly editing Docker’s config files. Take care when using this method: it’s entirely unsupported and a misplaced change could break your container.

While this option provides a way to arbitarily edit existing containers, it won’t work while they’re running. Use the docker stop my-container command to stop the container you want to edit, then continue to make your changes.

Container config files have the following path on your host:

/var/lib/docker/containers/<container id>/config.v2.json

You need to know the container’s full ID, not the truncated version shown by docker ps. You can use the docker inspect command to get this:

docker inspect <short id or name> | jq | grep Id

image of getting a Docker container's full ID with "docker inspect"

Once you’ve got to a container’s config.v2.json, you can open it in a text editor to make any necessary changes. The JSON stores the container configuration created when you ran docker run. You can modify the contents to alter properties such as port bindings, environment variables, volumes, and the container entrypoint and command.

To add a port binding, find the PortBindings key in the file, then insert a new item into the object:

{
    "PortBindings": {
        "80/tcp": {
            "HostIp": "",
            "HostPort": "8080"
        }
    }
}

Here port 80 in the container is bound to port 8080 on the host. It’s similarly straightforward to add environment variables – find the Env key, then insert new items into the array:

{
    "Env": [
        "FOO=bar",
        "CUSTOM_VARIABLE=example"
    ]
}

Once you’re done editing, restart the Docker service and your container:

sudo service docker restart

docker start my-container

The container will now run with its updated configuration.

Conclusion

Docker containers are meant to be ephemeral units which you replace when their configuration becomes outdated. Despite this intention, there are scenarios where it’s necessary to modify an existing container. Docker handles the most common use cases – name changes and real-time resource limit adjustments – via built-in CLI commands such as docker update.

When you want to change another property, always try to replace the container as your first course of action. This minimizes the risk of breaking things and is in keeping with Docker’s model of immutability. If you do end up in a situation where an existing container needs to be edited, you can manually alter Docker’s internal config files as outlined above.

Finally, remember that containers managed by other ecosystem tools like Docker Compose should be modified using those mechanisms. Otherwise you might find containers are unexpectedly orphaned or overwritten if the tool’s unaware of the changes you’ve made.

Profile Photo for James Walker James Walker
James Walker is a contributor to How-To Geek DevOps. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows, using technologies including Linux, GitLab, Docker, and Kubernetes.
Read Full Bio »