You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible循环中配置带变量的字典实现多用户Docker容器及Traefik路由

解决Ansible循环部署带动态Traefik标签Docker容器的方案

问题核心原因

你当前的配置无法运行的核心原因是:Ansible不支持直接在YAML字典的键位置内联Jinja2模板变量,你写在labels下的动态键名不符合Ansible的语法规范。

最优实现方案

不需要用到嵌套循环或复杂的set_fact预定义逻辑,直接在docker_container任务中通过Jinja2模板动态构造完整的labels字典即可,修正后的完整任务代码如下:

- name: Run syncthing
  docker_container:
    name: "{{ item.name }}-syncthing"
    image: "lscr.io/linuxserver/syncthing"
    state: started
    restart_policy: "always"
    env:
      PUID: "1000"
      PGID: "1000"
    volumes:
      - "{{ item.data_dir }}:/data"
      # 其他你需要挂载的卷继续加在这里
    labels: "{{
      {
        'traefik.enable': 'true',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.entrypoints': 'websecure',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.rule': 'Host(`' ~ item.name ~ '.' ~ fqdn_real ~ '`)',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.tls': 'true',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.tls.certresolver': 'le',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.service': item.name ~ '-syncthing',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.middlewares': item.name ~ '-syncthing-basicauth',
        'traefik.http.services.' ~ item.name ~ '-syncthing.loadbalancer.server.port': '8080',
        'traefik.http.middlewares.' ~ item.name ~ '-syncthing-basicauth.basicauth.users': item.auth
      }
    }}"
  loop: "{{ syncthing_containers_info }}"

注意事项

  • 上面的代码修正了你原有配置里的一个笔误:你之前路由引用的中间件名是{{ item.name }}-basicauth,但实际定义的中间件名是{{ item.name }}-syncthing-basicauth,两者不一致会导致Traefik报错,这里已经统一为后者,你可以根据实际需求调整。
  • 代码中使用~作为Jinja2的字符串拼接符,语法兼容性更好,所有变量都会被正确解析拼接成最终的标签键名。
  • 你原有定义的syncthing_containers_info变量不需要做任何修改,可以直接复用。

验证方法

如果你需要先确认生成的标签是否正确,可以在部署容器前新增一个debug任务打印配置:

- name: Debug generated labels
  debug:
    msg: "{{
      {
        'traefik.enable': 'true',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.entrypoints': 'websecure',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.rule': 'Host(`' ~ item.name ~ '.' ~ fqdn_real ~ '`)',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.tls': 'true',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.tls.certresolver': 'le',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.service': item.name ~ '-syncthing',
        'traefik.http.routers.' ~ item.name ~ '-syncthing.middlewares': item.name ~ '-syncthing-basicauth',
        'traefik.http.services.' ~ item.name ~ '-syncthing.loadbalancer.server.port': '8080',
        'traefik.http.middlewares.' ~ item.name ~ '-syncthing-basicauth.basicauth.users': item.auth
      }
    }}"
  loop: "{{ syncthing_containers_info }}"

内容的提问来源于stack exchange,提问作者xmd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:45:02