Skip to content

Separated networks - #3

Open
casse-boubou wants to merge 47 commits into
tjhorner:mainfrom
casse-boubou:main
Open

Separated networks#3
casse-boubou wants to merge 47 commits into
tjhorner:mainfrom
casse-boubou:main

Conversation

@casse-boubou

@casse-boubou casse-boubou commented Apr 25, 2025

Copy link
Copy Markdown

Thank you for your work.
I think this addition could be very useful, please take a look.

Description:

  • Add the possibility to create multiple and separate networks with the ENV variable "CUSTOMS_NETWORKS".
  • Add the possibility to connect a container to one or more network with LABEL "network.to.connect"

Context:

Hi,
I've only had my very first NAS server for two weeks, and 25.04 is my first version.
So I'm not familiar with the capabilities you had with version 24.04, but having encountered issues connecting SWAG and some common services, I found your Custom_App after reading your discussion.
First of all, a GREAT GREAT THANK YOU! Using the container name as an identifier rather than its IP address is a basic principle for me, and I don't understand why it's missing from TrueNas. So thank you for your excellent work!!!

However, more than a network to bring them all (....and in the darkness bind them in), it's important for me to differentiate networks. Not all applications need to be networked, and not all need to be on the same network.
With this update, it's now possible to separate networks, and even better, a LABEL is enough to add an APP container to a network.
This also works with official or community apps.

HOW TO:

Networking

Networks are created by adding the CUSTOMS_NETWORKS ENV variable, separated by a comma.
This variable is not required, and if it is not set, the default value "apps-internal" will be used.

services:
  dragonify:
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 1024M
    environment:
      - LOG_LEVEL=info
      - CUSTOMS_NETWORKS=apps-internal-custom,app-external
    image: ghcr.io/tjhorner/dragonify:main
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Connecting containers

To connect a container to a network, assign it the LABEL network.to.connect.
Multiple networks can be configured, separated by a comma.

Config by YAML

services:
  swag:
    image: lscr.io/linuxserver/swag:latest
    container_name: swag
    environment:
      - PUID=568
      - PGID=568
      - TZ=TZ=Europe/Paris
      -  ............
    labels:
      - network.to.connect=apps-internal-custom,app-external
    volumes:
      - /mnt/imladris/elrond/swag/config:/config
     ...........

Setting up an APP Community

Elia 2025-04-26 à 00 02 39

Set the CUSTOMS_NETWORKS environment variable to add multiple networks

ex: CUSTOMS_NETWORKS=apps-internal-custom,app-external
Set the network.to.connect container LABEL for define the networks to connect the container

ex:
services:
  swag:
    container_name: swag
    .......
    labels:
      - network.to.connect=apps-internal-custom,app-external
Some update in logs lines
@casse-boubou

Copy link
Copy Markdown
Author

Another benefit, I just noticed that it's also possible to use directly the container name instead of {service}.ix-{app-name}.svc.cluster.local to have SWAG detect the container.
Elia 2025-04-26 à 00 19 29

@tjhorner

tjhorner commented Apr 26, 2025

Copy link
Copy Markdown
Owner

This is a great idea! Keeping apps only on their relevant networks can improve security posture. I have a few minor suggestions:

  • Following Docker's recommendations, the container label should be something like tj.horner.dragonify.networks
  • To maintain backward compatibility, disabling the auto-connection of all containers to the default apps-internal network should only happen if the CUSTOM_NETWORKS environment variable is unset

I can go ahead and make these changes, or you could make them yourself if you prefer. Let me know what you think!

@tjhorner

tjhorner commented Apr 26, 2025

Copy link
Copy Markdown
Owner

Also, what do you think about creating networks on-the-fly rather than explicitly defining them in the environment variable beforehand? So all you would need to do is set the label tj.horner.dragonify.networks on the relevant apps and Dragonify could automatically create the relevant networks if they don't exist.

I also think we should probably add labels to networks created by Dragonify so it can manage their lifecycle (e.g., deleting them when no longer in use).

Change LABEL for Following Docker's recommendations
@casse-boubou

Copy link
Copy Markdown
Author

Hi
First of all, this is the first time that I have been using typescript and am not very experienced. But I would like to try the change you offer. I find these very relevant !

set the label tj.horner.dragonify.networks on the relevant apps and Dragonify could automatically create the relevant networks
This is a great idea, it would no longer have to use the ENV variable.

add labels to networks created by Dragonify
This is great! I didn't know it was possible to add a label to a network, but I was wondering about network management.
I had thought about the idea of ​​deleting a created network when all the containers are disconnected, but I was thinking that I would have to create a list of the created networks to memorize it and store this list somewhere. This required adding a volume of relevant data and making everything more complex.
But with a label on a network, this would be exactly what I needed!

disabling the auto-connection of all containers to the default apps-internal network should only happen if the CUSTOM_NETWORKS environment variable is unset
And what do you think about adding an ENV variable to define this. Something like "CONNECT_ALL" for example?

Add CONNECT_ALL ENV variable to maintain backward compatibility.
Set it to "false" or "False" for disabling the auto-connection of all containers to the default apps-internal network
Adds a check for existing networks when connecting to networks in order to create one if necessary
Add a function to delete networks that are no longer in use
Remove the default network if the CONNECT_ALL ENV is set to "false" or "False"
@casse-boubou

Copy link
Copy Markdown
Author

Hum,
I think I'm done with all these options. And it's not so bad.
Of course, I'm waiting for your feedback. But here's what works well.

  • A label is defined on the created networks
  • Automatic networks creation if they are specified in the container label
  • The ability to enable or disable the default "apps-internal" network (enabled by default)
  • Automatic disconnection of all containers from "apps-internal" if it is disabled
  • The default "apps-internal" network and custom networks work together (not just one OR the other)

Personally I use it like this and it works very well:

Dragonify

services:
  dragonify:
    environment:
      - LOG_LEVEL=info
      - CONNECT_ALL=False
    image: ghcr.io/tjhorner/dragonify:main
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

SWAG

services:
  swag:
    container_name: swag
    image: lscr.io/linuxserver/swag:latest
    ..........
    labels:
      - tj.horner.dragonify.networks=ix-homepage_default,ix-jellyfin_default

@leuchtrakete666

Copy link
Copy Markdown

this container and especially this pull request is a lifesaver! congrats to you @tjhorner and @casse-boubou.

i just changed the dns name to {service}.truenas. is more convenient.

my use case is a swarm over all my docker hosts and have a proxy overlay network for the reverse proxy. i use the swarm with standalone containers, no high availability. only truenas was a bit of a headache with networks.

i am really happy i found this project.

i testet the pull request intensely and it works like a charm. please @tjhorner commit it.

@Sophist-UK

Sophist-UK commented Dec 17, 2025

Copy link
Copy Markdown

Since this PR is not merged I cannot see how to run this version as described using image: ghcr.io/tjhorner/dragonify:main

I think I can probably make it work short-term using image: ghcr.io/casse-boubou/dragonify:main but this is not a good long-term solution.

@tjhorner Can we get this merged?

@Sophist-UK

Copy link
Copy Markdown

P.S. This PR needs to update the documentation to show two ways of running the service.

And IMO this is so useful that it should be contributed to the Truenas App directory.

@Sophist-UK

Sophist-UK commented Dec 22, 2025

Copy link
Copy Markdown

@tjhorner / @casse-boubou

I have a refactored version of Dragonify coded, and it is compiling cleanly but not yet tested - but I have gone back a few steps:

  1. I felt I needed to understand exactly what is happening when Dragonify connects and disconnects containers from networks e.g.
  2. Exactly how network names need to be handled in different circumstances , and
  3. How containers handle (or don't handle) the network reconfiguration e.g. of container internal IPTABLES when a network is attached or detached
  4. And that prompted me to go back to basics and think about exactly what Docker Network architectures should be handled (perhaps not just multiple shared equivalents to apps-internal), but perhaps also ...
  5. Docker network models with isolated "none" networks. (I have limited it to that as yet - and not started to consider other Docker Networks such as "overlay", "ipvlan", "macvlan" or "container:".)

I am part way through documenting my (as yet incomplete) vision, and would welcome your input.

Please see the work-in-progress README.md at https://github.com/Sophist-UK/dragonify/blob/main/README.md

I would welcome any comments on my ideas - and please don't hold back.

Fix network existence check and race condition handling
Almost completely rewrites the code to add a concept of tuple variables in order to manage the connection/reconnection of an existing container to a new network.
Handle Docker shutdown to obtain an exit code: 0
- reduces the number of calls to the Docker API in the event of a container stop. Thus accelerating the execution speed
- changes the way networks are prunned in order to avoid performing a prune of all networks at each container stop
Apply a timer to prune network to prevent it from triggering at each container stop.
Truenas already executes this function when restarting an app and this caused a conflict if Drogonify deleted the network before Truenas could reuse it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants