Parcourir la source

docker multi stage build

kevin il y a 2 ans
Parent
commit
be84b36c73
8 fichiers modifiés avec 66 ajouts et 67 suppressions
  1. 1 1
      .dockerignore
  2. 14 5
      Dockerfile
  3. 0 7
      build_docker.sh
  4. 7 0
      build_docker_base.sh
  5. 12 9
      docker-compose.yaml
  6. 13 43
      fr_flask.py
  7. 17 0
      gunicorn.conf.py
  8. 2 2
      run.sh

+ 1 - 1
.dockerignore

@@ -6,7 +6,7 @@ venv
 mysql
 Dockerfile
 configure.sh
-build_docker.sh
+build_docker_base.sh
 run_docker.sh
 face_align.py
 hello*

+ 14 - 5
Dockerfile

@@ -1,8 +1,8 @@
-FROM python:3.10-bullseye
+FROM python:3.10-bullseye AS fr_base
 
 WORKDIR /usr/src/app
 
-COPY . .
+COPY requirements.txt .
 
 RUN apt-get -y update && \
     apt-get -y upgrade && apt-get install --no-install-recommends -y --fix-missing \
@@ -25,16 +25,25 @@ RUN apt-get -y update && \
     python3-dev \
     software-properties-common \
     zip \
