From a26efe12e5a4b2a55a02e1c34e34bd46bcf0e5cf Mon Sep 17 00:00:00 2001 From: staffadmin Date: Sat, 13 Jul 2024 19:15:56 +0200 Subject: [PATCH] push --- .../config/traefik-dynamic-configuration.yml | 4 + files/swarm/stack.yml | 156 ++++++++++ files/swarm/tls/jingoh.private.crt | 22 ++ files/swarm/tls/jingoh.private.key | 27 ++ host_vars/{v1.yml => manager.yml} | 3 +- host_vars/ovh01.yml | 3 +- host_vars/{v2.yml => worker.yml} | 0 hosts | 14 +- portainer-traefik-agent.yml | 39 ++- swarm.yml | 266 +++++++++++++++++- 10 files changed, 508 insertions(+), 26 deletions(-) create mode 100644 files/swarm/config/traefik-dynamic-configuration.yml create mode 100644 files/swarm/stack.yml create mode 100644 files/swarm/tls/jingoh.private.crt create mode 100644 files/swarm/tls/jingoh.private.key rename host_vars/{v1.yml => manager.yml} (79%) rename host_vars/{v2.yml => worker.yml} (100%) diff --git a/files/swarm/config/traefik-dynamic-configuration.yml b/files/swarm/config/traefik-dynamic-configuration.yml new file mode 100644 index 0000000..610cba6 --- /dev/null +++ b/files/swarm/config/traefik-dynamic-configuration.yml @@ -0,0 +1,4 @@ +tls: + certificates: + - certFile: /run/secrets/wildcard-jingoh-private.crt + keyFile: /run/secrets/wildcard-jingoh-private.key \ No newline at end of file diff --git a/files/swarm/stack.yml b/files/swarm/stack.yml new file mode 100644 index 0000000..61d6a50 --- /dev/null +++ b/files/swarm/stack.yml @@ -0,0 +1,156 @@ +version: '3.13' +# https://github.com/akhil/traefik-docker-swarm-example/blob/master/traefik.yml +# services: +# traefik: +# # Image tag (replace with yours) +# image: traefik:latest +# command: +# - "--log.level=DEBUG" +# - "--accesslog=true" +# - "--api.dashboard=true" +# - "--api.insecure=true" +# - "--entryPoints.web.address=:80" +# - "--entryPoints.websecure.address=:443" +# - "--providers.docker=true" +# - "--providers.docker.watch=true" +# - "--providers.swarm=true" +# - "--providers.docker.network=public" +# - "--providers.docker.endpoint=unix:///var/run/docker.sock" +# - "--providers.docker.exposedByDefault=false" +# - "--providers.file.filename=/etc/traefik/configs/traefik-dynamic-configuration.yml" +# # - "--metrics.prometheus=true" +# # - "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0" +# - "--global.checkNewVersion=true" +# - "--global.sendAnonymousUsage=false" +# volumes: +# - /var/run/docker.sock:/var/run/docker.sock +# networks: +# - public +# ports: +# - "80:80" +# - "443:443" +# # For Mattermost +# # - "8443:8443" +# configs: +# - source: traefik-dynamic-configuration +# target: /etc/traefik/configs/traefik-dynamic-configuration.yml +# secrets: +# - wildcard-jingoh-private.crt +# - wildcard-jingoh-private.key +# deploy: +# mode: replicated +# replicas: 1 +# placement: +# constraints: +# - node.role == manager +# update_config: +# delay: 15s +# parallelism: 1 +# monitor: 10s +# failure_action: rollback +# max_failure_ratio: 0.55 +# # Container resources (replace with yours) +# resources: +# limits: +# cpus: '1.55' +# memory: 2G +# reservations: +# cpus: '0.55' +# memory: 1G +# labels: +# - "traefik.enable=true" +# # Traefik URL (replace with yours) +# - "traefik.http.routers.dashboard.rule=Host(`traefikswarm.jingoh.private`)" +# - "traefik.http.routers.dashboard.service=api@internal" +# - "traefik.http.routers.dashboard.entrypoints=websecure" +# - "traefik.http.services.dashboard.loadbalancer.server.port=8080" +# - "traefik.http.routers.dashboard.tls=true" +# - "traefik.http.services.dashboard.loadbalancer.passhostheader=true" +# - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)" +# - "traefik.http.routers.http-catchall.entrypoints=web" +# - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" +# - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" + +# agent: +# image: portainer/agent:latest +# environment: +# # REQUIRED: Should be equal to the service name prefixed by "tasks." when +# # deployed inside an overlay network +# AGENT_CLUSTER_ADDR: tasks.agent +# # AGENT_PORT: 9001 +# # LOG_LEVEL: debug +# volumes: +# - /var/run/docker.sock:/var/run/docker.sock +# - /var/lib/docker/volumes:/var/lib/docker/volumes +# networks: +# - agent_network +# deploy: +# mode: global +# placement: +# constraints: [node.platform.os == linux] + +# portainer: +# image: portainer/portainer-ce:latest +# command: -H tcp://tasks.agent:9001 --tlsskipverify --http-enabled +# volumes: +# - /var/run/docker.sock:/var/run/docker.sock +# - portainer_data:/data +# - /etc/localtime:/etc/localtime +# networks: +# - public +# - agent_network +# deploy: +# mode: replicated +# replicas: 1 +# placement: +# constraints: [node.role == manager] +# labels: +# - "traefik.enable=true" +# - "traefik.http.routers.portainer.rule=Host(`portainer.jingoh.private`)" +# - "traefik.http.routers.portainer.entrypoints=websecure" +# - "traefik.http.routers.portainer.service=portainer" +# - "traefik.http.services.portainer.loadbalancer.server.port=9443" +# - "traefik.http.routers.portainer.tls=true" +# - "traefik.http.services.portainer.loadbalancer.passhostheader=true" +# # Edge +# - "traefik.http.routers.edge.rule=Host(`edge.jingoh.private`)" +# - "traefik.http.routers.edge.entrypoints=websecure" +# - "traefik.http.services.edge.loadbalancer.server.port=8000" +# - "traefik.http.routers.edge.service=edge" +# - "traefik.http.routers.edge.tls=true" +# - "traefik.http.services.edge.loadbalancer.passhostheader=true" + +# whoami: +# image: "traefik/whoami" +# deploy: +# labels: +# - "traefik.enable=true" +# - "traefik.http.routers.whoami.rule=Host(`whoamitest.jingoh.private`)" +# - "traefik.http.routers.whoami.entrypoints=websecure" +# - "traefik.http.services.whoami.loadbalancer.server.port=80" +# - "traefik.http.routers.whoami.tls=true" +# - "traefik.http.services.whoami.loadbalancer.passhostheader=true" +# networks: +# - public + +# networks: +# public: +# external: true +# agent_network: +# external: true +# attachable: true +# volumes: +# portainer_data: + + + +# configs: +# traefik-dynamic-configuration: +# external: true + +# secrets: +# wildcard-jingoh-private.crt: +# external: true + +# wildcard-jingoh-private.key: +# external: true diff --git a/files/swarm/tls/jingoh.private.crt b/files/swarm/tls/jingoh.private.crt new file mode 100644 index 0000000..a46aab1 --- /dev/null +++ b/files/swarm/tls/jingoh.private.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIUKJ9Qnulnmv91wS0XQXuFAAJTLOkwDQYJKoZIhvcNAQEL +BQAwcTELMAkGA1UEBhMCRlIxFzAVBgNVBAgMDklsZXMtZGUtZnJhbmNlMQ4wDAYD +VQQHDAVQYXJpczEPMA0GA1UECgwGamluZ29oMQ8wDQYDVQQLDAZqaW5nb2gxFzAV +BgNVBAMMDmppbmdvaC5wcml2YXRlMB4XDTI0MDQxNzE5MDIxMloXDTM0MDQxNTE5 +MDIxMlowcTELMAkGA1UEBhMCRlIxFzAVBgNVBAgMDklsZXMtZGUtZnJhbmNlMQ4w +DAYDVQQHDAVQYXJpczEPMA0GA1UECgwGamluZ29oMQ8wDQYDVQQLDAZqaW5nb2gx +FzAVBgNVBAMMDmppbmdvaC5wcml2YXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuvwbT5XwP4wOhPLubWk7KBdt1+taFV/YNIkx+Ky9Nb+eceJ8iYXm +Xy9bRK0WTdTiwOLC60h3WigsMMPc8sI1FiW3jfHMU8Z2GqJTHFM6CP1LcN+LpKZZ +f8pZu3ONMhTcaPGvGYH+GAdi8Qk7rRskirZlImsA6lGDoteKKF/Xc4Y6IoIxIZ7X +SK7klO/qN0ZPHWiu9QAtNBc4vVZEz83aXEbKH7eCOtSz07cOIT6yrvUF11225Y0e +nn+DOLEcBBwI5KLco0udERz/Epn90eUWgbibP4QIaVQJypFC17RU3fXkiqZjb0Qy +B2WEYi8awyB6KgZfu1PvzuvHYuKugBeYVwIDAQABoz8wPTAJBgNVHRMEAjAAMBsG +A1UdEQQUMBKCECouamluZ29oLnByaXZhdGUwEwYDVR0lBAwwCgYIKwYBBQUHAwEw +DQYJKoZIhvcNAQELBQADggEBAJ2hJ5SW9TD9yLecxG++x/jl32oxYJ/EyDPXZNHw +fAb+9YmniThDEJTJ2RJTOIhZz6uqdjfP+37sFDu17SMvxauG78RIYSaTGnIaoiXt +v5Uh4apUR1DOOPoZoUX82ZQJEJ5LenO+EFHevYbzgcDW61T/oByPwK8FOtLqQMHe +SC09WsGyLQ/hls+4EgxQFyl7UN5T9NK6xrQrHwNbV0IgHcnGcTSkzRj4mt1nzsdh +Enq/Ztz9iefxqDvHPFRRtcqDv+Ozh7zSuxVfP3tb7+5Ak7j/0Txi5NAbo+F3opAD +8eeY2dTgxc9sV1esvB305zgl4SUkfLD+BDjOjn/NvWFj2i0= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/files/swarm/tls/jingoh.private.key b/files/swarm/tls/jingoh.private.key new file mode 100644 index 0000000..bc9b8cd --- /dev/null +++ b/files/swarm/tls/jingoh.private.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuvwbT5XwP4wOhPLubWk7KBdt1+taFV/YNIkx+Ky9Nb+eceJ8 +iYXmXy9bRK0WTdTiwOLC60h3WigsMMPc8sI1FiW3jfHMU8Z2GqJTHFM6CP1LcN+L +pKZZf8pZu3ONMhTcaPGvGYH+GAdi8Qk7rRskirZlImsA6lGDoteKKF/Xc4Y6IoIx +IZ7XSK7klO/qN0ZPHWiu9QAtNBc4vVZEz83aXEbKH7eCOtSz07cOIT6yrvUF1122 +5Y0enn+DOLEcBBwI5KLco0udERz/Epn90eUWgbibP4QIaVQJypFC17RU3fXkiqZj +b0QyB2WEYi8awyB6KgZfu1PvzuvHYuKugBeYVwIDAQABAoIBACqQz4rLgDiHIpsD +TmGbzfqvcrLvgb9R5T74aGbKs/vzVhdozp7j23CZsDYvDN/E8aWlOWgkQ/9DG+Qy +Ai9FJJ6ZEXL/s1ry19nyT+cnzxNSzgSw7vIZaFBd+RViFadr9kzxj8HHxNclf1GN +n4cloajuIpG2OCwfSE8er/XG8535cc7aErTpuhj5EoqRtYy++VkiC0d3VSaCE/uW +J1ulfGnaZ3qiJfr6o+0xlTPYFcK5pkm+3uvTdSYZeLSSJPfnnaqx7G8yxoVZ1QaH +3Sey4Ax1Y8vGYtbJ2ZS7NlnBgbgSDPGimZMFfoGFThK4Y5AcqGIEByZvOSByXnQ6 +tHiB6OECgYEA3KJIThM+RtwAk17MoRvkdUl+iPj0k+Go7lJQycFgCeNfp2rylqYm +K1/Hzo0rSueVVRO3iL+clxt3bYHHNk62nJnp+nnkAaETTs9A8QRwGk418BKw9HyR +faSrmXkTgKlY+sWrwECP9SyLa80UPyWIyIeOqb/zvjfirRRaPRFQTrECgYEA2PUI +HYSqia+iOm4XEOtlUMHbNnLhW/aFhBingABt/CMO0cPTCCYdEzS+xDZzF7MROHzd +O6zJyLUtenTIwN3dcVTWCPCRxcAY4p6V/PjV0c/b0vteQ4WWFM/l6ubTAwX+uJih +SQREkqseMPLAqeEX84yZfqb/N3s2N2GuGIbP6YcCgYEAsztlz38UbU3VbeJqC0r0 +WU896pmLXgLIT+ow1OUxVncOQpu/vB/3C+9ACoxlqfDdQALHauB1nc9jQmNV6Mki +0a67A443ahdm7vOwhtqbEtOMP51/gO0c59t4xzEzZaassPMZphEMoRfxnr43f2DH +cFemzkEwCcuuafoJoGhLO9ECgYA2yAg4i9sT0QlBf7LLTuTSM2DKqs9EjUbBSAhj +Rbh/xcpkJPIQSK9mvha9LJJ7FXfvr3edLc/1oenN1dcq+9qCV02EDFqCeDLQZgKx +UZOL2tRCvb3bhsuSjbwcSBRX2xeqPL/c0/sMnbCN433KZ0/I62OGm1wuAip6aWuw +PboZ2QKBgFaEqOCUFMGHet0A/BOGkzkpCZsXl+EDqvx9l7s30vdv2NIoNR8V+Zl3 +B2arO/jGjDZnbGJcHG6B7WrCX8aJyM7Fm9akbreL7lWWzqKXs1lDHwAxqQN/TllI +tO5XRx7AHoJXkEmzKAwQWAbKzRKLTp0x9lcOBGz8CR29oPxZI2/H +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/host_vars/v1.yml b/host_vars/manager.yml similarity index 79% rename from host_vars/v1.yml rename to host_vars/manager.yml index 086419f..0902bde 100644 --- a/host_vars/v1.yml +++ b/host_vars/manager.yml @@ -3,4 +3,5 @@ docker_swarm_addr: 192.168.56.4 docker_swarm_interface: eth1 pip_install_packages: - - docker \ No newline at end of file + - docker + - jsondiff \ No newline at end of file diff --git a/host_vars/ovh01.yml b/host_vars/ovh01.yml index 182e94f..e2ebfb6 100644 --- a/host_vars/ovh01.yml +++ b/host_vars/ovh01.yml @@ -3,4 +3,5 @@ docker_swarm_addr: 100.96.125.190 docker_swarm_interface: wt0 pip_install_packages: - - docker \ No newline at end of file + - docker + - jsondiff \ No newline at end of file diff --git a/host_vars/v2.yml b/host_vars/worker.yml similarity index 100% rename from host_vars/v2.yml rename to host_vars/worker.yml diff --git a/hosts b/hosts index 89507ad..96d7f79 100644 --- a/hosts +++ b/hosts @@ -11,19 +11,13 @@ scaleway ansible_host=163.172.84.28 ansible_user=stephane scale01 ansible_host=163.172.209.36 ansible_user=stephane ovh01 ansible_host=5.135.181.11 ansible_user=stephane -[worker] - -[kubernetes:children] -control -worker - [docker_swarm_manager] -v1 ansible_host=192.168.121.68 ansible_user=vagrant ansible_ssh_pass=vagrant -ovh01 ansible_host=5.135.181.11 ansible_user=stephane +manager ansible_host=192.168.121.68 ansible_user=vagrant ansible_ssh_pass=vagrant +#ovh01 ansible_host=5.135.181.11 ansible_user=stephane [docker_swarm_worker] -v2 ansible_host=192.168.121.128 ansible_user=vagrant ansible_ssh_pass=vagrant -scale01 ansible_host=163.172.209.36 ansible_user=stephane +worker ansible_host=192.168.121.128 ansible_user=vagrant ansible_ssh_pass=vagrant +#scale01 ansible_host=163.172.209.36 ansible_user=stephane [vagrant:children] docker_swarm_manager diff --git a/portainer-traefik-agent.yml b/portainer-traefik-agent.yml index 724a3cf..6347fc5 100644 --- a/portainer-traefik-agent.yml +++ b/portainer-traefik-agent.yml @@ -5,7 +5,6 @@ services: image: "traefik:latest" command: - --entrypoints.web.address=:80 - - --entryPoints.web.forwardedHeaders.insecure=true - --entrypoints.websecure.address=:443 - --providers.docker=true - --providers.swarm=true @@ -14,7 +13,7 @@ services: - --api=true - --api.dashboard=true - --api.insecure=true - - --log.level=INFO + - --log.level=DEBUG deploy: mode: replicated replicas: 1 @@ -24,6 +23,10 @@ services: - "traefik.http.routers.dashboard.rule=Host(`traefik.test.com`)" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.services.dashboard.loadbalancer.server.port=8080" + tls: + certificates: + - certFile: /certificates/jingoh.private.crt + keyFile: /certificates/jingoh.private.key ports: - target: 80 published: 80 @@ -35,6 +38,7 @@ services: - public volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" + - traefik-public-certificates:/certificates agent: image: portainer/agent:latest @@ -56,7 +60,7 @@ services: portainer: image: portainer/portainer-ce:latest - command: -H tcp://tasks.agent:9001 --tlsskipverify + command: -H tcp://tasks.agent:9001 --tlsskipverify --http-enabled volumes: - /var/run/docker.sock:/var/run/docker.sock - data:/data @@ -71,15 +75,31 @@ services: constraints: [node.role == manager] labels: - "traefik.enable=true" - - "traefik.http.routers.portainer.rule=Host(`portainer.test.com`)" - - "traefik.http.routers.portainer.entrypoints=web" + - "traefik.http.routers.portainer.rule=Host(`portainer.jingoh.private.com`)" + - "traefik.http.routers.portainer.entrypoints=websecure" - "traefik.http.routers.portainer.service=portainer" - - "traefik.http.services.portainer.loadbalancer.server.port=9000" + - "traefik.http.services.portainer.loadbalancer.server.port=9443" + - "traefik.http.routers.portainer.tls=true" # Edge - - "traefik.http.routers.edge.rule=Host(`edge.test.com`)" - - "traefik.http.routers.edge.entrypoints=web" + - "traefik.http.routers.edge.rule=Host(`edge.private.com`)" + - "traefik.http.routers.edge.entrypoints=websecure" - "traefik.http.services.edge.loadbalancer.server.port=8000" - "traefik.http.routers.edge.service=edge" + - "traefik.http.routers.edge.tls=true" + + whoami: + image: "traefik/whoami" + deploy: + labels: + - "traefik.enable=true" + - "traefik.http.routers.whoami.rule=Host(`whoamitest.jingoh.private`)" + - "traefik.http.routers.whoami.entrypoints=web" + - "traefik.http.services.whoami.loadbalancer.server.port=80" + - "traefik.http.routers.whoami-secured.rule=Host(`whoamitest.jingoh.private`)" + - "traefik.http.routers.whoami-secured.entrypoints=websecure" + - traefik.docker.network=public + networks: + - public networks: public: @@ -88,4 +108,5 @@ networks: external: true attachable: true volumes: - data: \ No newline at end of file + data: + traefik-public-certificates: \ No newline at end of file diff --git a/swarm.yml b/swarm.yml index 95510b7..122fd35 100644 --- a/swarm.yml +++ b/swarm.yml @@ -1,6 +1,8 @@ --- - name: Swarm - hosts: control + hosts: + # - control + - vagrant become: true # @@ -62,13 +64,267 @@ - roles: - - { role: geerlingguy.pip, tags: pip } - - { role: geerlingguy.docker, tags: docker } - - { role: asg1612.dockerswarm, tags: swarm } + # roles: + # - { role: geerlingguy.pip, tags: pip } + # - { role: geerlingguy.docker, tags: docker } + # - { role: asg1612.dockerswarm, tags: swarm } tasks: + - name: Create network + community.docker.docker_network: + name: "{{ item.name }}" + scope: swarm + driver: overlay + internal: false + attachable: "{{ item.attachable }}" + run_once: true + loop: + - name: agent_network + attachable: true + - name: public + attachable: false + when: inventory_hostname in groups['docker_swarm_manager'] + + - name: Create volume + community.docker.docker_volume: + name: portainer_data + run_once: true + when: inventory_hostname in groups['docker_swarm_manager'] + + - name: Create secret (from a file on the control machine) + community.docker.docker_secret: + name: "{{ item.name }}" + # If the file is JSON or binary, Ansible might modify it (because + # it is first decoded and later re-encoded). Base64-encoding the + # file directly after reading it prevents this to happen. + data: "{{ lookup('file', '{{ playbook_dir }}/{{ item.path }}') | b64encode }}" + data_is_b64: true + state: present + loop: + - name: wildcard-jingoh-private.crt + path: /files/swarm/tls/jingoh.private.crt + - name: wildcard-jingoh-private.key + path: /files/swarm/tls/jingoh.private.key + run_once: true + when: inventory_hostname in groups['docker_swarm_manager'] + + - name: Create config (from a file on the control machine) + community.docker.docker_config: + name: traefik-dynamic-configuration + # If the file is JSON or binary, Ansible might modify it (because + # it is first decoded and later re-encoded). Base64-encoding the + # file directly after reading it prevents this to happen. + data: "{{ lookup('file', '{{ playbook_dir }}/files/swarm/config/traefik-dynamic-configuration.yml') | b64encode }}" + data_is_b64: true + state: present + run_once: true + when: inventory_hostname in groups['docker_swarm_manager'] + + # - name: Change file ownership, group and permissions + # ansible.builtin.file: + # path: /opt/stack.yml + # owner: root + # group: root + # mode: '0644' + # state: touch + # when: inventory_hostname in groups['docker_swarm_manager'] + + - name: Copy using inline content + ansible.builtin.copy: + content: "version: '3.13'" + dest: /opt/stack.yml + when: inventory_hostname in groups['docker_swarm_manager'] + + # - name: Copy file with owner and permissions + # ansible.builtin.copy: + # src: /{{ playbook_dir }}/files/swarm/stack.yml + # dest: /opt/stack.yml + # owner: root + # group: root + # mode: '0644' + # run_once: true + # when: inventory_hostname in groups['docker_swarm_manager'] + + - name: Deploy stack from a compose file + community.docker.docker_stack: + state: present + name: cluster + compose: + - /opt/stack.yml + - version: '3.13' + # https://github.com/akhil/traefik-docker-swarm-example/blob/master/traefik.yml + - services: + traefik: + # Image tag (replace with yours) + image: traefik:latest + command: + - "--log.level=DEBUG" + - "--accesslog=true" + - "--api.dashboard=true" + - "--api.insecure=true" + - "--entryPoints.web.address=:80" + - "--entryPoints.websecure.address=:443" + - "--providers.docker=true" + - "--providers.docker.watch=true" + - "--providers.swarm=true" + - "--providers.docker.network=public" + - "--providers.docker.endpoint=unix:///var/run/docker.sock" + - "--providers.docker.exposedByDefault=false" + - "--providers.file.filename=/etc/traefik/configs/traefik-dynamic-configuration.yml" + # - "--metrics.prometheus=true" + # - "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0" + - "--global.checkNewVersion=true" + - "--global.sendAnonymousUsage=false" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + networks: + - public + ports: + - "80:80" + - "443:443" + # For Mattermost + # - "8443:8443" + configs: + - source: traefik-dynamic-configuration + target: /etc/traefik/configs/traefik-dynamic-configuration.yml + secrets: + - wildcard-jingoh-private.crt + - wildcard-jingoh-private.key + labels: + - "io.portainer.accesscontrol.public" + deploy: + mode: replicated + replicas: 1 + placement: + constraints: + - node.role == manager + update_config: + delay: 15s + parallelism: 1 + monitor: 10s + failure_action: rollback + max_failure_ratio: 0.55 + labels: + - "traefik.enable=true" + # Traefik URL (replace with yours) + - "traefik.http.routers.dashboard.rule=Host(`traefikswarm.jingoh.private`)" + - "traefik.http.routers.dashboard.service=api@internal" + - "traefik.http.routers.dashboard.entrypoints=websecure" + - "traefik.http.services.dashboard.loadbalancer.server.port=8080" + - "traefik.http.routers.dashboard.tls=true" + - "traefik.http.services.dashboard.loadbalancer.passhostheader=true" + - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)" + - "traefik.http.routers.http-catchall.entrypoints=web" + - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" + - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" + + agent: + image: portainer/agent:latest + environment: + # REQUIRED: Should be equal to the service name prefixed by "tasks." when + # deployed inside an overlay network + AGENT_CLUSTER_ADDR: tasks.agent + AGENT_PORT: 9001 + LOG_LEVEL: DEBUG + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /var/lib/docker/volumes:/var/lib/docker/volumes + networks: + - agent_network + labels: + - "io.portainer.accesscontrol.public" + deploy: + mode: global + placement: + constraints: [node.platform.os == linux] + + portainer: + image: portainer/portainer-ce:latest + command: -H tcp://tasks.agent:9001 --tlsskipverify + volumes: + - portainer_data:/data + networks: + - public + - agent_network + labels: + - "io.portainer.accesscontrol.public" + deploy: + mode: replicated + replicas: 1 + placement: + constraints: [node.role == manager] + labels: + # Frontend + - "traefik.enable=true" + - "traefik.docker.network=public" + - "traefik.http.routers.frontend.rule=Host(`portainer.jingoh.private`)" + - "traefik.http.routers.frontend.entrypoints=websecure" + - "traefik.http.services.frontend.loadbalancer.server.port=9000" + - "traefik.http.routers.frontend.service=frontend" + - "traefik.http.routers.frontend.tls=true" + # Edge + - "traefik.http.routers.edge.rule=Host(`edge.jingoh.private`)" + - "traefik.http.routers.edge.entrypoints=websecure" + - "traefik.http.services.edge.loadbalancer.server.port=8000" + - "traefik.http.routers.edge.service=edge" + - "traefik.http.routers.edge.tls=true" + + whoami: + image: "traefik/whoami" + labels: + - "io.portainer.accesscontrol.public" + deploy: + labels: + - "traefik.enable=true" + - "traefik.docker.network=public" + - "traefik.http.routers.whoami.rule=Host(`whoamitest.jingoh.private`)" + - "traefik.http.routers.whoami.entrypoints=websecure" + - "traefik.http.services.whoami.loadbalancer.server.port=80" + - "traefik.http.routers.whoami.tls=true" + networks: + - public + + networks: + public: + external: true + agent_network: + external: true + attachable: true + volumes: + portainer_data: + + + + configs: + traefik-dynamic-configuration: + external: true + + secrets: + wildcard-jingoh-private.crt: + external: true + + wildcard-jingoh-private.key: + external: true + + run_once: true + when: inventory_hostname in groups['docker_swarm_manager'] + +# docker network create -d overlay agent_network +# docker network create -d overlay public +# docker volume create portainer_data + +# Create a secret for storing the certificate using the command: +# docker secret create wildcard-jingoh-private.crt jingoh.private.crt + +# Create a secret for storing the key using the command: +# docker secret create wildcard-jingoh-private.key jingoh.private.key + +# Create a config for storing the Traefik configuration using the command: +# docker config create traefik-dynamic-configuration.yml traefik-dynamic-configuration.yml + +# docker stack deploy -c stack.yml stack + # - ansible.builtin.include_role: # name: softing.swarm.softing_swarm_certs # apply: