From 2d90c81204af26fa2613911099133eead0a1a930 Mon Sep 17 00:00:00 2001 From: Henrik Jess Nielsen Date: Mon, 9 Dec 2024 21:07:31 +0100 Subject: [PATCH] [main] Template update --- .gitea/workflows/main.yml | 61 ++++++++++++++++++++++++++++ .gitea/workflows/main.yml.tmpl | 2 + .gitea/workflows/nomad-job.hcl | 60 +++++++++++++++++++++++++++ .gitea/workflows/nomad-job.hcl.tmpl | 4 +- .gitignore | 2 + project-installer | Bin 95791 -> 95845 bytes 6 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 .gitea/workflows/main.yml create mode 100644 .gitea/workflows/nomad-job.hcl diff --git a/.gitea/workflows/main.yml b/.gitea/workflows/main.yml new file mode 100644 index 0000000..855d90d --- /dev/null +++ b/.gitea/workflows/main.yml @@ -0,0 +1,61 @@ +name: Build, Push, and Deploy to Nomad + +on: + push: + branches: + - main + +jobs: + docker-nomad: + runs-on: self-hosted + steps: + - name: Check out code + uses: actions/checkout@v3 + + - name: Log in to Container Registry + run: echo ${{ secrets.password }} | docker login registry.i80.dk -u ${{ secrets.username }} --password-stdin + + - name: Build Docker Image + run: | + COMMIT_HASH=$(git rev-parse --short HEAD) + docker build -t registry.i80.dk/gitea/pythontemplateproject:latest -t registry.i80.dk/gitea/pythontemplateproject:${COMMIT_HASH} . + + + - name: Push Docker Image + run: | + COMMIT_HASH=$(git rev-parse --short HEAD) + echo "registry.i80.dk/gitea/pythontemplateproject:latest" + echo "registry.i80.dk/gitea/pythontemplateproject:${COMMIT_HASH}" + docker push registry.i80.dk/gitea/pythontemplateproject:${COMMIT_HASH} + docker push registry.i80.dk/gitea/pythontemplateproject:latest + + + - name: Validate Nomad Job + env: + NOMAD_ADDR: https://nomad.i80.dk + run: nomad job validate .gitea/workflows/nomad-job.hcl + + - name: Stop old deployment + env: + NOMAD_ADDR: https://nomad.i80.dk + run: nomad job stop -purge -no-shutdown-delay pythontemplateproject + continue-on-error: true + + + - name: Apply Nomad Job + env: + NOMAD_ADDR: https://nomad.i80.dk + run: nomad job run .gitea/workflows/nomad-job.hcl + + - name: Update Nginx Configuration + run: ssh runner@nomad sudo /opt/nginx_updater/venv/bin/python3 /opt/nginx_updater/nginx_updater.py pythontemplateproject + + + +# - name: Restart Nomad Job +# env: +# NOMAD_ADDR: https://nomad.i80.dk +# run: | +# nomad job stop pythontemplateproject +# sleep 5 # Optional: Wait to ensure the old allocation is stopped +# nomad job run .gitea/workflows/nomad-job.hcl diff --git a/.gitea/workflows/main.yml.tmpl b/.gitea/workflows/main.yml.tmpl index 6075429..cce4463 100644 --- a/.gitea/workflows/main.yml.tmpl +++ b/.gitea/workflows/main.yml.tmpl @@ -50,6 +50,8 @@ jobs: - name: Update Nginx Configuration run: ssh runner@nomad sudo /opt/nginx_updater/venv/bin/python3 /opt/nginx_updater/nginx_updater.py [[PROJECT_NAME]] + - name: Update Forwarder Configuration + run: ssh runner@nomad sudo /opt/nginx_updater/venv/bin/python3 /opt/nginx_updater/update_forwarder.py [[PROJECT_NAME]] # - name: Restart Nomad Job diff --git a/.gitea/workflows/nomad-job.hcl b/.gitea/workflows/nomad-job.hcl new file mode 100644 index 0000000..e4a0df7 --- /dev/null +++ b/.gitea/workflows/nomad-job.hcl @@ -0,0 +1,60 @@ +job "pythontemplateproject" { + region = "global" + datacenters = ["dc1"] + type = "service" + + update { + stagger = "60s" + max_parallel = 1 + progress_deadline = "6m" + } + + group "pythontemplateproject-group" { + count = 1 + + network { + port "port-app" { + to = 9048 # Internal application port + } + } + + # Register the service with Consul + service { + provider = "consul" + name = "pythontemplateproject" + port = "port-app" + + # Traefik-specific tags for routing + tags = [ + "PORT=${NOMAD_PORT_port-app}" + ] + + # Define a health check using TCP + check { + name = "tcp_check" + type = "tcp" + interval = "10s" + timeout = "2s" + } + } + + task "pythontemplateproject-task" { + driver = "docker" + + config { + image = "registry.i80.dk/gitea/pythontemplateproject:latest" + ports = ["port-app"] + } + + env { + APP_ENV = "production" + PORT = "${NOMAD_PORT_port-app}" + } + + resources { + cpu = 250 + memory = 80 + } + } + } +} diff --git a/.gitea/workflows/nomad-job.hcl.tmpl b/.gitea/workflows/nomad-job.hcl.tmpl index b3946ab..71756e0 100644 --- a/.gitea/workflows/nomad-job.hcl.tmpl +++ b/.gitea/workflows/nomad-job.hcl.tmpl @@ -1,4 +1,4 @@ -job "{{PROJECT_NAME}}" { +job "[[PROJECT_NAME]]" { region = "global" datacenters = ["dc1"] type = "service" @@ -42,7 +42,7 @@ job "{{PROJECT_NAME}}" { driver = "docker" config { - image = "registry.i80.dk/gitea/{{PROJECT_NAME}}:latest" + image = "registry.i80.dk/gitea/[[PROJECT_NAME]]:latest" ports = ["port-app"] } diff --git a/.gitignore b/.gitignore index 61660b6..82fef80 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .venv/* .ídea .idea/* +.gitea/**/build*/ + diff --git a/project-installer b/project-installer index e602fd7f560794bc2e2073231376c6f575e2de70..83e9ac0b9b0bc5ece12a73d95eb6e0a9d969371b 100755 GIT binary patch delta 10673 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 delta 10683 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 w=i<4aQGZn-83c@|18A0(uGUU&mX>_*B*udOvj&