diff --git a/.github/workflows/dockerbuild.release.yml b/.github/workflows/dockerbuild.release.yml new file mode 100644 index 000000000..bb0bfdc6d --- /dev/null +++ b/.github/workflows/dockerbuild.release.yml @@ -0,0 +1,56 @@ +name: Docker Build Production + +on: + release: + types: [published] + +jobs: + build: + runs-on: ubuntu-latest + steps: + # + # Get Release Version + # + - uses: oprypin/find-latest-tag@v1 + with: + repository: hay-kot/mealie # The repository to scan. + releases-only: true # We know that all relevant tags have a GitHub release for them. + id: mealie_version # The step ID to refer to later. + # + # Checkout + # + - name: checkout code + uses: actions/checkout@v2 + # + # Setup QEMU + # + - name: Set up QEMU + id: qemu + uses: docker/setup-qemu-action@v1 + with: + image: tonistiigi/binfmt:latest + platforms: all + # + # Setup Buildx + # + - name: install buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + install: true + # + # Login to Docker Hub + # + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + # + # Build + # + - name: build the image + run: | + docker build --push \ + --tag hkotel/mealie:${{ steps.mealie_version.outputs.tag }} \ + --platform linux/amd64,linux/arm/v7,linux/arm64 . diff --git a/.vscode/settings.json b/.vscode/settings.json index be59f4b7e..b2cd9fb84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,6 @@ "i18n-ally.keystyle": "nested", "cSpell.words": [ "performant" - ] + ], + "search.mode": "reuseEditor" } diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 000000000..a24ecb85f --- /dev/null +++ b/Caddyfile @@ -0,0 +1,21 @@ +{ + auto_https off +} + +:80 { + @proxied path /api/* /docs /openapi.json + + root * /app/dist + encode gzip + uri strip_suffix / + + handle @proxied { + reverse_proxy http://127.0.0.1:9000 + } + + handle { + try_files {path}.html {path} / + file_server + } + +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index ad18c37d4..020e7e018 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN npm run build FROM python:3.9-alpine -RUN apk add --no-cache libxml2-dev libxslt-dev libxml2 +RUN apk add --no-cache libxml2-dev libxslt-dev libxml2 caddy ENV ENV prod EXPOSE 80 WORKDIR /app @@ -30,9 +30,12 @@ RUN apk add --update --no-cache --virtual .build-deps \ COPY ./mealie /app +COPY ./Caddyfile /app COPY --from=build-stage /app/dist /app/dist RUN rm -rf /app/test /app/.temp - VOLUME [ "/app/data/" ] -CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"] +RUN chmod +x /app/run.sh +CMD /app/run.sh + +# CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"] diff --git a/frontend/src/api/meta.js b/frontend/src/api/meta.js index d8205c5f5..d8ba5d734 100644 --- a/frontend/src/api/meta.js +++ b/frontend/src/api/meta.js @@ -5,6 +5,7 @@ const prefix = baseURL + "debug"; const debugURLs = { version: `${prefix}/version`, + lastRecipe: `${prefix}/last-recipe-json`, }; export default { @@ -12,4 +13,8 @@ export default { let response = await apiReq.get(debugURLs.version); return response.data; }, + async getLastJson() { + let response = await apiReq.get(debugURLs.lastRecipe); + return response.data; + }, }; diff --git a/frontend/src/components/Debug/LastRecipe.vue b/frontend/src/components/Debug/LastRecipe.vue new file mode 100644 index 000000000..caaad006e --- /dev/null +++ b/frontend/src/components/Debug/LastRecipe.vue @@ -0,0 +1,38 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/components/Debug/LogFile.vue b/frontend/src/components/Debug/LogFile.vue new file mode 100644 index 000000000..47f309496 --- /dev/null +++ b/frontend/src/components/Debug/LogFile.vue @@ -0,0 +1,37 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/pages/Debug.vue b/frontend/src/pages/Debug.vue new file mode 100644 index 000000000..14711b2f7 --- /dev/null +++ b/frontend/src/pages/Debug.vue @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/routes.js b/frontend/src/routes.js index e3790a4c0..5fbbde2a2 100644 --- a/frontend/src/routes.js +++ b/frontend/src/routes.js @@ -7,12 +7,14 @@ import SettingsPage from "./pages/SettingsPage"; import AllRecipesPage from "./pages/AllRecipesPage"; import CategoryPage from "./pages/CategoryPage"; import MeaplPlanPage from "./pages/MealPlanPage"; +import Debug from "./pages/Debug"; import MealPlanThisWeekPage from "./pages/MealPlanThisWeekPage"; import api from "@/api"; export const routes = [ { path: "/", component: HomePage }, { path: "/mealie", component: HomePage }, + { path: "/debug", component: Debug }, { path: "/search", component: SearchPage }, { path: "/recipes/all", component: AllRecipesPage }, { path: "/recipes/:category", component: CategoryPage }, diff --git a/frontend/vue.config.js b/frontend/vue.config.js index 958c61e8f..d24793322 100644 --- a/frontend/vue.config.js +++ b/frontend/vue.config.js @@ -1,6 +1,6 @@ module.exports = { transpileDependencies: ["vuetify"], - publicPath: process.env.NODE_ENV === "production" ? "/static/" : "/", + publicPath: process.env.NODE_ENV === "production" ? "/" : "/", outputDir: process.env.NODE_ENV === "production" ? "./dist" : "../mealie/web", devServer: { proxy: { @@ -12,10 +12,10 @@ module.exports = { }, pluginOptions: { i18n: { - locale: 'en', - fallbackLocale: 'en', - localeDir: 'locales', - enableInSFC: true - } - } + locale: "en", + fallbackLocale: "en", + localeDir: "locales", + enableInSFC: true, + }, + }, }; diff --git a/mealie/app.py b/mealie/app.py index b8781df5d..fd96e6b3d 100644 --- a/mealie/app.py +++ b/mealie/app.py @@ -1,16 +1,14 @@ import uvicorn from fastapi import FastAPI -from fastapi.staticfiles import StaticFiles # import utils.startup as startup -from app_config import APP_VERSION, PORT, PRODUCTION, WEB_PATH, docs_url, redoc_url +from app_config import APP_VERSION, PORT, WEB_PATH, docs_url, redoc_url from routes import ( backup_routes, debug_routes, meal_routes, migration_routes, setting_routes, - static_routes, theme_routes, ) from routes.recipe import ( @@ -31,10 +29,6 @@ app = FastAPI( ) -def mount_static_files(): - app.mount("/static", StaticFiles(directory=WEB_PATH, html=True)) - - def start_scheduler(): import services.scheduler.scheduled_jobs @@ -62,24 +56,7 @@ def api_routers(): app.include_router(debug_routes.router) -if PRODUCTION: - mount_static_files() - api_routers() - -# API 404 Catch all CALL AFTER ROUTERS -@app.get("/api/{full_path:path}", status_code=404, include_in_schema=False) -def invalid_api(): - return None - - -app.include_router(static_routes.router) - - -# Generate API Documentation -# if not PRODUCTION: -# generate_api_docs(app) - start_scheduler() init_settings() @@ -92,6 +69,7 @@ if __name__ == "__main__": port=PORT, reload=True, debug=True, + log_level="info", workers=1, forwarded_allow_ips="*", ) diff --git a/mealie/routes/debug_routes.py b/mealie/routes/debug_routes.py index 2c0d8f3b7..bf7829047 100644 --- a/mealie/routes/debug_routes.py +++ b/mealie/routes/debug_routes.py @@ -22,7 +22,7 @@ async def get_last_recipe_json(): return json.loads(f.read()) -@router.get("/log/{num}", response_class=HTMLResponse) +@router.get("/log/{num}") async def get_log(num: int): """ Doc Str """ with open(LOGGER_FILE, "rb") as f: @@ -53,4 +53,4 @@ def tail(f, lines=20): block_end_byte -= BLOCK_SIZE block_number -= 1 all_read_text = b"".join(reversed(blocks)) - return b"
".join(all_read_text.splitlines()[-total_lines_wanted:]) + return b"/n".join(all_read_text.splitlines()[-total_lines_wanted:]) diff --git a/mealie/routes/static_routes.py b/mealie/routes/static_routes.py deleted file mode 100644 index 52d2fa9fe..000000000 --- a/mealie/routes/static_routes.py +++ /dev/null @@ -1,24 +0,0 @@ -from pathlib import Path - -from fastapi import APIRouter, responses -from fastapi.responses import FileResponse - -CWD = Path(__file__).parent -WEB_PATH = CWD.parent.joinpath("dist") -BASE_HTML = WEB_PATH.joinpath("index.html") -router = APIRouter(include_in_schema=False) - - -@router.get("/favicon.ico") -def facivon(): - return responses.RedirectResponse(url="/mealie/favicon.ico") - - -@router.get("/") -async def root(): - return FileResponse(BASE_HTML) - - -@router.get("/{full_path:path}") -async def root_plus(full_path): - return FileResponse(BASE_HTML) diff --git a/mealie/run.sh b/mealie/run.sh new file mode 100644 index 000000000..1c72a05d6 --- /dev/null +++ b/mealie/run.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +## Migrations +# TODO + +## Web Server +caddy start --config ./Caddyfile + +## Start API +uvicorn app:app --host 0.0.0.0 --port 9000 \ No newline at end of file