kamal icon indicating copy to clipboard operation
kamal copied to clipboard

Request: Option to skip auto create kamal network

Open aarroisi opened this issue 1 year ago • 2 comments

I would like to request the ability to skip creating "kamal" network. In the docs, it is suggested that we pre-create the "kamal" network prior to deployment, but in my case it's not sufficient if you are trying to connect all the deployed apps to the same overlay, swarm network.

My use case is as follow:

  • I have Elixir apps deployed to multiple servers
  • These Elixir apps need to be connected to the same network to make them a single Erlang cluster
  • To make the above possible, these servers are connected to the same docker swarm with one of the nodes acts as the manager
  • It uses overlay network in swarm scope connecting all these servers
  • I don't mind naming it "kamal"

HOWEVER, overlay swarm network in Docker that spans multiple servers has a condition in which a host is not yet connected to the network unless it has a running container connected to the network.

So, currently, what happened in my setup is as follow:

  1. I have a new node that I want to add as a deployment target
  2. I have previously created the network in the manager node, named "kamal"; overlay driver + swarm scope
  3. In the docker-setup hook, I connect the new node to the swarm as worker. Note: the new node is not automatically connected to the network since there is no running container that connected to the network. It's a new server after all.
  4. In one of the deployment steps, Kamal tries to create "kamal" network in the worker node. It will successfully create the new local bridge network named "kamal" (because at this point before auto creation of the network, the new node is not yet connected to the previously created overlay network, so no conflicting network name)
  5. Now there are two networks named kamal; one is the "correct" overlay network and the other is the local bridge network in the new node

With that new behavior in Kamal 2 (always tries to create new "kamal" network), I have 2 somewhat hacky solutions:

  1. Make all nodes act as manager node in the swarm. No worker nodes. This way, all nodes can manage the swarm network.
  2. Create a "dummy" service that make all the servers have a running container, making the "kamal" overlay network immediately discoverable

My ideal solution would be an ability to skip auto creation of "kamal" network.

aarroisi avatar Oct 02 '24 15:10 aarroisi

@aarroisi do you use a particular workaround for the above for now?

dvic avatar Jun 22 '25 17:06 dvic

@aarroisi do you use a particular workaround for the above for now?

In docker-setup hook, I run this:

#!/usr/bin/env ruby

manager_node = ENV["MANAGER_NODE"]
manager = "root@#{manager_node}"
`mkdir -p /root/.ssh`
`ssh-keyscan #{manager_node} >> /root/.ssh/known_hosts`
`ssh #{manager} docker network create --scope=swarm --attachable -d overlay kamal`

hosts = ENV["WORKER_HOSTS"].split(",")
hosts.each do |ip|
  destination = "root@#{ip}"
  join_token = ENV["JOIN_TOKEN"]
  puts "#{destination} is joining the swarm to the manager on #{manager_node}"
  `ssh-keyscan #{ip} >> /root/.ssh/known_hosts`
  `ssh #{destination} docker swarm join --token #{join_token} #{manager_node}:2377`
end

puts "Creating a service on the manager node"
`ssh #{manager} docker service create --name alpine --network kamal --mode global alpine sleep infinity`

What it's doing:

  1. Creates swarm network in manager node with name "kamal"
  2. Join all the worker hosts to the swarm.
  3. Make lightweight docker service that will be run in all nodes, making the overlay swam network discoverable in all nodes.

When the kamal deploy runs and tries to create "kamal" network, it will fail (since the network named kamal already exists) and skip the creation and proceeds to the next step.

aarroisi avatar Aug 17 '25 13:08 aarroisi