diff --git a/Dockerfile b/Dockerfile index 84404ae..53f50a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,33 @@ 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 -COPY requirements.txt . +RUN pip install --upgrade --no-cache-dir pip + +COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY app.py . COPY templates/ templates/ -COPY static/ static/ -ENV DATA_DIR=/data -VOLUME ["/data"] +ENV DATA_DIR=/app/instance \ + PORT=9756 \ + HOST=0.0.0.0 + +RUN mkdir -p /app/instance + EXPOSE 9756 -RUN useradd -m appuser && chown -R appuser /app -USER appuser - -CMD ["python", "app.py"] +CMD ["sh", "-c", "python app.py"] diff --git a/app.py b/app.py index 54b8a63..57469b5 100644 --- a/app.py +++ b/app.py @@ -191,6 +191,11 @@ def serve_upload(filename): return send_from_directory(UPLOAD_DIR, filename) +@app.route('/health') +def health(): + return jsonify({'status': 'healthy', 'service': 'citti'}) + + @app.route('/api/category', methods=['POST']) def add_category(): d = request.json @@ -255,6 +260,7 @@ def analyse(): if __name__ == '__main__': init_db() + port = int(os.environ.get('PORT', 9756)) try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) @@ -262,6 +268,6 @@ if __name__ == '__main__': s.close() except Exception: local_ip = "127.0.0.1" - print(f"\n Computer: http://localhost:9756") - print(f" Telefon (samme WiFi): http://{local_ip}:9756\n") - app.run(host='0.0.0.0', port=9756, debug=False) + print(f"\n Computer: http://localhost:{port}") + print(f" Telefon (samme WiFi): http://{local_ip}:{port}\n") + app.run(host='0.0.0.0', port=port, debug=False) diff --git a/citti.nomad b/citti.nomad index 1f0a6fd..515dafb 100644 --- a/citti.nomad +++ b/citti.nomad @@ -1,50 +1,102 @@ job "citti" { + region = "global" datacenters = ["dc1"] type = "service" + 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 "app" { count = 1 - volume "citti-data" { - type = "host" - read_only = false - source = "citti-data" + network { + port "http" {} } - network { - port "http" { - static = 9756 + reschedule { + attempts = 5 + interval = "10m" + delay = "30s" + delay_function = "exponential" + max_delay = "120s" + unlimited = false + } + + volume "citti-data" { + type = "host" + source = "citti-data" + read_only = false + } + + service { + provider = "consul" + name = "citti" + port = "http" + + tags = [ + "traefik.enable=true", + "traefik.http.routers.citti.rule=Host(`citti.i80.dk`)", + "traefik.http.routers.citti.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" + volume_mount { + volume = "citti-data" + destination = "/app/instance" + read_only = false + } + config { image = "registry.i80.dk/gitea/citti:latest" ports = ["http"] force_pull = true } - volume_mount { - volume = "citti-data" - destination = "/data" - read_only = false + restart { + attempts = 10 + interval = "10m" + delay = "10s" + mode = "fail" } env { - DATA_DIR = "/data" + DATA_DIR = "/app/instance" + PORT = "${NOMAD_PORT_http}" + HOST = "0.0.0.0" } resources { cpu = 200 memory = 256 } - - service { - name = "citti" - port = "http" - } } } }