Skip to content

Semaphore - Installation & Anwendung

Verschoben Ansible
4 1 2.0k
  • Semaphore ist ein UI für Ansible, geschrieben mit Go & Vue.js. Beim Besuch der letzten FrOSCon 18 lernt man ja immer was dazu. Es wurde Zeit das mal auszuprobieren.

    Bis jetzt habe ich meine Server, einmal in der Hetzner-Cloud zum anderen Lokal, immer mit ClusterSSH administriert. Das ist für mich völlig ausreichend, aber ich möchte gerne auch immer was dazu lernen.

    Ok, dann fangen wir mal an.

    Installation

    Voraussetzungen

    • Debian Bookworm 12 Server
    • vorhandenen MariaDB Instanz
    • Linux Grundkenntnisse

    Ich werde nicht alles bis ins letzte Detail hier aufschreiben, aber mit Grundkenntnissen sollte man in der Lage sein, das erfolgreich umzusetzen.

    Die Anleitung empfiehlt folgende Vorgehensweise.

    wget https://github.com/ansible-semaphore/semaphore/releases/\
    download/v2.8.75/semaphore_2.8.75_linux_amd64.deb
    
    sudo dpkg -i semaphore_2.8.75_linux_amd64.deb
    

    Ich ändere das ein wenig ab. Zum einen, ist die Dokumentation nicht ganz aktuell und zum anderen brauche ich kein sudo.

    wget https://github.com/ansible-semaphore/semaphore/releases/\
    download/v2.8.90/semaphore_2.8.90_linux_amd64.deb
    
    dpkg -i semaphore_2.8.90_linux_amd64.deb
    

    Danach ruft man das Setup auf

    semaphore setup
    

    und ergänzt die Abfragen. Kleiner Tipp von mir, der Web Host bleibt leer, sonst ist die Installation defekt. Für Euch getestet. Bezieht sich nur auf eine lokale Installation. Siehe meine Ergänzung zum Thema Email.

    "web_host": "",
    

    Wenn man das Ganze jetzt als User root gemacht hat, liegt die Konfigurationsdatei config.json unter /root

    Das machen wir jetzt mal was sicherer. Eine Anwendung sollte ja unter seinem eigenen User laufen, kein Dienst der nicht unbedingt Rootrechte benötigt, bekommt diese auch. Also legen wir uns dafür einen User an, der heißt hier semaphore - Überraschung 🙂

    User anlegen

    Den User legen wir mit

    useradd -m semaphore
    

    an. Damit hat dieser User auch ein Home-Verzeichnis unter /home/semaphore Nun kopieren wir schon mal die config.json hierhin.

    mv /root/config.json /home/semaphore
    

    Jetzt muss der Dienst auch noch gestartet werden, dazu legen wir einen SystemD Service an.

    /etc/systemd/system/semaphore.service

    [Unit]
    Description=Ansible Semaphore
    Documentation=https://docs.ansible-semaphore.com/
    Wants=network-online.target
    After=network-online.target
    ConditionPathExists=/usr/bin/semaphore
    ConditionPathExists=/home/semaphore/config.json
    
    [Service]
    ExecStart=/usr/bin/semaphore service --config /home/semaphore/config.json
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=always
    RestartSec=10s
    User=semaphore
    Group=semaphore
    
    
    [Install]
    WantedBy=multi-user.target
    

    Den Dienst aktivieren und starten ihn

    systemctl enable semaphore.service
    systemctl start semaphore.service
    

    Danach sollte man in der Lage sein, das Webinterface aufzurufen. Hier das Beispiel meiner Proxmox VM. Passt das an Eure Gegebenheiten bitte an.

    http://192.168.3.14:3000/
    

    TASK_ergebnis.png

    NGINX

    Sollte man das ganze im Netz betreiben wollen, dann sollte man einen Proxy davor schalten. Hier mal ein Beispiel aus der Doku.

    Man muss dann nicht

    http://192.168.3.14:3000/
    

    eingeben, um den Server zu erreichen. Es reicht dann

    http://192.168.3.14
    

    Die NGINX Beispiel Konfiguration

    server {
      listen 443 ssl;
      server_name  _;
    
      # add Strict-Transport-Security to prevent man in the middle attacks
      add_header Strict-Transport-Security "max-age=31536000" always;
    
      # SSL
      ssl_certificate /etc/nginx/cert/cert.pem;
      ssl_certificate_key /etc/nginx/cert/privkey.pem;
    
      # Recommendations from 
      # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
      ssl_protocols TLSv1.1 TLSv1.2;
      ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
      ssl_prefer_server_ciphers on;
      ssl_session_cache shared:SSL:10m;
    
      # required to avoid HTTP 411: see Issue #1486 
      # (https://github.com/docker/docker/issues/1486)
      chunked_transfer_encoding on;
    
      location / {
        proxy_pass http://127.0.0.1/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_set_header X-Forwarded-Proto $scheme;
    
        proxy_buffering off;
        proxy_request_buffering off;
      }
    
      location /api/ws {
        proxy_pass http://127.0.0.1/api/ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Origin "";
      }
    }
    

    Das habe ich aktuell nicht getestet, da mein Semaphore-Server lokal steht und es auch so bleiben soll.

    Für eine Anwendung, gitlab.com, brauch ich den doch im Netz. Habe das probiert und funktioniert auch. Kommt aber sicher noch ein ergänzender Beitrag von mir (Update: 20.08.23)

    SSH

    Wichtig ist, das der User semaphore auf alle Server, die er erreichen soll, mittels

    ssh root@<DOMAIN oder IP>
    

    connecten kann. Dazu muss die id_rsa.pub auf den Zielsystemen unter authorized_keys hinterlegt sein. Das solltet ihr kennen, wenn nicht mal kurz hier rein lesen. Zusammenfassung:

    Der User semaphore muss mittels

    ssh root@<DOMAIN oder IP>
    

    connecten können!

    Einrichtung eines Projektes

    Wir legen ein neues Projekt an.

    2395e6ef-847a-4abb-8541-1fb0e20abf2d-grafik.png

    Namen eingeben, der Rest ist optional. Danach legen wir den Key an.

    Key Store

    3157efe2-fe75-46ce-8d28-62ea0a13bf72-grafik.png

    Wir geben ihm einen Namen, wählen SSH Key aus, als Username wählen wir root und geben den Private Key des Semaphore Servers ein.

    Repositories

    dead2fe3-156d-4b3f-b9a0-ea3cf79cbc80-grafik.png

    Wir geben ihm einen Namen. Der Pfad zeigt auf einen Ordner im Home-Verzeichnis des Users semaphore. Ich nenne das hier im Beispiel ansible, dort liegen hinterher die Playbooks usw.

    Environment

    170bfcec-5683-426f-aef1-6e92613c0536-grafik.png

    Dort kann man Umgebungsvariablen ablegen. Brauchen wir aktuell nicht, muss aber angelegt sein. Deswegen muss das so aussehen. Also, ohne Inhalt.

    Inventory

    23f609ca-e37b-42fb-82a7-5a726d736ffe-grafik.png

    Hier legt man an, welche Server bearbeitet werden sollen. Denke, das ist selbsterklärend. Der Name [Name] kann beliebig sein.

    Task Template

    94b8c36c-c5ab-4e7d-84c7-46cf8fb73ac3-grafik.png

    Jetzt könnt Ihr alles auswählen. Das Playbook Filename hat mich etwas Zeit gekostet um zu verstehen, wo das liegt. Da kommt jetzt wieder das Repository zum Einsatz. Der dort hinterlegte Pfad wird jetzt für das Playbook benutzt.

    Das Playbook task.yml haben wir noch nicht, kommt noch 🙂 Das kann man jetzt aber nicht in dem UI anlegen und bearbeiten, wir müssen auf die Konsole des Servers.

    Playbook anlegen

    Das Playbook muss hier liegen

    /home/semaphore/ansible
    

    /home/semaphore/ansible/task.yml

    ---
    - name: My task
      hosts: all
      tasks:
        # Update and install the base software
        - name: Update apt package cache.
          apt:
            update_cache: yes
            cache_valid_time: 600
    
        - name: Upgrade installed apt packages.
          apt:
            upgrade: 'yes'
            #register: upgrade
    
        - name: Ensure that a base set of software packages are installed.
          apt:
            name:
             - duf
             - needrestart
             - htop
             # - build-essential
             # - curl
             # - fail2ban
             # - firewalld
             # - git
             # - needrestart
             # - pwgen
             # - resolvconf
             # - restic
             # - rsync
             # - sudo
             # - unbound
             # - unzip
             # - vim-nox
            state: latest
    
        - name: Check if a new kernel is available
          ansible.builtin.command: needrestart -k -p > /dev/null; echo $?
          register: result
          ignore_errors: yes
    
        - name: No new kernel
          ansible.builtin.command: uname -r
          when: result.rc == 0
    
        - name: Restart the server if new kernel is available
          ansible.builtin.command: reboot
          when: result.rc == 2
          async: 1
          poll: 0
    
        - name: Wait for the reboot and reconnect
          wait_for:
            port: 22
            host: '{{ (ansible_ssh_host|default(ansible_host))|default(inventory_hostname) }}'
            search_regex: OpenSSH
            delay: 10
            timeout: 60
          connection: local
    
        - name: Check the Uptime of the servers
          shell: "uptime"
          register: Uptime
    
        - debug: var=Uptime.stdout
    

    Ich habe die letzten Tage an meinem Playbook gefeilt, die Dokumentation ist riesig. Richtige Hilfe im Netz ist selten, ChatGPT hat auch mehr Blödsinn geschrieben, als Hilfe. Zum Schluss habe ich es aber doch hinbekommen.

    Die Tasks

    1. Update apt package cache.
      Macht das was apt update auch macht, schaut nach neuen Paketen.

    2. Upgrade installed apt packages.
      Also ein apt upgrade

    3. Ensure that a base set of software packages are installed.
      Stellt sicher, das man bestimmte Software Pakete auf seinem Server installiert hat.

    4. Check if a new kernel is available
      Hat apt upgrade einen neuen Kernel installiert? Dazu nutze ich das Tool needrestart. Rückgabewert 0 bedeutet keinen neuen Kernel, Rückgabewert 2 bedeutet, es ist Zeit für einen Reboot. Interessantes Feature von ansible ist, man kann gewisse Dinge auch async machen. Ohne das knallte das Playbook immer mit Failure, weil logischerweise der Server nicht mehr erreichbar war. Spannend.

    5. No new kernel
      Rückgabe 0

    6. Restart the server if new kernel is available
      Rückgabe 2

    7. Wait for the reboot and reconnect
      Wir warten auf alle Server, bis alle Server wieder on sind.

    8. Check the Uptime of the servers
      Wir schauen nach dem die Server alle wieder on sind, ob sie auch leben 😉

    9. debug: var=Uptime.stdout
      Kontrolle der Uptime.

    Fertig!

    Task Ausgabe

    Task_1.png

    Task_2.png

    Fazit

    Mal wieder ein Tool, was @Nico mir empfohlen hat und was vermutlich aus meinem Leben nicht mehr verschwindet 🙂

    Hinweise

    Für einen Server im Netz fehlen da noch einige Dinge, also bitte so nicht ins Internet. Lokal ist das ausreichend.

    Sollte jemand Fehler finden, würde ich mich über eine Korrektur freuen. Man kann immer nur dazu lernen.

    Viel Spaß mit dem Tool!

  • Email

    Als Ergänzung, wenn man beim Setup keine Email Daten eingegeben hat.

    In der config.json findet man folgendes

            "email_sender": "<SENDER ADRESS>",
            "email_host": "smtps.<DOMAIN>.de",
            "email_port": "587",
            "email_username": "<USERNAME>",
            "email_password": "<PASSWORD>",
    

    Ging danach noch nicht. Man findet noch diese beiden Einstellungen.

            "email_alert": true,
            "email_secure": true,
    

    Der erste schaltet wohl die Email Funktionalität ein. Der zweite steuert vermutlich den Email-Port.

    Ports: 465 (SSL/TLS), 587 (STARTTLS)
    

    Ich nutze den Port 587 und email_secure muss auf true stehen.

    Habe dann einen Server ausgeschaltet um einen Failure zu provozieren. Danach kam diese Email.

    Task 119 with template 'TEST' has failed!`
    Task Log: /project/1/templates/1?t=119
    

    Und nun macht auch die Einstellung

    "web_host": "",
    

    Sinn. Bei einem ordentlich konfigurierten Server im Internet, der einen Domainnamen hat, kommt dieser jetzt in das Feld und dann wird der auch in der Email ergänzt. Somit hätte man auch direkt einen Link zum Log.

    Noch was, unter Edit User kann man einstellen das der User Emails versendet. Diese Mailadresse empfängt die Mails. Sieht nach einer schlechten Übersetzung aus!?

    Email.png

    Und unter den Projekt Settings kann man einstellen, ob das Projekt überhaupt Emails versenden darf.

    e880c667-bdb7-450c-aaab-5e3e95b9c8ce-grafik.png

  • Heute geht es dann mal ans Testen der Gitlab bzw. Github Funktionalität. Das Playbook jedes mal auf der Konsole zu editieren ist doof und macht ja auch kein Profi, viel zu mühsam. Das möchte man ja alles von seiner Maschine aus machen, im Idealfall mit seiner Entwicklungsumgebung.

    Gitlab

    Ihr erstellt Euch ein leeres neues Projekt. Dann legt man einen Access Token an.

    4f5fcf59-3250-43ec-886b-8c03540e2dfe-grafik.png

    Pycharm

    Ich nutze Pycharm, das geht aber mit jeder Entwicklungsumgebung gleich. Man legt ein neues Projekt an, erstellt das Playbook (task.yml) und commitet das zum Gitlab Projekt. Dazu benötigt man die URL des Gitlab Projektes und den Benutzer & das Passowrt des Access Tokens. Fertig, danach ist das Playbook im Gitlab.

    833caaa8-f201-490c-8609-dedc1abb1cc1-grafik.png

    Semaphore

    Im Semaphore Projekt muss man jetzt zwei Dingen anpassen.

    Key Store

    eaeb7b55-cd01-4de6-a776-b439e464a56f-grafik.png

    Wir geben dem Key einen Namen (beliebig), der Login wird auf Login with password eingestellt. Und User & Password befüllen wir mit den Daten des Access Tokens - fertig.

    Repositories

    e395246b-d2f6-488a-82f2-da1420f44587-grafik.png

    Dort gibt man die URL zum Gitlab Projekt ein. Dann den Branch, hier master. Ganz unten wählt man noch den eben angelegten Key aus. Um die Warnung weg zu bekommen, siehe unteres Bild, muss man nur anstelle von playbook - playbook.git eingeben.

    Resultat

    gitlab.png

  • FrankMF FrankM verschob dieses Thema von Linux am
  • Ich parke das mal hier, damit ich das nicht noch mal vergesse. Hat mich eben mal wieder eine Stunde gekostet 😞

    /etc/ansible/ansible.cfg

    [defaults]
    host_key_checking = False
    

    Edit -> https://linux-nerds.org/topic/1493/ansible-host_key_checking

  • FrankMF FrankM hat am auf dieses Thema verwiesen
  • OpenCloud - Storage Backends testen

    OpenCloud opencloud linux docker
    2
    0 Stimmen
    2 Beiträge
    117 Aufrufe
    FrankMF
    So, mal weiter damit beschäftigen. Also, durch meine ganze Testerei war doch ein Haufen Müll angefallen. dockeruser@opencloud:~/opencloud/deployments/examples/opencloud_full$ docker volume ls DRIVER VOLUME NAME local 0fcd6f237898477b251f3dacb6cd083996092b783f991f899b06d89befc41b1e local 1d8df3f5d41613ad93ed753ce2102a14738cf00e8e7d127ec79881660be291ab local 3b612ce20b207c226640d6b84c32c788cd0fad9f9157578c2310f4b3db63dd29 local 5dfdde733fefb9fdb805acec8338a860762e88cd0753f4bb4098a19fbcd4b6c3 local 6bd5659759fb99b0d0613175d2392ca268dbdb3bd0353b85ccdf9a6004e798c0 local 6f8881420aa0e7713ed5308e635fcb9382939b6570afbd1d776866a07f6d61f2 local 29f7d20edd9eda935041cea7af5aab0af748175d7df8f345288463753d2afa9a local 66ca6287706aac5013b458a109e7c143c4fb177670734fc7a0f68495b1c62fd4 local 74d304835ef51f91226cc22dbbd494d2ddc9a4d91badf88814cae24126efd04a local 0203eb654c1f28a60899ded4660fb101ea222a5f8c86a225d39f3e5da877f1c0 local 271c474feb2ed915afb8efa85e422461fcfdf8acd4097355841eadf33847b7ef local 569a8c34804afd5861299973bed023c0146f40c0dbda0d980b8651bbcadc7fc9 local 655b1f446b5db9749787d4be4445887dcb3d19906d4244d059a0f292a6cd5f01 local 843bb8d0d7845adab06e146c44b153b842d5a1a1d8eb3972bdee1d3cbcb7e815 local 987ee19b8639ad5fffabba276ceb1ca09af6ebc66efb007e561570589c9c53a8 local 1004f5b7b161a4fe37a07d7960740e5cd09b90d5744f1922fb3e41c1265f800a local 2043c77b57728106cbcca8b7e2d3ae2f07ddf4ca44ee21fca232526c95e07381 local 3685c81df1be0061352dfc5b0e6db8d8d9f9b0915a271f1ca53d2796a7876805 local 9581abcfb4fb42b2fabfabbc8139cc4659ca83d92a8b60041957565409293ef4 local 796650f1fa887ff0b153822b268a10aa3579f4f2ca3ce6855ff292e49b3bb6b8 local 426251107e3131a250b27b96e795355332127f19ccf1ec8252860aff5d0caec8 local bd43ceef38448db348cc34e7dc5c4fee9c834d8b6c5957b1e6cdb83cec7b0974 local d94e7ce6c0fb1f4f7b811f624b4526ea889f2f8b99d2aa1b21e79d00dfeb38d0 local e87a27c307a8be80839fae1c006273d57570bb99f60c78c95e86a1e9ea1a786c local f2b3e30406db730e2a341850243c115b6eb231f30f41f5353c7b2427de39af75 local opencloud_full_certs local opencloud_full_opencloud-apps local opencloud_full_opencloud-config local opencloud_full_opencloud-data Oje, das sieht ziemlich vermüllt aus. Dann mal ganz mutig alles löschen. Vorher alles gestoppt. docker compose down Volume löschen, nur ein Beispiel docker volume rm opencloud_full_opencloud-data Alles gelöscht. Dann mal ein Neustart docker compose up -d Jetzt sieht das schon viel besser aus. dockeruser@opencloud:~/opencloud/deployments/examples/opencloud_full$ docker volume ls DRIVER VOLUME NAME local 3737a8eab68ffdc08d6e41493346feeb2e06ef350a210213ab450775318e49f8 local opencloud_full_opencloud-apps Da ich neugierig bin, schauen wir mal rein. root@opencloud:~ ls -lha /var/lib/docker/volumes/3737a8eab68ffdc08d6e41493346feeb2e06ef350a210213ab450775318e49f8/_data/web/assets/apps/ total 8.0K drwxr-x--x 2 dockeruser dockeruser 4.0K May 19 18:25 . drwxr-x--x 3 dockeruser dockeruser 4.0K May 31 10:21 .. Vermutlich ein Speicher, wo die Web Apps was ablegen können. Der andere zeigt es dann klarer. root@opencloud-4gb-fsn1-2:~# ls -lha /var/lib/docker/volumes/opencloud_full_opencloud-apps/_data total 28K drwxr-x--x 7 dockeruser dockeruser 4.0K May 31 10:22 . drwx-----x 3 root root 4.0K May 31 10:21 .. drwxr-xr-x 2 root root 4.0K May 31 10:22 draw-io drwxr-xr-x 2 root root 4.0K May 31 10:21 external-sites drwxr-xr-x 3 root root 4.0K May 31 10:22 json-viewer drwxr-xr-x 2 root root 4.0K May 31 10:22 progress-bars drwxr-xr-x 3 root root 4.0K May 31 10:22 unzip Ok, das sollte mir erst mal reichen. Meine Installation lagert die certs ja aus, das habe ich im docker compose geändert. dockeruser@opencloud:~/opencloud/deployments/examples/opencloud_full$ ls -lha certs/ total 44K drwxr-xr-x 2 dockeruser dockeruser 4.0K May 30 05:49 . drwxr-xr-x 6 dockeruser dockeruser 4.0K May 31 10:38 .. -rw------- 1 dockeruser dockeruser 33K May 29 11:00 acme.json Im docker-compose.yml volumes: - ./certs:/certs # bind-mount acme.json Der Grund dafür ist, das ich das docker-compose nicht als root laufen haben möchte. Die Hauptdaten sind nach lokal ausgelagert. OC_CONFIG_DIR=/home/dockeruser/oc_data/config OC_DATA_DIR=/home/dockeruser/oc_data/data Somit sollte jetzt alles so passen und ich muss mal langsam mit der Spielerei aufhören
  • Proxmox Setup 2025

    Proxmox proxmox linux
    1
    3
    0 Stimmen
    1 Beiträge
    187 Aufrufe
    Niemand hat geantwortet
  • Proxmox 8.3 released

    Proxmox proxmox linux
    2
    0 Stimmen
    2 Beiträge
    279 Aufrufe
    FrankMF
    Ich habe gestern mal eine Neuigkeit ausprobiert, den Import einer Anwendung mittels OVA. Dazu habe ich irgendwo im Netz ein File für OpenProject gefunden (steht schon sehr lange auf meiner Testliste). Der Import war langweilig einfach. Nach Import ein paar Dinge eingestellt, Netzwerk usw. und die VM gestartet. Ok, die Installation war so alt, das ich sie danach wieder gelöscht habe, aber das soll ja kein Problem sein. Man kann OpenProject ja auch mittels .deb Package installieren. Zweiter Test war der "Tag View". Interessantes Feature, was ich auch mal direkt angewendet habe, auch wenn fast alle meine VMs Debian sind
  • Linux Mint Cinnamon 21.3 Virginia

    Linux linuxmint 21.3 linux wayland
    1
    2
    0 Stimmen
    1 Beiträge
    552 Aufrufe
    Niemand hat geantwortet
  • Debian Bookworm 12 - Restic

    Linux debian restic linux
    1
    0 Stimmen
    1 Beiträge
    196 Aufrufe
    Niemand hat geantwortet
  • 2,5G

    Linux linux
    2
    1
    0 Stimmen
    2 Beiträge
    239 Aufrufe
    FrankMF
    Gutes Video zum Zyxel Switch, was ich vorher gar nicht kannte. Hätte meine Entscheidung aber auch nicht verändert. https://www.youtube.com/watch?v=59I-RlliRms
  • NanoPI R2S - Snapshot aktualisieren

    NanoPi R2S nanopir2s openwrt linux
    3
    0 Stimmen
    3 Beiträge
    449 Aufrufe
    FrankMF
    @thrakath1980 Das kann ich Dir leider nicht beantworten. Denke aber, das es sinnvoll ist neu anzufangen. Welche Settings meinst Du? Ich würde mal /etc/config sichern. Da sollte das Meiste ja drin sein. Notifications? Hmm, ich hoffe das das funktioniert. Ich schau zur Sicherheit mal nach.
  • Redis oder MongoDB?

    Verschoben Redis nodebb linux redis
    1
    0 Stimmen
    1 Beiträge
    531 Aufrufe
    Niemand hat geantwortet