diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..cffe7ca --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,96 @@ +name: Build and Deploy Erika CV + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build-and-deploy: + runs-on: debian-host + + env: + PATH: /usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/bin:/snap/bin + DOCKER_HOST: unix:///var/run/docker.sock + BUILDX_CONFIG: /tmp/buildx + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: System info + run: | + uname -a + whoami + + - name: Set up Docker Context for Buildx + id: buildx-context + run: | + export DOCKER_HOST=tcp://docker:2376/ + export DOCKER_TLS_VERIFY=0 + docker context rm builders || true + docker context create builders + + - name: Verify Docker + run: docker --version + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + env: + PATH: /usr/bin:/usr/local/bin:/bin:/sbin:/usr/sbin + + - name: Log in to Harbor Registry + run: | + echo "${{ secrets.HARBOR_ROBOT_TOKEN }}" | docker login registry.i80.dk -u "robot\$gitserver" --password-stdin + env: + PATH: /usr/bin:/usr/local/bin:/bin:/sbin:/usr/sbin + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + env: + PATH: /usr/bin:/usr/local/bin:/bin:/sbin:/usr/sbin + with: + context: . + file: ./Dockerfile + push: true + tags: | + registry.i80.dk/gitea/web-erika:latest + registry.i80.dk/gitea/web-erika:${{ github.sha }} + build-args: | + BUILD_VERSION=${{ github.ref_name }}-${{ github.sha }} + GIT_COMMIT=${{ github.sha }} + BUILD_TIME=${{ github.event.head_commit.timestamp }} + + - name: Validate Nomad job + run: | + echo "Validating Nomad job..." + nomad job validate erika.nomad + env: + NOMAD_ADDR: "https://nomad.i80.dk:4646" + + - name: Deploy to Nomad + run: | + echo "Deploying to Nomad..." + nomad job run erika.nomad + env: + NOMAD_ADDR: "https://nomad.i80.dk:4646" + + - name: Wait for deployment + run: | + sleep 10 + nomad job status web-erika + nomad job allocs web-erika + env: + NOMAD_ADDR: "https://nomad.i80.dk:4646" + + - name: Health check + run: | + sleep 20 + curl -f https://erika.i80.dk/health || echo "Not yet available" + + - name: Notify deployment status + run: | + echo "Deployment complete" + echo "Site: https://erika.i80.dk" + echo "Health: https://erika.i80.dk/health" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e856613 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.12-slim + +ARG BUILD_VERSION=unknown +ARG BUILD_TIME=unknown +ARG GIT_COMMIT=unknown + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + FLASK_APP=app.py \ + FLASK_ENV=production \ + BUILD_VERSION=${BUILD_VERSION} \ + BUILD_TIME=${BUILD_TIME} \ + GIT_COMMIT=${GIT_COMMIT} + +WORKDIR /app + +RUN pip install --upgrade --no-cache-dir pip + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +ENV PORT=5000 \ + HOST=0.0.0.0 + +EXPOSE 5000 + +CMD ["sh", "-c", "gunicorn --bind ${HOST}:${PORT} --workers 2 --timeout 60 app:app"] diff --git a/Skærmbillede 2026-04-19 165611.png b/Skærmbillede 2026-04-19 165611.png new file mode 100644 index 0000000..49e3c14 Binary files /dev/null and b/Skærmbillede 2026-04-19 165611.png differ diff --git a/app.py b/app.py new file mode 100644 index 0000000..68a4c03 --- /dev/null +++ b/app.py @@ -0,0 +1,25 @@ +from flask import Flask, render_template, jsonify +from datetime import datetime, timezone +import os + +app = Flask(__name__) + +BUILD_VERSION = os.getenv('BUILD_VERSION', 'unknown') +GIT_COMMIT = os.getenv('GIT_COMMIT', 'unknown') + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/health') +def health(): + return jsonify({ + 'status': 'healthy', + 'timestamp': datetime.now(timezone.utc).isoformat(), + 'version': BUILD_VERSION, + 'commit': GIT_COMMIT[:7] if GIT_COMMIT != 'unknown' else 'unknown' + }) + +if __name__ == '__main__': + port = int(os.getenv('PORT', 5000)) + app.run(host='0.0.0.0', port=port) diff --git a/erika.nomad b/erika.nomad new file mode 100644 index 0000000..18d2e76 --- /dev/null +++ b/erika.nomad @@ -0,0 +1,95 @@ +job "web-erika" { + region = "global" + datacenters = ["dc1"] + type = "service" + + meta { + uuid = uuidv4() + deployed_at = "[[ timeNowUTC ]]" + } + + update { + stagger = "30s" + max_parallel = 1 + canary = 1 + min_healthy_time = "10s" + healthy_deadline = "5m" + auto_revert = true + auto_promote = true + progress_deadline = "10m" + } + + group "web" { + count = 1 + + network { + port "http" {} + } + + reschedule { + attempts = 5 + interval = "10m" + delay = "30s" + delay_function = "exponential" + max_delay = "120s" + unlimited = false + } + + service { + provider = "consul" + name = "erika" + port = "http" + + tags = [ + "traefik.enable=true", + "traefik.http.routers.erika.rule=Host(`erika.i80.dk`)", + "traefik.http.routers.erika.tls=true" + ] + + canary_tags = [ + "traefik.enable=false" + ] + + check { + name = "http_health_check" + type = "http" + path = "/health" + interval = "10s" + timeout = "5s" + + check_restart { + limit = 3 + grace = "10s" + } + } + } + + task "web" { + driver = "docker" + + config { + image = "registry.i80.dk/gitea/web-erika:latest" + ports = ["http"] + force_pull = true + } + + restart { + attempts = 10 + interval = "10m" + delay = "10s" + mode = "fail" + } + + env { + APP_ENV = "production" + PORT = "${NOMAD_PORT_http}" + HOST = "0.0.0.0" + } + + resources { + cpu = 100 + memory = 128 + } + } + } +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ab3471f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +flask>=3.0.0 +gunicorn>=22.0.0 diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..bbb6459 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,572 @@ + + + + + + Erika Stensvedny - CV + + + + + + +
+ + + + + +
+ + +
+
Erhvervserfaring
+
+ +
+
+
+
Marts 2026 - April 2026
+
Tjener - Restaurant Kujirasushi
+
Vordingborg
+
    +
  • Koordinerede med køkkenpersonalet for at sikre hurtig og præcis levering af retter
  • +
  • Assisterede i daglig opsætning og oprydning af restaurantens borde og serviceområder
  • +
  • Serverede mad og drikkevarer til gæster, hvilket sikrede en høj grad af kundetilfredshed
  • +
