The standard approach is to build a new image, stop the existing server container, and then start a new container based on a new image. If you're using Docker Compose, this can be as little as
docker-compose build
docker-compose up -d
Compare this to running a server in a compiled language like Java or Go. Here you have the exact same workflow: compile your updated sources into a new jar file or binary, stop the existing server, and start a new one. There's not usually a reason to try to preserve the existing process and update it with new code.
In the same way, a container is a (temporary) wrapper around a single (temporary) process. There's no particular reason that you need the same container; in normal operation you should be able to delete and recreate a container without losing anything. In Docker you need to recreate a container fairly routinely to change various startup-time-only options, and also to update the underlying image. If you move on to clustered environments like Kubernetes this becomes even more important: you'll have multiple replicas of a container so they can't have persistent state, and it's possible for a container to be deleted and recreated outside of your immediate control.