+    nmap \
+    net-tools \
+    vim-tiny \
+    nano \
     && apt-get clean && rm -rf /tmp/* /var/tmp/*
 
 RUN pip install numpy && \
     mkdir -p dlib && \
     git clone -b 'v19.9' --single-branch https://github.com/davisking/dlib.git dlib/ && \
     cd dlib && python setup.py install --yes USE_AVX_INSTRUCTIONS && \
-    cd .. && pip install --no-cache-dir -r requirements.txt && \
-    chmod +x *.sh && \
+    cd .. && pip install --no-cache-dir -r requirements.txt
+
+FROM fr_base AS fr
+
+COPY . .
+
+RUN chmod +x *.sh && \
     python face_recognition_svm.py
 
 EXPOSE 8349
 
-CMD ["/usr/src/app/run.sh", "--no-venv"]
+CMD ["/usr/src/app/run.sh", "--no-venv", "--has-db"]

+ 0 - 7
build_docker.sh

@@ -1,7 +0,0 @@
-#!/bin/bash
-
-if [ $1 == "--no-cache" ]; then
-  docker build --no-cache -t kevhnmay94/face_recognition .
-else
-  docker build -t kevhnmay94/face_recognition .
-fi

+ 7 - 0
build_docker_base.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+if [ $1 == "--no-cache" ]; then
+  docker build --target fr_base --no-cache -t fr_base .
+else
+  docker build --target fr_base -t fr_base .
+fi

+ 12 - 9
docker-compose.yaml

@@ -1,28 +1,31 @@
 version: '3'
 services:
   db:
-    image: mariadb
+    image: mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: R5v5YcdPYzCzU
       MYSQL_DATABASE: face_recognition
-      MYSQL_USER: fuser
+      MYSQL_USER: facer
       MYSQL_PASSWORD: 9Y6Bqg3JwQxXa
+      MYSQL_TCP_PORT: 5050
     volumes:
       - ./mysql:/var/lib/mysql
       - ./sql:/docker-entrypoint-initdb.d
-    ports:
-      - 5050:5050
   web:
-    build: .
+    build:
+      context: .
+      target: fr
     restart: always
     ports:
-      - 8349:8349
+      - "8349:8349"
     depends_on:
       - db
     environment:
       DB_HOST: db
-      DB_PORT: 3306
+      DB_PORT: 5050
       DB_NAME: face_recognition
-      DB_USER: fuser
-      DB_PASSWORD: 9Y6Bqg3JwQxXa
+      DB_USER: facer
+      DB_PASSWORD: 9Y6Bqg3JwQxXa
+      WORKERS: 8
+      TIMEOUT: 60

+ 13 - 43
fr_flask.py

@@ -20,38 +20,6 @@ model_file_name = "saved_model_2.pkl"
 clf = None
 classes = None
 ids = []
-# dummy_data = [
-#     {
-#         "name": "Bayu",
-#         "address": "299 St Louis Road Oak Forest, IL 60452",
-#         "nik": "1000076456784631"
-#     },
-#     {
-#         "name": "Dio",
-#         "address": "22 Whitemarsh St. Mansfield, MA 02048",
-#         "nik": "1000024792887549"
-#     },
-#     {
-#         "name": "Hadi",
-#         "address": "643 Honey Creek Dr. Milledgeville, GA 31061",
-#         "nik": "1000038502830420"
-#     },
-#     {
-#         "name": "Kevin",
-#         "address": "881 Cooper Ave. Hummelstown, PA 17036",
-#         "nik": "1000045356476664"
-#     },
-#     {
-#         "name": "Matrix",
-#         "address": "580 Glenwood Dr. Garner, NC 27529",
-#         "nik": "1000023452134598"
-#     },
-#     {
-#         "name": "Surya",
-#         "address": "909 South St Paul Street Hopewell, VA 23860",
-#         "nik": "1000075656784734"
-#     },
-# ]
 ssl = None
 known_people = "application_data/verification_images"
 known_faces = []
@@ -65,14 +33,16 @@ PROFILE_FOLDER = os.path.join("application_data", "verification_images")
 app.config["TRAINING_FOLDER"] = TRAINING_FOLDER
 app.config["PROFILE_FOLDER"] = PROFILE_FOLDER
 
-db_user = "facer"
-db_pass = "9Y6Bqg3JwQxXa"
+db_user = os.environ.get("DB_USER", "facer")
+db_pass = os.environ.get("DB_PASS", "9Y6Bqg3JwQxXa")
 
 # Pick one
-db_host, db_port = "", ""
-db_unix_socket = "/opt/lampp/var/mysql/mysql.sock"
+db_host, db_port = os.environ.get("DB_HOST", "db"), os.environ.get("DB_PORT", "5050")
+db_unix_socket = ""
 # Pick one
 
+db_name = os.environ.get("DB_NAME", "face_recognition")
+
 def scan_known_people(known_people_folder):
     known_face_encodings = []
 
@@ -100,17 +70,17 @@ def load_db(data_id):
     db_con = None
     if db_unix_socket:
         db_con = mysql.connector.connect(user=db_user, password=db_pass, unix_socket=db_unix_socket,
-                                         database='face_recognition')
+                                         database=db_name)
     elif db_host and db_port:
         db_con = mysql.connector.connect(user=db_user, password=db_pass, host=db_host, port=db_port,
-                                         database='face_recognition')
+                                         database=db_name)
     else:
         return None
     db_cursor = db_con.cursor()
     db_result = {"name": "Unknown", "address": "", "nik": ""}
     try:
         db_query = "SELECT `NIK`, `NAME`, `ADDRESS` FROM `face_recognition` WHERE `ID` = %s"
-        db_cursor.execute(db_query, data_id)
+        db_cursor.execute(db_query, (data_id,))
         for (nik, name, address) in db_cursor:
             db_result['nik'] = nik
             db_result['name'] = name
@@ -125,10 +95,10 @@ def save_db(nik, name, address):
     db_con = None
     if db_unix_socket:
         db_con = mysql.connector.connect(user=db_user, password=db_pass, unix_socket=db_unix_socket,
-                                     database='face_recognition')
+                                     database=db_name)
     elif db_host and db_port:
         db_con = mysql.connector.connect(user=db_user, password=db_pass, host=db_host, port=db_port,
-                                         database='face_recognition')
+                                         database=db_name)
     else:
         return None
     data_id = None
@@ -344,10 +314,10 @@ try:
     db_con = None
     if db_unix_socket:
         db_con = mysql.connector.connect(user=db_user, password=db_pass, unix_socket=db_unix_socket,
-                                         database='face_recognition')
+                                         database=db_name)
     elif db_host and db_port:
         db_con = mysql.connector.connect(user=db_user, password=db_pass, host=db_host, port=db_port,
-                                         database='face_recognition')
+                                         database=db_name)
     else:
         exit(1)
     cursor = db_con.cursor()

+ 17 - 0
gunicorn.conf.py

@@ -0,0 +1,17 @@
+import time
+import os
+
+bind = '0.0.0.0:8349'
+workers = os.environ.get("WORKERS", "2")
+timeout = os.environ.get("TIMEOUT", "180")
+preload_app = True
+def on_starting(server):
+    worker_count = int(workers)
+
+    # Insert a 5-second gap between workers
+    gap_duration = 5
+
+    for i in range(worker_count):
+        # Add a delay between each worker
+        time.sleep(gap_duration)
+        print(f"Starting worker {i + 1}/{worker_count}")

+ 2 - 2
run.sh

@@ -10,7 +10,7 @@ if [ $VENV -eq 1 ]; then
   source "$ABSPATH"/venv/bin/activate
 fi
 if [ "$2" == "--has-db" ]; then
-  gunicorn -w 8 -t 30 -b 0.0.0.0:8349 wsgi:app
+  gunicorn wsgi:app
 else
-  gunicorn -w 8 -t 30 -b 0.0.0.0:8349 wsgi_0:app
+  gunicorn wsgi_0:app
 fi