+
+
+ +
+
+
+
April 2026 - April 2026
+
Praktikant - Egmont
+
København
+
    +
  • Udvikling af hjemmeside
  • +
  • Test af AI-løsninger
  • +
  • Deltagelse i udviklingsmøder
  • +
+
+
+ +
+
+
+
Januar 2025 - Februar 2026
+
Privat Rengøring
+
Vordingborg / Stensved / Kalvehave
+
    +
  • Rengøring i private hjem
  • +
  • Effektiv udførelse af tildelte opgaver
  • +
+
+
+ +
+
+
+
Januar 2025 - Maj 2025
+
Rengøringshjælp - Møllers Grill
+
Vordingborg
+
    +
  • Planlagde og udførte rengøringsopgaver i henhold til en detaljeret tidsplan
  • +
  • Effektiv udførelse af tildelte opgaver
  • +
+
+
+ +
+
+
+
Oktober 2024 - Oktober 2024
+
Praktikant - Vordingborg Madservice
+
Nyråd
+
    +
  • Lavede mad til ældre borgere
  • +
  • Rengøring af køkken
  • +
+
+
+ +
+
+ + +
+
Uddannelse
+
+
+
August 2025 - Juni 2027
+
Hf-eksamen
+
Hf, Vordingborg
+
+
+
August 2023 - Juni 2024
+
10. klasse-eksamen
+
10. klasse, Næsved
+
+
+
August 2023 - Juni 2024
+
9. klasse-eksamen
+
9. klasse Efterskole, Glamsbjerg
+
+
+
+ + +
+
Sprog
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+ +