[solved]Templates when using Traefik

Hi everyone.

I have a Docker Sarm (3 nodes, 2 Workers & 1 Manager). With portainer.

Everything is working fine but I’m trying to add some templates now.
As far as I was able to test, it is crucial that the name of the service is only allowed to exist once to not collide with another. So I tried having a variable that you have to put in when using templates. Here one line as example:
traefik.http.routers.${NAMEOFSERVICE}.rule=Host(`${HOSTNAME}`)

When using the template I have the field for the hostname. But not for the service name. How do I do that?

Templates.json:

    "type": 2,
    "title": "Hello World test",
    "description": "Kleiner Service/Stack zum Testen der Konfiguration",
    "note": "Mit aktiviertem TLS",
    "categories": ["Tools"],
    "platform": "linux",
    "logo": "http://www.digitalconnectmag.com/wp-content/uploads/2016/01/tutum.png",
    "repository": {
      "url": "https://LOCALGITREPO/portainer-templates",
      "stackfile": "helloworld.yml"
    },
    "env": [
      {
        "name": "HOSTNAME",
        "label": "Domain/Hostname",
        "description": "Der Dateipfad für die Traefik-Config (dort muss die certificates.toml-Datei liegen). Beispiel: /traefik/configuration/ "
      },
	  {
        "name": "NAMEOFSERVICE",
        "label": "Name des Services (Muss eindeutig sein!)",
        "description": "Darf es nicht zwei mal geben, da sonst das Routing für beide nicht mehr funktioniert!"
      }
    ]
  }

I do not see what I’ve might done wrong.
Thank you in advance for any help…

I also posted on GitHub --> Click

Same behavior for me. Probably a bug.

Do you know a workaround? I need to finish this project this week…

Don’t use the templates feature. When you launch any stack in a swarm you can specify any environment variables you want.

You can launch 1 docker-compose stack with a unique service for each set of environment variables. (https://docs.docker.com/compose/compose-file/#extension-fields)

You can launch as many copies of the same docker-compose file with changes to the env variables.

Paste then into the docker-compose editor in portainer under Stacks > + Add stack. This is the equivalent of docker stack deploy -f docker-compose.yml

Name your stacks:

  • service-stage
  • service-prod
  • service-testing

For the first solution, 1 compose file, 1 “stack”, many services:

version: '3.4'
x-svc-fragment:
  &svc-default-networks
  options: 'abc'
  &svc-default-something
  yaml-node: 'def'

service:
  db-test:
    image: mysql/something
    env:
        my-custom-env: value
    network: *svc-default-network
    something: *svc-default-something

  db-stage:
    image: mysql/something
    env:
        my-custom-env: stage-value
    network: *svc-default-network
    something: *svc-default-something

YAML anchors can remove duplication a little. You could also use bash or other yaml tools to create a final docker-compose file by merging .env files or whatever. A custom technique to manage your docker-compose, or just write it and manage it by hand.

1 Like

You can launch as many copies of the same docker-compose file with changes to the env variables.

I did not explain this enough.

You have 1 docker-compose.yml file. The env variables are defined, but they are blank or default.

Then you paste into portainer with a cusotm name, like “service-testing”, launch it, then use portainer UI to change the env variables in the stack’s page.

The downside is that you have to manually use the UI everytime you launch the service (and maybe everytime you do a rolling update of the service too).

Because the template env vars feature is broken in portainer, it means you need to manage multiple docker-compose files yourself, or manage a set of tools to build 1 or more docker-compose.ymls.

If you want to allow your portainer users to create a service w/o having to manage docker-compose files, then you must create usable defaults for the env variables and have the users change after launching the service :frowning:

1 Like

Oh no…

Well I can let the users handle compose-files. It’s just that they also wanted this template feature but ok…

Thank you for your help :slight_smile:

For those interested:

Solution:

Instead of (in helloworld.yml)
traefik.http.routers.${NAMEOFSERVICE}.rule=Host(`${HOSTNAME}`)
I had to add something like "helloworld-"bevore the variable.
traefik.http.routers.helloworld-${NAMEOFSERVICE}.rule=Host(`${HOSTNAME}`)

With this change the field NAMEOFSERVICE is being shown in the Templates-UI and the services/stacks run without any issues (so far).