浏览代码

Merge remote-tracking branch 'origin/master' into front-dev

SyuanYu 2 年之前
父节点
当前提交
885f2c768d

+ 8 - 27
.env

@@ -1,4 +1,4 @@
-DOMAIN=localhost
+DOMAIN=cloud.choozmo.com:8080
 SERVER_ADDRESS=http://localhost
 SERVER_ADDRESS=http://localhost
 # DOMAIN=local.dockertoolbox.tiangolo.com
 # DOMAIN=local.dockertoolbox.tiangolo.com
 # DOMAIN=localhost.tiangolo.com
 # DOMAIN=localhost.tiangolo.com
@@ -11,39 +11,20 @@ TRAEFIK_TAG=ai-anchor.com
 TRAEFIK_PUBLIC_TAG=traefik-public
 TRAEFIK_PUBLIC_TAG=traefik-public
 
 
 DOCKER_IMAGE_BACKEND=backend
 DOCKER_IMAGE_BACKEND=backend
-DOCKER_IMAGE_CELERYWORKER=celeryworker
+DOCKER_IMAGE_CELERYWORKER=gpuceleryworker
 DOCKER_IMAGE_FRONTEND=frontend
 DOCKER_IMAGE_FRONTEND=frontend
 
 
 # Backend
 # Backend
-BACKEND_CORS_ORIGINS=["https://cloud.choozmo:8080", 
-                      "http://cloud.choozmo.com:8080", 
-                      "https://cloud.choozmo.com", 
-                      "http://cloud.choozmo.com", 
-                      "http://local.ai-anchor.com:5173", 
-                      "http://local.ai-anchor.com:8080", 
-                      "http://localhost", 
-                      "http://localhost:4200", 
-                      "http://localhost:3000", 
-                      "http://localhost:5173", 
-                      "http://localhost:8080", 
-                      "https://localhost", 
-                      "https://localhost:4200", 
-                      "https://localhost:3000", 
-                      "https://localhost:8080", 
-                      "http://dev.ai-anchor.com:3000",
-                      "http://dev.ai-anchor.com:5173", 
-                      "http://dev.ai-anchor.com:8080", 
-                      "https://stag.ai-anchor.com", 
-                      "https://ai-anchor.com"]
+BACKEND_CORS_ORIGINS=["https://cloud.choozmo:8080", "http://cloud.choozmo.com:8080", "https://cloud.choozmo.com", "http://cloud.choozmo.com","http://172.105.219.42", "http://local.ai-anchor.com:5173", "http://local.ai-anchor.com:8080", "http://localhost", "http://localhost:4200", "http://localhost:3000", "http://localhost:5173", "http://localhost:8080", "https://localhost", "https://localhost:4200", "https://localhost:3000", "https://localhost:8080", "http://dev.ai-anchor.com:3000", "http://dev.ai-anchor.com:5173", "http://dev.ai-anchor.com:8080", "https://stag.ai-anchor.com", "https://ai-anchor.com", "http://local.dockertoolbox.tiangolo.com", "http://localhost.tiangolo.com"]
 PROJECT_NAME=AI anchor
 PROJECT_NAME=AI anchor
 SECRET_KEY=1df1f2180c7b2550e76a8ccf5e67a76e5321d8c2d3fee4a725f8b80baf9a0c91
 SECRET_KEY=1df1f2180c7b2550e76a8ccf5e67a76e5321d8c2d3fee4a725f8b80baf9a0c91
 FIRST_SUPERUSER=admin@ai-anchor.com
 FIRST_SUPERUSER=admin@ai-anchor.com
 FIRST_SUPERUSER_PASSWORD=password
 FIRST_SUPERUSER_PASSWORD=password
 SMTP_TLS=True
 SMTP_TLS=True
 SMTP_PORT=587
 SMTP_PORT=587
-SMTP_HOST=
-SMTP_USER=
-SMTP_PASSWORD=
+SMTP_HOST=smtp.gmail.com
+SMTP_USER=verify@choozmo.com
+SMTP_PASSWORD=hlmaxzjnvpeaulhw
 EMAILS_FROM_EMAIL=info@ai-anchor.com
 EMAILS_FROM_EMAIL=info@ai-anchor.com
 
 
 USERS_OPEN_REGISTRATION=True
 USERS_OPEN_REGISTRATION=True
@@ -68,8 +49,8 @@ PGADMIN_DEFAULT_EMAIL=admin@ai-anchor.com
 PGADMIN_DEFAULT_PASSWORD=password
 PGADMIN_DEFAULT_PASSWORD=password
 
 
 # Initial data
 # Initial data
-MEMBERSHIP_TYPES=["normal", "infinite"]
-PROGRESS_TYPES=["waiting", "processing", "completed"]
+MEMBERSHIP_STATUS=["normal", "infinite"]
+PROGRESS_STATE=["waiting", "processing", "completed"]
 
 
 # celery
 # celery
 CELERY_ZIP_STORAGE=celery_storage/zips
 CELERY_ZIP_STORAGE=celery_storage/zips

+ 4 - 0
backend/app/app/api/api_v1/endpoints/videos.py

@@ -14,6 +14,8 @@ from app.core.celery_app import celery_app
 from app.core.config import settings
 from app.core.config import settings
 from pathlib import Path
 from pathlib import Path
 
 
+from app.core.celery_app import celery_app
+
 ZIP_STORAGE = Path("/app").joinpath(settings.BACKEND_ZIP_STORAGE)
 ZIP_STORAGE = Path("/app").joinpath(settings.BACKEND_ZIP_STORAGE)
 VIDEO_STORAGE = Path("/app").joinpath(settings.BACKEND_VIDEO_STORAGE)
 VIDEO_STORAGE = Path("/app").joinpath(settings.BACKEND_VIDEO_STORAGE)
 
 
@@ -64,6 +66,8 @@ def upload_plot(
         return {"error": str(e)}
         return {"error": str(e)}
     finally:
     finally:
         upload_file.file.close()
         upload_file.file.close()
+
+    celery_app.send_task("app.worker.make_video", args=[video.id, video.stored_file_name, current_user.id])
     return video
     return video
 
 
 @router.get("/{id}")
 @router.get("/{id}")

+ 2 - 3
backend/app/app/core/celery_app.py

@@ -1,8 +1,7 @@
 from celery import Celery
 from celery import Celery
 
 
-celery_app = Celery("worker", broker="amqp://guest@queue//")
+celery_app = Celery("worker", broker="redis://172.104.93.163:16379/0")
 
 
 
 
 
 
-celery_app.conf.task_routes = {"app.worker.test_celery": "main-queue", 
-                                  "app.worker.make_video": "main-queue"}
+celery_app.conf.task_routes = {"app.worker.make_video": "main-queue"}

+ 16 - 35
backend/app/app/core/config.py

@@ -9,13 +9,13 @@ class Settings(BaseSettings):
     SECRET_KEY: str = secrets.token_urlsafe(32)
     SECRET_KEY: str = secrets.token_urlsafe(32)
     # 60 minutes * 24 hours * 8 days = 8 days
     # 60 minutes * 24 hours * 8 days = 8 days
     ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8
     ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8
-    SERVER_NAME: str 
-    SERVER_HOST: AnyHttpUrl 
+    SERVER_NAME: str  = "cloud.choozmo.com:8080"
+    SERVER_HOST: AnyHttpUrl  = "http://cloud.choozmo.com:8080"
     # BACKEND_CORS_ORIGINS is a JSON-formatted list of origins
     # BACKEND_CORS_ORIGINS is a JSON-formatted list of origins
     # e.g: '["http://localhost", "http://localhost:4200", "http://localhost:3000", \
     # e.g: '["http://localhost", "http://localhost:4200", "http://localhost:3000", \
     # "http://localhost:8080", "http://local.dockertoolbox.tiangolo.com"]'
     # "http://localhost:8080", "http://local.dockertoolbox.tiangolo.com"]'
-    BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = ["*"]
-    '''
+    BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = ["https://cloud.choozmo:8080", "http://cloud.choozmo.com:8080", "https://cloud.choozmo.com", "http://cloud.choozmo.com","http://172.105.219.42", "http://local.ai-anchor.com:5173", "http://local.ai-anchor.com:8080", "http://localhost", "http://localhost:4200", "http://localhost:3000", "http://localhost:5173", "http://localhost:8080", "https://localhost", "https://localhost:4200", "https://localhost:3000", "https://localhost:8080", "http://dev.ai-anchor.com:3000", "http://dev.ai-anchor.com:5173", "http://dev.ai-anchor.com:8080"]
+    
     @validator("BACKEND_CORS_ORIGINS", pre=True)
     @validator("BACKEND_CORS_ORIGINS", pre=True)
     def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
     def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
         if isinstance(v, str) and not v.startswith("["):
         if isinstance(v, str) and not v.startswith("["):
@@ -23,21 +23,15 @@ class Settings(BaseSettings):
         elif isinstance(v, (list, str)):
         elif isinstance(v, (list, str)):
             return v
             return v
         raise ValueError(v)
         raise ValueError(v)
-    '''
+    
     PROJECT_NAME: str = "ai-anchor"
     PROJECT_NAME: str = "ai-anchor"
-    SENTRY_DSN: Optional[HttpUrl] = None
+    SENTRY_DSN: Optional[HttpUrl] = "http://SENTRY_DSN"
 
 
     @validator("SENTRY_DSN", pre=True)
     @validator("SENTRY_DSN", pre=True)
     def sentry_dsn_can_be_blank(cls, v: str) -> Optional[str]:
     def sentry_dsn_can_be_blank(cls, v: str) -> Optional[str]:
         if len(v) == 0:
         if len(v) == 0:
             return None
             return None
-        return v
-
-    POSTGRES_SERVER: str
-    POSTGRES_USER: str
-    POSTGRES_PASSWORD: str
-    POSTGRES_DB: str
-    SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None
+        return 
 
 
     '''
     '''
     @validator("SQLALCHEMY_DATABASE_URI", pre=True)
     @validator("SQLALCHEMY_DATABASE_URI", pre=True)
@@ -52,19 +46,6 @@ class Settings(BaseSettings):
             path=f"/{values.get('POSTGRES_DB') or ''}",
             path=f"/{values.get('POSTGRES_DB') or ''}",
         )
         )
     '''
     '''
-    '''
-    @validator("SQLALCHEMY_DATABASE_URI", pre=True)
-    def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
-        if isinstance(v, str):
-            return v
-        return PostgresDsn.build(
-            scheme="mysql",
-            user="choozmo",
-            password="pAssw0rd",
-            host="db.ptt.cx:3306",
-            path=f"/ai-anchor",
-        )
-    '''
 
 
     SMTP_TLS: bool = True
     SMTP_TLS: bool = True
     SMTP_PORT: Optional[int] = None
     SMTP_PORT: Optional[int] = None
@@ -93,20 +74,20 @@ class Settings(BaseSettings):
         )
         )
 
 
     EMAIL_TEST_USER: EmailStr = "test@example.com"  # type: ignore
     EMAIL_TEST_USER: EmailStr = "test@example.com"  # type: ignore
-    FIRST_SUPERUSER: EmailStr
-    FIRST_SUPERUSER_PASSWORD: str
+    FIRST_SUPERUSER: EmailStr = "admin@ai-anchor.com"
+    FIRST_SUPERUSER_PASSWORD: str = "password"
     USERS_OPEN_REGISTRATION: bool = False
     USERS_OPEN_REGISTRATION: bool = False
 
 
-    MEMBERSHIP_TYPES: List[str]
-    PROGRESS_TYPES: List[str]
+    MEMBERSHIP_STATUS : List[str] = ['normal', 'infinite']
+    PROGRESS_STATE: List[str] = ['waiting', 'processing', 'completed']
 
 
-    SERVER_ADDRESS: AnyHttpUrl
+    SERVER_ADDRESS: AnyHttpUrl = "http://172.105.219.42:8080"
 
 
-    CELERY_ZIP_STORAGE: str
-    CELERY_VIDEO_STORAGE: str
+    CELERY_ZIP_STORAGE: str = "/celery_storage/zips"
+    CELERY_VIDEO_STORAGE: str = "/celery_storage/videos"
 
 
-    BACKEND_ZIP_STORAGE: str
-    BACKEND_VIDEO_STORAGE: str
+    BACKEND_ZIP_STORAGE: str = "/backend_storage/zips"
+    BACKEND_VIDEO_STORAGE: str = "/backend_storage/videos"
 
 
     class Config:
     class Config:
         case_sensitive = True
         case_sensitive = True

