7

Assuming that I have a MongoDb or Sql Server container with a lotta data, and all of a sudden (which is very probable) I need to change the port! Maybe due to a sudden security issue! And I need to stop the container and start it up again running on a different port. Why doesn't docker allow me to do that, if I run the image again a new container will be created with no data inside and that causes a lot of mess.

Is there a proper built-in solution? By proper I mean a solution that does not require me to back up databases, move them to out the container volume and restore them again. Something logical such as a command that can allow me to change the forwarded port, for example -p 1433:1234 to 27017:1234.

Arnold Zahrneinder
  • 3,368
  • 4
  • 28
  • 54

3 Answers3

4

BLUF: Start your MongoDB container with a volume mapped in to keep the data persistant using this format: docker run --name some-mongo -v /my/own/datadir:/data/db -d mongo

While I agree, it would be great if Docker had the ability to switch port numbers in a running container. As others said, each container is a process, and I do not know a way of changing a port on a running process.

You do not need to import your data if you have set up your volumes properly. I do this all the time for MySQL databases. The MyQSL image is just the database engine separate from the database if you map in your volumes correctly. That's how Docker is designed.

In looking at the section "Where to store data", it gives an example of mounting a volume to a folder on the host to keep your data. This should allow you to start a new container using the same data without having to re-import. But I'm not as familiar with MongoDB which is a NoSQL.

https://hub.docker.com/_/mongo/#!

You may need backup your database using this dump command:

docker exec some-mongo sh -c 'exec mongodump -d <database_name> --archive' > /some/path/on/your/host/all-collections.archive

Start a new container with the volume mapped and restore the data.

docker run --name some-mongo -v /my/own/datadir:/data/db -v /some/path/on/your/host/all-collections.archive:/data/db/collections.archive -d mongo

You'll need to restore that backup.

docker exec some-mongo sh -c 'exec mongorestore --db <database_name> --archive=/data/db/collections.archive

From that point on you should be able to simply stop and start a new container with the volumes mapped in. Your data should remain persistent. You should not need to dump and restore any more (well, obviously for normal backup purposes).

J Roysdon
  • 174
  • 1
  • 4
2

Container is the instantiation of a image.

The port number is the instantiation state of a container, so it can only be changed while creating a container.

sarath kumar
  • 304
  • 2
  • 14
  • 6
    That means Docker belongs in the dumpster :) – Arnold Zahrneinder Jun 05 '18 at 10:58
  • 1
    actually here the port number involves in creating the network flow between the host machine network and the docker network. so this cannot be changed dynamically. – sarath kumar Jun 05 '18 at 11:01
  • 2
    So as I said, it is unfit for production environment. Because in a production environment, a port particularly may need to be changed at runtime. – Arnold Zahrneinder Jun 05 '18 at 11:03
  • in that case you can make use of the --net-alias and --net options to find your service. – sarath kumar Jun 05 '18 at 11:13
  • 1
    "Running" containers are processes, that's why it is difficult to change their configuration. You can't configure a process, you kill it and start a new one with the correct parameters. Containers should be considered ephemeral. – tgogos Jun 05 '18 at 11:13
  • Well, the thing is that, right now, I need to close port 1433 and drop all requests for that port. And for 5 hours I wanna serve my DB over port 1438 and then wanna switch back. Do I have to create a new container?? and restore all data???? – Arnold Zahrneinder Jun 05 '18 at 11:15
  • @tgogos: A process can be bind to a configuration. and about killing and starting, ok fine, how can you start it with a new port? (start not run) – Arnold Zahrneinder Jun 05 '18 at 11:17
  • have you created the volumes to save the data of you DB ? Actually the volume is the storage area where these kind of data are saved. so start of new container will make use of this volume space to retrieve the data. – sarath kumar Jun 05 '18 at 11:19
  • @sarathkumar: Yes but the volume and the data inside of belong to a particular container. When you create a new one and run it, then what happens? – Arnold Zahrneinder Jun 05 '18 at 11:21
  • @Arrrr volumes are not container specific. The purpose of the volume is to store this kind of multiple container data without data loss. – sarath kumar Jun 05 '18 at 11:22
  • @sarathkumar: but a new `Mongo Db` image!!! would it have any data inside or should you restore all the data for that new container running on that different port? – Arnold Zahrneinder Jun 05 '18 at 11:24
  • even if you remove the container the volume lives. use the following command. **docker volume ls** – sarath kumar Jun 05 '18 at 11:27
  • @sarathkumar: The problem is that, you have to attach/restore all databases/documents manually!! That is messy and a lot of work. – Arnold Zahrneinder Jun 05 '18 at 11:28
  • volume is completely out of the container and you can frame the container run command with -v option with full volume path – sarath kumar Jun 05 '18 at 11:31
  • @sarathkumar: That does not actually solve any problem. Copying and pasting data from volume to another does not do anything in this case. You still have to go inside and handle things manually. That is the problem. – Arnold Zahrneinder Jun 05 '18 at 11:33
  • 1
    Kindly refer to the docker volume documentation for details https://docs.docker.com/storage/volumes/ – sarath kumar Jun 05 '18 at 11:45
0

You can change the port mapping by directly editing the hostconfig.json file at /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

You can determine the [hash_of_the_container] via the docker inspect command and the value of the "Id" field is the hash.

1) stop the container 
2) change the file
3) restart your docker engine (to flush/clear config caches)
4) start the container

Reference: How do I assign a port mapping to an existing Docker container?

fly2matrix
  • 1,743
  • 9
  • 11
  • I clearly mentioned 'Something such as a command', I'm not interested in editing files. I wanna know if that framework has such functionality or not. If it does not have that, then it will be something which lacks a lot of consideration and that means it will not be proper for commercial environment. – Arnold Zahrneinder Jun 05 '18 at 10:51
  • 1
    Sorry I missed that part, however It would be simple one because there is no direct mean to do port change in the running containers. Any specific reason why you don't want to modify in this way... is your container's in cluster.............I must say your container should store data into volumes so that creating a new container will never loose any of the existing data. Think of this as opportunity to redesign it. – fly2matrix Jun 05 '18 at 11:00
  • A new container and particularly a database one will be fresh with not data, so you have to restore a lot of things. In a commercial environment with many force-major tasks, we need developer-friendly procedures, not hacks, workaround, and silly procedures. – Arnold Zahrneinder Jun 05 '18 at 11:02
  • I think you are looking for a solution to seed your database on new environments : Can you try https://ardoq.com/delightful-database-seeding-with-docker/ to adopt for a particular mechanism ? – fly2matrix Jun 05 '18 at 11:05
  • 1
    No, actually at the first glance, docker seems nice and may make you think about fully switching from ESXi to a lightweight virtualized container-based environment that docker offers. But after I look deep inside of it, it turned out to be a toy with insufficient design consideration. I just wanted to prove to my colleagues that it indeed is a silly toy :) – Arnold Zahrneinder Jun 05 '18 at 11:09
  • 1
    Best of Luck... I'll keep an eye on the solution if available..... I can not think of other than port fowarding as a temp solution, and for that you have to execute certain set of commands... – fly2matrix Jun 05 '18 at 11:24