Skip to content

Commit

Permalink
Merge pull request #11 from hotosm/feat/dockerize-frontend
Browse files Browse the repository at this point in the history
Dockerized Frontend with required changes to backend and docker stack
  • Loading branch information
nrjadkry authored Jun 27, 2024
2 parents 54ef903 + f3bd178 commit 865fb8e
Show file tree
Hide file tree
Showing 15 changed files with 986 additions and 1,105 deletions.
24 changes: 24 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# For Database and Backend
POSTGRES_USER=dtm
POSTGRES_DB=dtm_db
POSTGRES_PASSWORD=dtm
POSTGRES_HOST=db

# For MinIO and Backend
S3_BUCKET_NAME=dtm-bucket
S3_ACCESS_KEY=SAMPLEACCESSKEYFORMINIOROOT
S3_SECRET_KEY=SAMPLESECRETACCESSKEYFORMINIOROOT

GOOGLE_CLIENT_ID="xxxxxxxxx-xxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="GOOGLE_CLIENT_SECRET"
SECRET_KEY=SUPERSECRETKEY

EXTRA_CORS_ORIGINS=["http://localhost:3040"]

# For Frontend
SITE_NAME="DTM-Drone Tasking Manager"
BASE_URL=http://localhost:${BACKEND_WEB_APP_PORT:-8000}
API_URL_V1=http://localhost:${BACKEND_WEB_APP_PORT:-8000}/api

# use development for frontend as dev else live
DOCKER_TARGET=development
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ chart/charts

#Docker
DockerData/

#Backend Template
src/backend/templates/
25 changes: 19 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,39 @@ volumes:
dtm_db_data:

services:
web:
backend:
build:
context: .
dockerfile: src/backend/Dockerfile
restart: always
ports:
- 8002:8000
- ${BACKEND_WEB_APP_PORT:-8000}:8000
volumes:
- ./src/backend:/project/src/backend
env_file: .env
networks:
- dtm-network
container_name: api

frontend:
build:
context: .
dockerfile: src/frontend/Dockerfile
target: ${DOCKER_TARGET:-development}
ports:
- ${FRONTEND_WEB_APP_PORT:-3040}:3040
env_file: .env
networks:
- dtm-network
volumes:
- ./src/frontend:/app
- /var/run/docker.sock:/var/run/docker.sock
- ./src/frontend/docker-entrypoint.sh:/docker-entrypoint.sh

db:
image: postgis/postgis:14-3.4-alpine
restart: always
volumes:
- dtm_db_data:/var/lib/postgresql/data/
- ./DockerData/dtm_db_data:/var/lib/postgresql/data/
env_file: .env
networks:
- dtm-network
Expand All @@ -44,7 +58,6 @@ services:
MINIO_ROOT_USER: ${S3_ACCESS_KEY:-dtm_user}
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY:-somelongpassword}
MINIO_CONSOLE_ADDRESS: ":9090"
MINIO_ENDPOINT: ${S3_ENDPOINT:-http://s3:9000}
ports:
- 9000:9000
- 9090:9090
Expand All @@ -70,7 +83,7 @@ services:
volumes:
- ./src/backend:/project/src/backend
depends_on:
- web
- backend
- db
env_file:
- .env
Expand Down
18 changes: 0 additions & 18 deletions env_sample.txt

This file was deleted.

4 changes: 2 additions & 2 deletions src/backend/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def assemble_cors_origins(
default_origins += val
return default_origins

API_PREFIX: str = "/"
API_PREFIX: str = "/api"
SECRET_KEY: str = secrets.token_urlsafe(32)

POSTGRES_HOST: Optional[str] = "db"
Expand Down Expand Up @@ -83,7 +83,7 @@ def assemble_db_connection(cls, v: Optional[str], info: ValidationInfo) -> Any:

GOOGLE_CLIENT_ID: str
GOOGLE_CLIENT_SECRET: str
GOOGLE_LOGIN_REDIRECT_URI: str = "http://localhost:8002"
GOOGLE_LOGIN_REDIRECT_URI: str = "http://localhost:8000"


@lru_cache
Expand Down
44 changes: 39 additions & 5 deletions src/backend/app/main.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import os
import logging
import sys
from fastapi import FastAPI
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
from app.projects import project_routes
from app.waypoints import waypoint_routes
from fastapi.responses import RedirectResponse
from fastapi.responses import RedirectResponse, JSONResponse
from app.users import oauth_routes
from app.users import user_routes
from loguru import logger as log
from fastapi.templating import Jinja2Templates
from fastapi.responses import RedirectResponse


root = os.path.dirname(os.path.abspath(__file__))
templates = Jinja2Templates(directory=f'templates')


class InterceptHandler(logging.Handler):
Expand Down Expand Up @@ -68,6 +75,9 @@ def get_application() -> FastAPI:
"url": "https://raw.githubusercontent.com/hotosm/fmtm/main/LICENSE.md",
},
debug=settings.DEBUG,
docs_url="/api/docs",
openapi_url="/api/openapi.json",
redoc_url="/api/redoc"
)

# Set custom logger
Expand All @@ -94,6 +104,30 @@ def get_application() -> FastAPI:


@api.get("/")
async def home():
"""Redirect home to docs."""
return RedirectResponse("/docs")
async def home(request: Request):
try:
"""Return Frontend HTML"""
return templates.TemplateResponse(name="index.html", context={"request": request})
except:
"""Fall back if tempalate missing. Redirect home to docs."""
return RedirectResponse(f"{settings.API_PREFIX}/docs")


known_browsers = ["Mozilla", "Chrome", "Safari", "Opera", "Edge", "Firefox"]

@api.exception_handler(404)
async def custom_404_handler(request: Request, _):
"""Return Frontend HTML or throw 404 Response on 404 requests."""
try:
query_params = dict(request.query_params)
user_agent = request.headers.get("User-Agent", "")
format = query_params.get("format")
is_browser = any(browser in user_agent for browser in known_browsers)
if format == "json" or not is_browser:
return JSONResponse(status_code=404, content={"detail": "Not found"})
return templates.TemplateResponse(name="index.html", context={"request": request})

except:
"""Fall back if tempalate missing. Redirect home to docs."""
return JSONResponse(status_code=404, content={"detail": "Not found"})

3 changes: 2 additions & 1 deletion src/backend/app/projects/project_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
from app.s3 import s3_client
from app.config import settings
from app.db import db_models
from app.config import settings


router = APIRouter(
prefix="/projects",
prefix=f"{settings.API_PREFIX}/projects",
responses={404: {"description": "Not found"}},
)

Expand Down
4 changes: 2 additions & 2 deletions src/backend/app/users/user_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
from app.config import settings
from app.users import user_crud
from app.db import database

from app.config import settings

router = APIRouter(
prefix="/users",
prefix=f"{settings.API_PREFIX}/users",
tags=["users"],
responses={404: {"description": "Not found"}},
)
Expand Down
3 changes: 2 additions & 1 deletion src/backend/app/waypoints/waypoint_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
haversine_distance,
calculate_distance_between_2_lines,
)
from app.config import settings

router = APIRouter(
prefix="/waypoint",
prefix=f"{settings.API_PREFIX}/waypoint",
tags=["waypoint"],
responses={404: {"description": "Not found"}},
)
Expand Down
Loading

0 comments on commit 865fb8e

Please sign in to comment.