+ 8 - 19
backend/app/app/db/init_db.py

@@ -26,16 +26,16 @@ def init_db(db: Session) -> None:
     engine = create_engine(f'mysql://{user}:{password}@{host}/{db_name}', pool_pre_ping=True)
     engine = create_engine(f'mysql://{user}:{password}@{host}/{db_name}', pool_pre_ping=True)
     base.Base.metadata.create_all(bind=engine)
     base.Base.metadata.create_all(bind=engine)
 
 
-    if settings.MEMBERSHIP_TYPES:
-      for TYPE in settings.MEMBERSHIP_TYPES:
-          if not db.query(Membership).filter(Membership.status == TYPE).first():
-                db.add(Membership(status=TYPE))
+    if settings.MEMBERSHIP_STATUS:
+      for STATUS in settings.MEMBERSHIP_STATUS:
+          if not db.query(Membership).filter(Membership.status == STATUS).first():
+                db.add(Membership(status=STATUS))
       db.commit()
       db.commit()
 
 
-    if settings.PROGRESS_TYPES:
-        for TYPE in settings.PROGRESS_TYPES:
-            if not db.query(Progress).filter(Progress.state == TYPE).first():
-                db.add(Progress(state=TYPE))
+    if settings.PROGRESS_STATE:
+        for STATE in settings.PROGRESS_STATE:
+            if not db.query(Progress).filter(Progress.state == STATE).first():
+                db.add(Progress(state=STATE))
         db.commit()
         db.commit()
     
     
     user = crud.user.get_by_email(db, email=settings.FIRST_SUPERUSER)
     user = crud.user.get_by_email(db, email=settings.FIRST_SUPERUSER)
@@ -47,14 +47,3 @@ def init_db(db: Session) -> None:
         )
         )
         user = crud.user.create(db, obj_in=user_in)  # noqa: F841
         user = crud.user.create(db, obj_in=user_in)  # noqa: F841
     
     
-    if settings.MEMBERSHIP_TYPES:
-        for TYPE in settings.MEMBERSHIP_TYPES:
-            if not db.query(Membership).filter(Membership.status == TYPE).first():
-                  db.add(Membership(status=TYPE))
-        db.commit()
-
-    if settings.PROGRESS_TYPES:
-        for TYPE in settings.PROGRESS_TYPES:
-            if not db.query(Progress).filter(Progress.state == TYPE).first():
-                db.add(Progress(state=TYPE))
-        db.commit()

+ 1 - 1
backend/app/app/main.py

@@ -12,7 +12,7 @@ app = FastAPI(
 if settings.BACKEND_CORS_ORIGINS:
 if settings.BACKEND_CORS_ORIGINS:
     app.add_middleware(
     app.add_middleware(
         CORSMiddleware,
         CORSMiddleware,
-        allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
+        allow_origins=["*"],#str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
         allow_credentials=True,
         allow_credentials=True,
         allow_methods=["*"],
         allow_methods=["*"],
         allow_headers=["*"],
         allow_headers=["*"],

+ 10 - 37
backend/app/app/worker.py

@@ -1,61 +1,34 @@
 from raven import Client
 from raven import Client
-
+import os
 from app.core.celery_app import celery_app
 from app.core.celery_app import celery_app
 from app.core.config import settings
 from app.core.config import settings
 import requests
 import requests
 from pathlib import Path
 from pathlib import Path
 from urllib.parse import urlparse, urljoin
 from urllib.parse import urlparse, urljoin
 
 
-client_sentry = Client(settings.SENTRY_DSN)
-
-download_to_local_url = urljoin(settings.SERVER_ADDRESS, settings.API_V1_STR, "/videos/worker")
-upload_to_server_url = urljoin(settings.SERVER_ADDRESS, settings.API_V1_STR, "/videos/worker")
+#client_sentry = Client(settings.SENTRY_DSN)
 
 
-ZIP_STORAGE = Path("/app").joinpath(settings.CELERY_ZIP_STORAGE)
-VIDEO_STORAGE = Path("/app").joinpath(settings.CELERY_VIDEO_STORAGE)
+download_to_local_url = urljoin(settings.SERVER_HOST, settings.API_V1_STR+"/videos/worker")
+upload_to_server_url = urljoin(settings.SERVER_HOST, settings.API_V1_STR+"/videos/worker")
 
 
+ZIP_STORAGE = Path(settings.CELERY_ZIP_STORAGE) 
+VIDEO_STORAGE = Path(settings.CELERY_VIDEO_STORAGE)
 
 
-@celery_app.task(acks_late=True)
-def test_celery(word: str) -> str:
-    return f"test task return {word}"
-
-@celery_app.task(acks_late=True)
-def download_to_local(id:int, file_name:str) -> str:
-
-    zip_file = Path(file_name+"/.zip")
-    r = requests.get(download_to_local_url, stream=True)
-
-    with open(str(VIDEO_STORAGE/zip_file), 'wb') as f:
-        r.raise_for_status()
-        for chunk in r.iter_content(chunk_size=1024):
-            f.write(chunk)
-    return "complete"
 
 
 
 
 @celery_app.task(acks_late=True)
 @celery_app.task(acks_late=True)
-def make_video(id:int, file_name) -> str:
+def make_video(video_id, zip_filename, user_id) -> str:
+    #video_id, zip_filename, user_id = args
     # download 
     # download 
-    zip_file = Path(file_name+"/.zip")
     r = requests.get(download_to_local_url, stream=True)
     r = requests.get(download_to_local_url, stream=True)
-
-    with open(str(VIDEO_STORAGE/zip_file), 'wb') as f:
+    with open(str(VIDEO_STORAGE/zip_filename), 'wb') as f:
         r.raise_for_status()
         r.raise_for_status()
         for chunk in r.iter_content(chunk_size=1024):
         for chunk in r.iter_content(chunk_size=1024):
             f.write(chunk)
             f.write(chunk)
-
     # make video
     # make video
 
 
 
 
-    video_file = Path(file_name+".mp4")
-    r = requests.post(urljoin(upload_to_server_url,str(id)))
-
-
+    
     return "complete"
     return "complete"
 
 
 
 
-@celery_app.task(acks_late=True)
-def upload_to_server(id:int, file_name:str) -> str:
-
-    video_file = Path(file_name+".mp4")
-    r = requests.post(urljoin(upload_to_server_url,str(id)))
-    return "complete"

+ 1 - 0
backend/app/pyproject.toml

@@ -14,6 +14,7 @@ python-multipart = "^0.0.5"
 email-validator = "^1.0.5"
 email-validator = "^1.0.5"
 requests = "^2.23.0"
 requests = "^2.23.0"
 celery = "^5.2.7"
 celery = "^5.2.7"
+redis = "^4.5.0"
 passlib = {extras = ["bcrypt"], version = "^1.7.2"}
 passlib = {extras = ["bcrypt"], version = "^1.7.2"}
 tenacity = "^8.0.0"
 tenacity = "^8.0.0"
 pydantic = "^1.10.4"
 pydantic = "^1.10.4"

+ 22 - 7
cloud-docker-compose.override.yml

@@ -4,7 +4,6 @@ services:
   proxy:
   proxy:
     ports:
     ports:
       - "8080:80"
       - "8080:80"
-      - "8090:8080"
     command:
     command:
       # Enable Docker in Traefik, so that it reads labels from Docker services
       # Enable Docker in Traefik, so that it reads labels from Docker services
       - --providers.docker
       - --providers.docker
@@ -27,12 +26,28 @@ services:
       - traefik.enable=true
       - traefik.enable=true
       - traefik.http.routers.${STACK_NAME?Variable not set}-traefik-public-http.rule=Host(`${DOMAIN?Variable not set}`)
       - traefik.http.routers.${STACK_NAME?Variable not set}-traefik-public-http.rule=Host(`${DOMAIN?Variable not set}`)
       - traefik.http.services.${STACK_NAME?Variable not set}-traefik-public.loadbalancer.server.port=80
       - traefik.http.services.${STACK_NAME?Variable not set}-traefik-public.loadbalancer.server.port=80
-
-
-
-
-
-
+  
+  backend:
+    volumes:
+      - ./backend/app:/app
+      - /${BACKEND_ZIP_STORAGE}:/app/${BACKEND_ZIP_STORAGE}
+      - /${BACKEND_VIDEO_STORAGE}:/app/${BACKEND_VIDEO_STORAGE}
+    environment:
+      - SERVER_HOST=http://${DOMAIN?Variable not set}
+    build:
+      context: ./backend
+      dockerfile: backend.dockerfile
+      args:
+        INSTALL_DEV: ${INSTALL_DEV-true}
+        INSTALL_JUPYTER: ${INSTALL_JUPYTER-false}
+    # command: bash -c "while true; do sleep 1; done"  # Infinite loop to keep container live doing nothing
+    command: /start-reload.sh
+    labels:
+      - traefik.enable=true
+      - traefik.constraint-label-stack=${TRAEFIK_TAG?Variable not set}
+      - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=PathPrefix(`/api`) || PathPrefix(`/docs`) || PathPrefix(`/redoc`)
+      - traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=80
+  
   frontend:
   frontend:
     build:
     build:
       context: ./frontend
       context: ./frontend

+ 21 - 1
cloud-docker-compose.yml

@@ -67,7 +67,27 @@ services:
         # Middleware to redirect www, and redirect HTTP to HTTPS
         # Middleware to redirect www, and redirect HTTP to HTTPS
         # to disable www redirection remove the section: ${STACK_NAME?Variable not set}-www-redirect,
         # to disable www redirection remove the section: ${STACK_NAME?Variable not set}-www-redirect,
         - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-http.middlewares=${STACK_NAME?Variable not set}-www-redirect,${STACK_NAME?Variable not set}-https-redirect
         - traefik.http.routers.${STACK_NAME?Variable not set}-proxy-http.middlewares=${STACK_NAME?Variable not set}-www-redirect,${STACK_NAME?Variable not set}-https-redirect
-
+  
+  backend:
+    image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
+    env_file:
+      - .env
+    environment:
+      - SERVER_NAME=${DOMAIN?Variable not set}
+      - SERVER_HOST=https://${DOMAIN?Variable not set}
+      # Allow explicit env var override for tests
+      - SMTP_HOST=${SMTP_HOST}
+    build:
+      context: ./backend
+      dockerfile: backend.dockerfile
+      args:
+        INSTALL_DEV: ${INSTALL_DEV-false}
+    deploy:
+      labels:
+        - traefik.enable=true
+        - traefik.constraint-label-stack=${TRAEFIK_TAG?Variable not set}
+        - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=PathPrefix(`/api`) || PathPrefix(`/docs`) || PathPrefix(`/redoc`)
+        - traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=80
   
   
   frontend:
   frontend:
     image: '${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}'
     image: '${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}'

+ 2 - 2
frontend/.env

@@ -1,9 +1,9 @@
-VITE_APP_DOMAIN_DEV=172.104.93.163:10000
+VITE_APP_DOMAIN_DEV=cloud.choozmo.com:8080
 # VUE_APP_DOMAIN_DEV=local.dockertoolbox.tiangolo.com
 # VUE_APP_DOMAIN_DEV=local.dockertoolbox.tiangolo.com
 # VUE_APP_DOMAIN_DEV=localhost.tiangolo.com
 # VUE_APP_DOMAIN_DEV=localhost.tiangolo.com
 # VUE_APP_DOMAIN_DEV=dev.ai-anchor.com
 # VUE_APP_DOMAIN_DEV=dev.ai-anchor.com
 VITE_APP_DOMAIN_STAG=stag.ai-anchor.com
 VITE_APP_DOMAIN_STAG=stag.ai-anchor.com
-VITE_APP_DOMAIN_PROD=ai-anchor.com
+VITE_APP_DOMAIN_PROD=cloud.choozmo.com
 VITE_APP_NAME=AI anchor
 VITE_APP_NAME=AI anchor
 VITE_APP_ENV=development
 VITE_APP_ENV=development
 # VUE_APP_ENV=staging
 # VUE_APP_ENV=staging