Optimize Docker (#575)
* reduce docker dev size * reduce docker prod size * fix lint * add gunicorn * fix bandit reported issues * add docs external link icon * add env vars to docs * add permission to docker * merge to one backend Dockerfile * fix codefactor issues * add docs for puid/pgid * add docker healthcheck
This commit is contained in:
parent
6320ba7ec5
commit
999d0d4322
34 changed files with 465 additions and 193 deletions
|
@ -1,3 +1,27 @@
|
|||
.git
|
||||
.github
|
||||
.dockerignore
|
||||
.gitignore
|
||||
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
htmlcov/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.pytest_cache/
|
||||
.venv
|
||||
venv
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
|
||||
*/node_modules
|
||||
*/dist
|
||||
*/data/db
|
||||
|
|
149
Dockerfile
149
Dockerfile
|
@ -1,59 +1,140 @@
|
|||
# build
|
||||
FROM node:lts-alpine as build-stage
|
||||
###############################################
|
||||
# Frontend Builder Image
|
||||
###############################################
|
||||
FROM node:lts-alpine as frontend-build
|
||||
WORKDIR /app
|
||||
COPY ./frontend/package*.json ./
|
||||
RUN npm install
|
||||
COPY ./frontend/ .
|
||||
RUN npm run build
|
||||
|
||||
###############################################
|
||||
# Base Image
|
||||
###############################################
|
||||
FROM python:3.9-slim as python-base
|
||||
|
||||
FROM python:3.9-slim-buster
|
||||
ENV MEALIE_HOME="/app"
|
||||
|
||||
ENV PRODUCTION true
|
||||
ENV POETRY_VERSION 1.1.6
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
||||
PIP_DEFAULT_TIMEOUT=100 \
|
||||
POETRY_HOME="/opt/poetry" \
|
||||
POETRY_VIRTUALENVS_IN_PROJECT=true \
|
||||
POETRY_NO_INTERACTION=1 \
|
||||
PYSETUP_PATH="/opt/pysetup" \
|
||||
VENV_PATH="/opt/pysetup/.venv"
|
||||
|
||||
# prepend poetry and venv to path
|
||||
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc g++ \
|
||||
# create user account
|
||||
RUN useradd -u 911 -U -d $MEALIE_HOME -s /bin/bash abc \
|
||||
&& usermod -G users abc \
|
||||
&& mkdir $MEALIE_HOME
|
||||
|
||||
###############################################
|
||||
# Builder Image
|
||||
###############################################
|
||||
FROM python-base as builder-base
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
curl \
|
||||
gnupg gnupg2 gnupg1 \
|
||||
apt-transport-https \
|
||||
debian-archive-keyring \
|
||||
debian-keyring \
|
||||
build-essential \
|
||||
libpq-dev \
|
||||
libwebp-dev \
|
||||
gnupg gnupg2 gnupg1 \
|
||||
debian-keyring \
|
||||
debian-archive-keyring \
|
||||
apt-transport-https \
|
||||
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | apt-key add - \
|
||||
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee -a /etc/apt/sources.list.d/caddy-stable.list \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
caddy \
|
||||
&& apt autoremove \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& apt-get remove -y curl apt-transport-https debian-keyring g++ gnupg gnupg2 gnupg1
|
||||
&& pip install -U --no-cache-dir pip
|
||||
|
||||
# install poetry - respects $POETRY_VERSION & $POETRY_HOME
|
||||
ENV POETRY_VERSION=1.1.6
|
||||
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -
|
||||
|
||||
RUN pip install --no-cache-dir "poetry==$POETRY_VERSION"
|
||||
# copy project requirement files here to ensure they will be cached.
|
||||
WORKDIR $PYSETUP_PATH
|
||||
COPY ./poetry.lock ./pyproject.toml ./
|
||||
|
||||
# project dependencies
|
||||
WORKDIR /app
|
||||
COPY pyproject.toml poetry.lock /app/
|
||||
RUN poetry config virtualenvs.create false
|
||||
RUN poetry install -E pgsql --no-dev --no-interaction --no-ansi
|
||||
# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
|
||||
RUN poetry install -E pgsql --no-dev
|
||||
|
||||
COPY ./mealie /app/mealie
|
||||
RUN poetry config virtualenvs.create false \
|
||||
&& poetry install -E pgsql --no-dev
|
||||
###############################################
|
||||
# Development Image
|
||||
###############################################
|
||||
FROM python-base as development
|
||||
ENV PRODUCTION=false
|
||||
|
||||
# copying poetry and venv into image
|
||||
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
|
||||
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
|
||||
|
||||
# copy backend
|
||||
COPY ./mealie $MEALIE_HOME/mealie
|
||||
COPY ./poetry.lock ./pyproject.toml $MEALIE_HOME/
|
||||
|
||||
#! Future
|
||||
# COPY ./alembic /app
|
||||
# COPY alembic.ini /app
|
||||
COPY ./Caddyfile /app
|
||||
COPY ./dev/data/templates /app/data/templates
|
||||
# COPY ./alembic ./alembic.ini $MEALIE_HOME/
|
||||
|
||||
# frontend build
|
||||
COPY --from=build-stage /app/dist /app/dist
|
||||
# venv already has runtime deps installed we get a quicker install
|
||||
WORKDIR $MEALIE_HOME
|
||||
RUN . $VENV_PATH/bin/activate && poetry install
|
||||
WORKDIR /
|
||||
|
||||
VOLUME [ "/app/data/" ]
|
||||
RUN chmod +x $MEALIE_HOME/mealie/run.sh
|
||||
ENTRYPOINT $MEALIE_HOME/mealie/run.sh "reload"
|
||||
|
||||
EXPOSE 80
|
||||
###############################################
|
||||
# Production Image
|
||||
###############################################
|
||||
FROM python-base as production
|
||||
ENV PRODUCTION=true
|
||||
|
||||
CMD /app/mealie/run.sh
|
||||
# curl for used by healthcheck
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
curl \
|
||||
&& apt-get autoremove \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# copying poetry and venv into image
|
||||
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
|
||||
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
|
||||
|
||||
# copying caddy into image
|
||||
COPY --from=builder-base /usr/bin/caddy /usr/bin/caddy
|
||||
|
||||
# copy backend
|
||||
COPY ./mealie $MEALIE_HOME/mealie
|
||||
COPY ./poetry.lock ./pyproject.toml $MEALIE_HOME/
|
||||
COPY ./gunicorn_conf.py $MEALIE_HOME
|
||||
|
||||
#! Future
|
||||
# COPY ./alembic ./alembic.ini $MEALIE_HOME/
|
||||
|
||||
# venv already has runtime deps installed we get a quicker install
|
||||
WORKDIR $MEALIE_HOME
|
||||
RUN . $VENV_PATH/bin/activate && poetry install -E pgsql --no-dev
|
||||
WORKDIR /
|
||||
|
||||
# copy frontend
|
||||
COPY --from=frontend-build /app/dist $MEALIE_HOME/dist
|
||||
COPY ./dev/data/templates $MEALIE_HOME/data/templates
|
||||
COPY ./Caddyfile $MEALIE_HOME
|
||||
|
||||
VOLUME [ "$MEALIE_HOME/data/" ]
|
||||
ENV APP_PORT=80
|
||||
|
||||
EXPOSE ${APP_PORT}
|
||||
|
||||
HEALTHCHECK CMD curl -f http://localhost:${APP_PORT} || exit 1
|
||||
|
||||
RUN chmod +x $MEALIE_HOME/mealie/run.sh
|
||||
ENTRYPOINT $MEALIE_HOME/mealie/run.sh
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
FROM python:3.9-slim-buster
|
||||
|
||||
|
||||
ENV PRODUCTION false
|
||||
ENV POETRY_VERSION 1.1.6
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc g++ \
|
||||
curl \
|
||||
gnupg gnupg2 gnupg1 \
|
||||
apt-transport-https \
|
||||
debian-archive-keyring \
|
||||
debian-keyring \
|
||||
libwebp-dev \
|
||||
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | apt-key add - \
|
||||
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee -a /etc/apt/sources.list.d/caddy-stable.list \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||
&& apt autoremove \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& apt-get remove -y curl apt-transport-https debian-keyring g++ gnupg gnupg2 gnupg1
|
||||
|
||||
RUN pip install --no-cache-dir "poetry==$POETRY_VERSION"
|
||||
|
||||
WORKDIR /app/
|
||||
|
||||
# Copy poetry.lock* in case it doesn't exist in the repo
|
||||
COPY ./pyproject.toml /app/
|
||||
COPY ./mealie /app/mealie
|
||||
RUN poetry config virtualenvs.create false \
|
||||
&& poetry install
|
||||
|
||||
RUN chmod +x /app/mealie/run.sh
|
||||
CMD ["/app/mealie/run.sh", "reload"]
|
|
@ -23,7 +23,8 @@ services:
|
|||
image: mealie-api:dev
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile.dev
|
||||
target: development
|
||||
dockerfile: Dockerfile
|
||||
restart: always
|
||||
ports:
|
||||
- 9921:9000
|
||||
|
|
|
@ -3,6 +3,7 @@ services:
|
|||
mealie:
|
||||
build:
|
||||
context: ./
|
||||
target: production
|
||||
dockerfile: Dockerfile
|
||||
container_name: mealie
|
||||
restart: always
|
||||
|
@ -17,6 +18,13 @@ services:
|
|||
POSTGRES_SERVER: postgres
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_DB: mealie
|
||||
|
||||
# WORKERS_PER_CORE: 0.5
|
||||
# MAX_WORKERS: 8
|
||||
|
||||
WEB_CONCURRENCY: 2
|
||||
tmpfs:
|
||||
- /mem:size=64m,mode=1777,noatime
|
||||
postgres:
|
||||
container_name: postgres
|
||||
image: postgres
|
||||
|
|
11
docs/docs/assets/js/extra.js
Normal file
11
docs/docs/assets/js/extra.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* Add target="_blank" to external links */
|
||||
/* Source: https://html.com/attributes/a-target/#:~:text=browser */
|
||||
function externalLinks() {
|
||||
for (var c = document.getElementsByTagName("a"), a = 0; a < c.length; a++) {
|
||||
var b = c[a];
|
||||
b.getAttribute("href") &&
|
||||
b.hostname !== location.hostname &&
|
||||
(b.target = "_blank");
|
||||
}
|
||||
}
|
||||
externalLinks();
|
|
@ -33,6 +33,12 @@ a.md-button.md-button:hover {
|
|||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Add icon after external links */
|
||||
/* Ignore auto-generated material theme links */
|
||||
a[target="_blank"]:not([class*="md-"]):after {
|
||||
content: " " url("../svg/open-in-new.svg");
|
||||
}
|
||||
|
||||
/* Site width etc.*/
|
||||
.md-grid {
|
||||
max-width: 64rem !important;
|
||||
|
|
3
docs/docs/assets/svg/open-in-new.svg
Normal file
3
docs/docs/assets/svg/open-in-new.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24">
|
||||
<path fill="rgb(229,131,37)" d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 259 B |
|
@ -18,7 +18,7 @@
|
|||
If you have been using the API directly, many of the routes and status codes have changed. You may experience issues with directly consuming the API.
|
||||
|
||||
#### Arm/v7 Support
|
||||
Mealie will no longer build in CI/CD due to a issue with the rust compiler on 32 bit devices. You can reference [this issue on the matrix-org/synapse](https://github.com/matrix-org/synapse/issues/9403){:target="_blank"} Github page that are facing a similar issue. You may still be able to build the docker image you-self.
|
||||
Mealie will no longer build in CI/CD due to a issue with the rust compiler on 32 bit devices. You can reference [this issue on the matrix-org/synapse](https://github.com/matrix-org/synapse/issues/9403) Github page that are facing a similar issue. You may still be able to build the docker image you-self.
|
||||
|
||||
!!! warning "Potential Data Loss"
|
||||
With this release comes a major rework of how files are stored on disk and where things belong. Migration of files should be done automatically. We have tested extensively with many different backups and user bases and have found that no one experienced data-loss. HOWEVER, with all the major changes that have occurred, it is vital that to prevent any data-loss you must create a backup and store that backup outside of your mealie instance. If you do not do this, you may lose your data.
|
||||
|
@ -44,7 +44,7 @@
|
|||
### Highlights
|
||||
- Recipe Parser
|
||||
- Recipes can now be imported with a bookmarklet!
|
||||
- Significant improvement in supported sites with the new [Recipe Scraper Library](https://github.com/hhursev/recipe-scrapers){:target="_blank"}
|
||||
- Significant improvement in supported sites with the new [Recipe Scraper Library](https://github.com/hhursev/recipe-scrapers)
|
||||
- UI Debugging now available at `/recipes/debugger`
|
||||
- Better error messages on failure
|
||||
- ⚠️ last_recipe.json is now depreciated
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# vx.x.x COOL TITLE GOES HERE
|
||||
# v0.5.1
|
||||
|
||||
**App Version: v0.5.1**
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Contributing to Mealie
|
||||
|
||||
[Please Join the Discord](https://discord.gg/QuStdQGSGK){:target="_blank"}. We are building a community of developers working on the project.
|
||||
[Please Join the Discord](https://discord.gg/QuStdQGSGK). We are building a community of developers working on the project.
|
||||
|
||||
## We Develop with Github
|
||||
We use github to host code, to track issues and feature requests, as well as accept pull requests.
|
||||
|
||||
## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html){:target="_blank"}, So All Code Changes Happen Through Pull Requests
|
||||
Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html){:target="_blank"}). We actively welcome your pull requests:
|
||||
## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
|
||||
Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests:
|
||||
|
||||
1. Fork the repo and create your branch from `dev`.
|
||||
2. Checkout the Discord, the PRs page, or the Projects page to get an idea of what's already being worked on.
|
||||
|
@ -17,10 +17,10 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu
|
|||
7. If you make changes to the dev branch reflect those changes in the active changelog to keep track of changes. Don't forget to add your name/handle/identifier!
|
||||
|
||||
## Any contributions you make will be under the MIT Software License
|
||||
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/){:target="_blank"} that covers the project. Feel free to contact the maintainers if that's a concern.
|
||||
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern.
|
||||
|
||||
## Report bugs using Github's [issues](https://github.com/hay-kot/mealie/issues){:target="_blank"}
|
||||
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/hay-kot/mealie/issues/new){:target="_blank"}; it's that easy!
|
||||
## Report bugs using Github's [issues](https://github.com/hay-kot/mealie/issues)
|
||||
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/hay-kot/mealie/issues/new); it's that easy!
|
||||
|
||||
## Write bug reports with detail, background, and sample code
|
||||
**Great Bug Reports** tend to have:
|
||||
|
@ -28,7 +28,7 @@ We use GitHub issues to track public bugs. Report a bug by [opening a new issue]
|
|||
- A quick summary and/or background
|
||||
- Steps to reproduce
|
||||
- Be specific!
|
||||
- Give sample code if you can. [This stackoverflow question](http://stackoverflow.com/q/12488905/180626){:target="_blank"} includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing
|
||||
- Give sample code if you can. [This stackoverflow question](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing
|
||||
- What you expected would happen
|
||||
- What actually happens
|
||||
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
|
||||
|
@ -40,4 +40,4 @@ People *love* thorough bug reports. I'm not even kidding.
|
|||
By contributing, you agree that your contributions will be licensed under its MIT License.
|
||||
|
||||
## References
|
||||
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md){:target="_blank"}
|
||||
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)
|
||||
|
|
|
@ -48,4 +48,4 @@ code-gen 🤖 Run Code-Gen Scripts
|
|||
|
||||
Before you commit any changes on the backend/python side you'll want to run `make format` to format all the code with black. `make lint` to check with flake8, and `make test` to run pytests. You can also use `make test-all` to run both `lint` and `test`.
|
||||
|
||||
Run into another issue? [Ask for help on discord](https://discord.gg/QuStdQGSGK){:target="_blank"}
|
||||
Run into another issue? [Ask for help on discord](https://discord.gg/QuStdQGSGK)
|
|
@ -9,7 +9,7 @@ We love your input! We want to make contributing to this project as easy and tra
|
|||
- Becoming a maintainer
|
||||
- Help translate to a new language or improve current translations
|
||||
|
||||
[Remember to join the Discord and stay in touch with other developers working on the project](https://discord.gg/QuStdQGSGK){:target="_blank"}!
|
||||
[Remember to join the Discord and stay in touch with other developers working on the project](https://discord.gg/QuStdQGSGK)!
|
||||
|
||||
Additionally, you can buy me a coffee and support the project. When I get financial support it helps me know that there's real interest in the project and that it's worth the time to keep developing.
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# Contributing with Translations
|
||||
Translations can be a great way **for non-coders** to contribute to project.
|
||||
We use **[Crowdin](https://crowdin.com/project/mealie){:target="_blank"}** to allow several contributors to work on translating Mealie.
|
||||
We use **[Crowdin](https://crowdin.com/project/mealie)** to allow several contributors to work on translating Mealie.
|
||||
You can simply help by voting for your preferred translations, or even by completely translating Mealie into a new language.
|
||||
|
||||
Translations are regularly pulled from Crowdin and included in each new release.
|
||||
|
||||
Please use Crowdin as much as possible if you have any question/issue regarding a particular string. You can take a look at [Crowdin Knowledge base](https://support.crowdin.com/for-volunteer-translators/){:target="_blank"} if you want to know more about how to use this tool.
|
||||
Please use Crowdin as much as possible if you have any question/issue regarding a particular string. You can take a look at [Crowdin Knowledge base](https://support.crowdin.com/for-volunteer-translators/) if you want to know more about how to use this tool.
|
||||
|
||||
## My language is missing in Mealie
|
||||
Once your language is translated on Crowdin, we need to manually add it in Mealie. If you believe your language is ready for use, please create an issue on GitHub.
|
||||
|
@ -13,9 +13,9 @@ Once your language is translated on Crowdin, we need to manually add it in Meali
|
|||
## I can't find a particular text in Crowdin
|
||||
There can be several reasons:
|
||||
- The text you're looking for is outdated: someone has already changed it or it will be removed/changed in the next release.
|
||||
- It is possible some texts are not translatable (yet) for technical reasons. If you spot one, please reach out to us on [Discord](https://discord.gg/QuStdQGSGK){:target="_blank"} or raise an issue on GitHub.
|
||||
- It is possible some texts are not translatable (yet) for technical reasons. If you spot one, please reach out to us on [Discord](https://discord.gg/QuStdQGSGK) or raise an issue on GitHub.
|
||||
|
||||
## Technical information
|
||||
We use vue-i18n package for internationalization. Translations are stored in json format located in [frontend/src/locales/messages](https://github.com/hay-kot/mealie/tree/master/frontend/src/locales/messages){:target="_blank"}.
|
||||
We use vue-i18n package for internationalization. Translations are stored in json format located in [frontend/src/locales/messages](https://github.com/hay-kot/mealie/tree/master/frontend/src/locales/messages).
|
||||
|
||||
[i18n Ally for VScode](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally){:target="_blank"} is helpful for generating new strings to translate. It also has a nice feature, which shows translations in-place when editing code.
|
||||
[i18n Ally for VScode](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) is helpful for generating new strings to translate. It also has a nice feature, which shows translations in-place when editing code.
|
|
@ -3,7 +3,7 @@
|
|||
All recipe data can be imported and exported as necessary from the UI. Under the admin page you'll find the section for using Backups and Exports.
|
||||
|
||||
!!! danger
|
||||
As this is still a **BETA** it is recommended that you backup your data often and store in more than one place. Adhere to backup best practices with the [3-2-1 Backup Rule](https://en.wikipedia.org/wiki/Backup){:target="_blank"}. Prior to upgrading you **should** perform a backup to limit any data loss.
|
||||
As this is still a **BETA** it is recommended that you backup your data often and store in more than one place. Adhere to backup best practices with the [3-2-1 Backup Rule](https://en.wikipedia.org/wiki/Backup). Prior to upgrading you **should** perform a backup to limit any data loss.
|
||||
|
||||
!!! tip "Mealie data that is saved on backups"
|
||||
- [x] Recipe Data
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Building Pages
|
||||
|
||||
!!! warning
|
||||
The page building is still experimental and may change. You can provide feedback on any changes you'd like to see on [github](https://github.com/hay-kot/mealie/discussions/229){:target="_blank"}
|
||||
The page building is still experimental and may change. You can provide feedback on any changes you'd like to see on [github](https://github.com/hay-kot/mealie/discussions/229)
|
||||
|
||||
Custom pages can be created to organize multiple categories into a single page. Links to your custom pages are displayed on the home page sidebar and accessible by all users, however only Administrators can create or update pages.
|
||||
![custom page](../../assets/img/custom-page.webp)
|
||||
|
|
|
@ -31,4 +31,4 @@ style:
|
|||
|
||||
|
||||
!!! tip
|
||||
Due to how Home Assistant works with images, I had to include the additional styling to get the images to not appear distorted. This includes and [additional installation](https://github.com/thomasloven/lovelace-card-mod){:target="_blank"} from HACS.
|
||||
Due to how Home Assistant works with images, I had to include the additional styling to get the images to not appear distorted. This includes and [additional installation](https://github.com/thomasloven/lovelace-card-mod) from HACS.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
![](../../assets/img/iphone-image.png){: align=right style="height:400px;width:400px"}
|
||||
|
||||
|
||||
User [brasilikum](https://github.com/brasilikum){:target="_blank"} opened an issue on the main repo about how they had created an [iOS shortcut](https://github.com/hay-kot/mealie/issues/103){:target="_blank"} for interested users. This is a useful utility for iOS users who browse for recipes in their web browser from their devices.
|
||||
User [brasilikum](https://github.com/brasilikum) opened an issue on the main repo about how they had created an [iOS shortcut](https://github.com/hay-kot/mealie/issues/103) for interested users. This is a useful utility for iOS users who browse for recipes in their web browser from their devices.
|
||||
|
||||
Don't know what an iOS shortcut is? Neither did I! Experienced iOS users may already be familiar with this utility but for the uninitiated, here is the official Apple explanation:
|
||||
|
||||
|
@ -15,7 +15,7 @@ Don't know what an iOS shortcut is? Neither did I! Experienced iOS users may alr
|
|||
> A shortcut is a quick way to get one or more tasks done with your apps. The Shortcuts app lets you create your own shortcuts with multiple steps. For example, build a “Surf Time” shortcut that grabs the surf report, gives an ETA to the beach, and launches your surf music playlist.
|
||||
|
||||
|
||||
Basically it is a visual scripting language that lets a user build an automation in a guided fashion. The automation can be [shared with anyone](https://www.icloud.com/shortcuts/6ae356d5fc644cfa8983a3c90f242fbb){:target="_blank"} but if it is a user creation, you'll have to jump through a few hoops to make an untrusted automation work on your device. In brasilikum's shortcut, you need to make changes for it to work. Recent updates to the project have changed some of the syntax and folder structure since its original creation.
|
||||
Basically it is a visual scripting language that lets a user build an automation in a guided fashion. The automation can be [shared with anyone](https://www.icloud.com/shortcuts/6ae356d5fc644cfa8983a3c90f242fbb) but if it is a user creation, you'll have to jump through a few hoops to make an untrusted automation work on your device. In brasilikum's shortcut, you need to make changes for it to work. Recent updates to the project have changed some of the syntax and folder structure since its original creation.
|
||||
|
||||
|
||||
![screenshot](../../assets/img/ios-shortcut-image.jpg){: align=right style="height:500;width:400px"}
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
|
||||
|
||||
|
||||
To make the setup of a Reverse Proxy much easier, Linuxserver.io developed [SWAG](https://github.com/linuxserver/docker-swag){:target="_blank"}
|
||||
To make the setup of a Reverse Proxy much easier, Linuxserver.io developed [SWAG](https://github.com/linuxserver/docker-swag)
|
||||
SWAG - Secure Web Application Gateway (formerly known as letsencrypt, no relation to Let's Encrypt™) sets up an Nginx web server and reverse proxy with PHP support and a built-in certbot client that automates free SSL server certificate generation and renewal processes (Let's Encrypt and ZeroSSL). It also contains fail2ban for intrusion prevention.
|
||||
|
||||
## Step 1: Get a domain
|
||||
|
||||
The first step is to grab a dynamic DNS if you don't have your own subdomain already. You can get this from for example [DuckDNS](https://www.duckdns.org){:target="_blank"}.
|
||||
The first step is to grab a dynamic DNS if you don't have your own subdomain already. You can get this from for example [DuckDNS](https://www.duckdns.org).
|
||||
|
||||
## Step 2: Set-up SWAG
|
||||
|
||||
Then you will need to set up SWAG, the variables of the docker-compose are explained on the Github page of [SWAG](https://github.com/linuxserver/docker-swag){:target="_blank"}.
|
||||
Then you will need to set up SWAG, the variables of the docker-compose are explained on the Github page of [SWAG](https://github.com/linuxserver/docker-swag).
|
||||
This is an example of how to set it up using duckdns and docker-compose.
|
||||
|
||||
!!! example "docker-compose.yml"
|
||||
|
|
|
@ -8,7 +8,7 @@ Mealie supports long-live api tokens in the user frontend. See [user settings pa
|
|||
## Key Components
|
||||
|
||||
### Exploring Your Local API
|
||||
On your local installation you can access interactive API documentation that provides `curl` examples and expected results. This allows you to easily test and interact with your API to identify places to include your own functionality. You can visit the documentation at `http://mealie.yourdomain.com/docs` or see the example at the [Demo Site](https://mealie-demo.hay-kot.dev/docs){:target="_blank"}
|
||||
On your local installation you can access interactive API documentation that provides `curl` examples and expected results. This allows you to easily test and interact with your API to identify places to include your own functionality. You can visit the documentation at `http://mealie.yourdomain.com/docs` or see the example at the [Demo Site](https://mealie-demo.hay-kot.dev/docs)
|
||||
|
||||
### Recipe Extras
|
||||
Recipes extras are a key feature of the Mealie API. They allow you to create custom json key/value pairs within a recipe to reference from 3rd part applications. You can use these keys to contain information to trigger automation or custom messages to relay to your desired device.
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# Installation
|
||||
To deploy mealie on your local network it is highly recommended to use docker to deploy the image straight from dockerhub. Using the docker-compose below you should be able to get a stack up and running easily by changing a few default values and deploying. You can deploy with either SQLite (default) or Postgres. SQLite is sufficient for most use cases. Additionally, with mealies automated backup and restore functionality, you can easily move between SQLite and Postgres as you wish.
|
||||
|
||||
To deploy mealie on your local network it is highly recommended to use docker to deploy the image straight from dockerhub. Using the docker-compose below you should be able to get a stack up and running easily by changing a few default values and deploying. You can deploy with either SQLite (default) or Postgres. SQLite is sufficient for most use cases. Additionally, with mealies automated backup and restore functionality, you can easily move between SQLite and Postgres as you wish.
|
||||
|
||||
[Get Docker](https://docs.docker.com/get-docker/){:target="_blank"}
|
||||
[Get Docker](https://docs.docker.com/get-docker/)
|
||||
|
||||
[Mealie on Dockerhub](https://hub.docker.com/r/hkotel/mealie){:target="_blank"}
|
||||
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
[Mealie on Dockerhub](https://hub.docker.com/r/hkotel/mealie)
|
||||
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
|
||||
## Quick Start - Docker CLI
|
||||
|
||||
Deployment with the Docker CLI can be done with `docker run` and specify the database type, in this case `sqlite`, setting the exposed port `9925`, mounting the current directory, and pull the latest image. After the image is up and running you can navigate to http://your.ip.address:9925 and you'll should see mealie up and running!
|
||||
|
||||
```shell
|
||||
|
@ -22,12 +22,14 @@ docker run \
|
|||
```
|
||||
|
||||
!!! tip "Default Credentials"
|
||||
**Username:** changeme@email.com
|
||||
|
||||
**Username:** changeme@email.com
|
||||
|
||||
**Password:** MyPassword
|
||||
|
||||
## Docker Compose with SQLite
|
||||
Deployment with docker-compose is the recommended method for deployment. The example below will create an instance of mealie available on port `9925` with the data volume mounted from the local directory. To use, create a docker-compose.yml file, paste the contents below and save. In the terminal run `docker-compose up -d` to start the container.
|
||||
|
||||
Deployment with docker-compose is the recommended method for deployment. The example below will create an instance of mealie available on port `9925` with the data volume mounted from the local directory. To use, create a docker-compose.yml file, paste the contents below and save. In the terminal run `docker-compose up -d` to start the container.
|
||||
|
||||
```yaml
|
||||
version: "3.1"
|
||||
|
@ -39,14 +41,23 @@ services:
|
|||
ports:
|
||||
- 9925:80
|
||||
environment:
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
TZ: America/Anchorage
|
||||
|
||||
# WORKERS_PER_CORE: 0.5
|
||||
# MAX_WORKERS: 8
|
||||
|
||||
WEB_CONCURRENCY: 2
|
||||
volumes:
|
||||
- ./mealie/data/:/app/data
|
||||
|
||||
tmpfs:
|
||||
- /mem:size=64m,mode=1777,noatime
|
||||
```
|
||||
|
||||
## Docker Compose with Postgres *(BETA)*
|
||||
Postgres support was introduced in v0.5.0. At this point it should be used with caution and frequent backups.
|
||||
## Docker Compose with Postgres _(BETA)_
|
||||
|
||||
Postgres support was introduced in v0.5.0. At this point it should be used with caution and frequent backups.
|
||||
|
||||
```yaml
|
||||
version: "3.1"
|
||||
|
@ -57,13 +68,27 @@ services:
|
|||
restart: always
|
||||
ports:
|
||||
- 9090:80
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
TZ: America/Anchorage
|
||||
DB_ENGINE: postgres # Optional: 'sqlite', 'postgres'
|
||||
POSTGRES_USER: mealie
|
||||
POSTGRES_PASSWORD: mealie
|
||||
POSTGRES_SERVER: postgres
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_DB: mealie
|
||||
|
||||
# WORKERS_PER_CORE: 0.5
|
||||
# MAX_WORKERS: 8
|
||||
|
||||
WEB_CONCURRENCY: 2
|
||||
volumes:
|
||||
- ./mealie/data/:/app/data
|
||||
tmpfs:
|
||||
- /mem:size=64m,mode=1777,noatime
|
||||
postgres:
|
||||
container_name: postgres
|
||||
image: postgres
|
||||
|
@ -75,79 +100,86 @@ services:
|
|||
|
||||
## Env Variables
|
||||
|
||||
| Variables | Default | Description |
|
||||
| ----------------- | --------------------- | ----------------------------------------------------------------------------------- |
|
||||
| DEFAULT_GROUP | Home | The default group for users |
|
||||
| DEFAULT_EMAIL | changeme@email.com | The default username for the superuser |
|
||||
| BASE_URL | http://localhost:8080 | Used for Notifications |
|
||||
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
|
||||
| POSTGRES_USER | mealie | Postgres database user |
|
||||
| POSTGRES_PASSWORD | mealie | Postgres database password |
|
||||
| POSTGRES_SERVER | postgres | Postgres database server address |
|
||||
| POSTGRES_PORT | 5432 | Postgres database port |
|
||||
| POSTGRES_DB | mealie | Postgres database name |
|
||||
| TOKEN_TIME | 2 | The time in hours that a login/auth token is valid |
|
||||
| API_PORT | 9000 | The port exposed by backend API. **do not change this if you're running in docker** |
|
||||
| API_DOCS | True | Turns on/off access to the API documentation locally. |
|
||||
| TZ | UTC | Must be set to get correct date/time on the server |
|
||||
|
||||
| Variables | Default | Description |
|
||||
| ----------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PUID | 911 | UserID permissions between host OS and container |
|
||||
| PGID | 911 | GroupID permissions between host OS and container |
|
||||
| DEFAULT_GROUP | Home | The default group for users |
|
||||
| DEFAULT_EMAIL | changeme@email.com | The default username for the superuser |
|
||||
| BASE_URL | http://localhost:8080 | Used for Notifications |
|
||||
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
|
||||
| POSTGRES_USER | mealie | Postgres database user |
|
||||
| POSTGRES_PASSWORD | mealie | Postgres database password |
|
||||
| POSTGRES_SERVER | postgres | Postgres database server address |
|
||||
| POSTGRES_PORT | 5432 | Postgres database port |
|
||||
| POSTGRES_DB | mealie | Postgres database name |
|
||||
| TOKEN_TIME | 2 | The time in hours that a login/auth token is valid |
|
||||
| API_PORT | 9000 | The port exposed by backend API. **Do not change this if you're running in Docker** |
|
||||
| API_DOCS | True | Turns on/off access to the API documentation locally. |
|
||||
| TZ | UTC | Must be set to get correct date/time on the server |
|
||||
| WORKERS_PER_CORE | 1 | Set the number of workers to the number of CPU cores multiplied by this value (Value \* CPUs). More info [here][workers_per_core] |
|
||||
| MAX_WORKERS | | Set the maximum number of workers to use. Default is not set meaning unlimited. More info [here][max_workers] |
|
||||
| WEB_CONCURRENCY | 2 | Override the automatic definition of number of workers. More info [here][web_concurrency] |
|
||||
|
||||
## Raspberry Pi 4
|
||||
|
||||
!!! tip "Fatal Python error: init_interp_main: can't initialize time"
|
||||
|
||||
Some users experience an problem with running the linux/arm/v7 container on Raspberry Pi 4. This is not a problem with the Mealie container, but with a bug in the hosts Docker installation.
|
||||
|
||||
Update the host RP4 using [instructions](https://github.com/linuxserver/docker-papermerge/issues/4#issuecomment-735236388){:target="_blank"}, summarized here:
|
||||
|
||||
Update the host RP4 using [instructions](https://github.com/linuxserver/docker-papermerge/issues/4#issuecomment-735236388), summarized here:
|
||||
|
||||
```shell
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libseccomp/libseccomp2_2.5.1-1_armhf.deb
|
||||
sudo dpkg -i libseccomp2_2.5.1-1_armhf.deb
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
|
||||
## Advanced
|
||||
!!! warning "Not Required"
|
||||
The items below are completely optional and are not required to manage or install your Mealie instance.
|
||||
|
||||
The items below are completely optional and are not required to manage or install your Mealie instance.
|
||||
|
||||
### Custom Caddy File
|
||||
The Docker image provided by Mealie contains both the API and the html bundle in one convenient image. This is done by using a proxy server to serve different parts of the application depending on the URL/URI. Requests sent to `/api/*` or `/docs` will be directed to the API, anything else will be served the static web files. Below is the default Caddyfile that is used to proxy requests. You can override this file by mounting an alternative Caddyfile to `/app/Caddyfile`.
|
||||
|
||||
The Docker image provided by Mealie contains both the API and the html bundle in one convenient image. This is done by using a proxy server to serve different parts of the application depending on the URL/URI. Requests sent to `/api/*` or `/docs` will be directed to the API, anything else will be served the static web files. Below is the default Caddyfile that is used to proxy requests. You can override this file by mounting an alternative Caddyfile to `/app/Caddyfile`.
|
||||
|
||||
```
|
||||
{
|
||||
auto_https off
|
||||
auto_https off
|
||||
admin off
|
||||
}
|
||||
|
||||
:80 {
|
||||
@proxied path /api/* /docs /openapi.json
|
||||
|
||||
|
||||
root * /app/dist
|
||||
encode gzip
|
||||
uri strip_suffix /
|
||||
|
||||
|
||||
handle_path /api/recipes/image/* {
|
||||
root * /app/data/img/
|
||||
file_server
|
||||
}
|
||||
|
||||
handle @proxied {
|
||||
reverse_proxy http://127.0.0.1:9000
|
||||
reverse_proxy http://127.0.0.1:9000
|
||||
}
|
||||
|
||||
handle {
|
||||
try_files {path}.html {path} /
|
||||
file_server
|
||||
file_server
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Deployed without Docker
|
||||
!!! error "Unsupported Deployment"
|
||||
If you are experiencing a problem with manual deployment, please do not submit a github issue unless it is related to an aspect of the application. For deployment help, the [discord server](https://discord.gg/QuStdQGSGK){:target="_blank"} is a better place to find support.
|
||||
|
||||
Alternatively, this project is built on Python and SQLite so you may run it as a python application on your server. This is not a supported options for deployment and is only here as a reference for those who would like to do this on their own. To get started you can clone this repository into a directory of your choice and use the instructions below as a reference for how to get started.
|
||||
!!! error "Unsupported Deployment"
|
||||
|
||||
If you are experiencing a problem with manual deployment, please do not submit a github issue unless it is related to an aspect of the application. For deployment help, the [discord server](https://discord.gg/QuStdQGSGK) is a better place to find support.
|
||||
|
||||
Alternatively, this project is built on Python and SQLite so you may run it as a python application on your server. This is not a supported options for deployment and is only here as a reference for those who would like to do this on their own. To get started you can clone this repository into a directory of your choice and use the instructions below as a reference for how to get started.
|
||||
|
||||
There are three parts to the Mealie application
|
||||
|
||||
|
@ -156,14 +188,19 @@ There are three parts to the Mealie application
|
|||
- Proxy Server
|
||||
|
||||
### Frontend/ Static Files
|
||||
|
||||
The frontend static files are generated with `npm run build`. This is done during the build process with docker. If you choose to deploy this as a system application you must do this process yourself. In the project directory run `cd frontend` to change directories into the frontend directory and run `npm install` and then `npm run build`. This will generate the static files in a `dist` folder in the frontend directory.
|
||||
|
||||
### Backend API
|
||||
|
||||
The backend API is build with Python, FastAPI, and SQLite and requires Python 3.9, and Poetry. Once the requirements are installed, in the project directory you can run the command `poetry install` to create a python virtual environment and install the python dependencies.
|
||||
|
||||
Once the dependencies are installed you should be ready to run the server. To initialize that database you need to first run `python mealie/db/init_db.py`. Then to start The web server, you run the command `uvicorn mealie.app:app --host 0.0.0.0 --port 9000`
|
||||
|
||||
Once the dependencies are installed you should be ready to run the server. To initialize that database you need to first run `python mealie/db/init_db.py`. Then to start The web server, you run the command `uvicorn mealie.app:app --host 0.0.0.0 --port 9000`
|
||||
|
||||
### Proxy Server
|
||||
You must use a proxy server to server up the static files created with `npm run build` and proxy requests to the API. In the docker build this is done with Caddy. You can use the CaddyFile in the section above as a reference. One important thing to keep in mind is that you should drop any trailing `/` in the url. Not doing this may result in failed API requests.
|
||||
|
||||
You must use a proxy server to server up the static files created with `npm run build` and proxy requests to the API. In the docker build this is done with Caddy. You can use the CaddyFile in the section above as a reference. One important thing to keep in mind is that you should drop any trailing `/` in the url. Not doing this may result in failed API requests.
|
||||
|
||||
[workers_per_core]: https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/README.md#workers_per_core
|
||||
[max_workers]: https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/README.md#max_workers
|
||||
[web_concurrency]: https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/README.md#web_concurrency
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Mealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and Mealie will automatically import the relevant data or add a family recipe with the UI editor. Mealie also provides an API for interactions from 3rd party applications.
|
||||
|
||||
[Remember to join the Discord](https://discord.gg/QuStdQGSGK){:target="_blank"}!
|
||||
[Remember to join the Discord](https://discord.gg/QuStdQGSGK)!
|
||||
|
||||
!!! note
|
||||
In some of the demo gifs the styling may be different than the finale application. demos were done during development prior to finale styling.
|
||||
|
@ -26,7 +26,7 @@ Mealie is a self hosted recipe manager and meal planner with a RestAPI backend a
|
|||
- Flexible API
|
||||
- Custom key/value pairs for recipes
|
||||
- Webhook support
|
||||
- Interactive API Documentation thanks to [FastAPI](https://fastapi.tiangolo.com/){:target="_blank"} and [Swagger](https://petstore.swagger.io/){:target="_blank"}
|
||||
- Interactive API Documentation thanks to [FastAPI](https://fastapi.tiangolo.com/) and [Swagger](https://petstore.swagger.io/)
|
||||
- Raw JSON Recipe Editor
|
||||
- Migration from other platforms
|
||||
- Chowdown
|
||||
|
@ -36,7 +36,7 @@ Mealie is a self hosted recipe manager and meal planner with a RestAPI backend a
|
|||
## FAQ
|
||||
|
||||
### Why An API?
|
||||
An API allows integration into applications like [Home Assistant](https://www.home-assistant.io/){:target="_blank"} that can act as notification engines to provide custom notifications based of Meal Plan data to remind you to defrost the chicken, marinade the steak, or start the CrockPot. Additionally, you can access nearly any backend service via the API giving you total control to extend the application. To explore the API spin up your server and navigate to http://yourserver.com/docs for interactive API documentation.
|
||||
An API allows integration into applications like [Home Assistant](https://www.home-assistant.io/) that can act as notification engines to provide custom notifications based of Meal Plan data to remind you to defrost the chicken, marinade the steak, or start the CrockPot. Additionally, you can access nearly any backend service via the API giving you total control to extend the application. To explore the API spin up your server and navigate to http://yourserver.com/docs for interactive API documentation.
|
||||
|
||||
### Why a Database?
|
||||
Some users of static-site generator applications like ChowDown have expressed concerns about their data being stuck in a database. Considering this is a new project it is a valid concern to be worried about your data. Mealie specifically addresses this concern by provided automatic daily backups that export your data in json, plain-text markdown files, and/or custom Jinja2 templates. **This puts you in controls of how your data is represented** when exported from Mealie, which means you can easily migrate to any other service provided Mealie doesn't work for you.
|
||||
|
@ -48,10 +48,10 @@ As to why we need a database?
|
|||
|
||||
## Built With
|
||||
|
||||
* [Vue.js](https://vuejs.org/){:target="_blank"}
|
||||
* [Vuetify](https://vuetifyjs.com/en/){:target="_blank"}
|
||||
* [FastAPI](https://fastapi.tiangolo.com/){:target="_blank"}
|
||||
* [Docker](https://www.docker.com/){:target="_blank"}
|
||||
* [Vue.js](https://vuejs.org/)
|
||||
* [Vuetify](https://vuetifyjs.com/en/)
|
||||
* [FastAPI](https://fastapi.tiangolo.com/)
|
||||
* [Docker](https://www.docker.com/)
|
||||
|
||||
<!-- ROADMAP -->
|
||||
## Road Map
|
||||
|
|
|
@ -9,7 +9,7 @@ Below are some general guidelines that were considered when creating the organiz
|
|||
>
|
||||
> My tags are for picking the exact type of meal I'm looking for, based on my mood or my guests' diet, like gluten-free, vegetarian, sweet-sour or casserole. They can also act as sub-categories, like "alcohol" for beverages or "hot meal" for a main course.
|
||||
>
|
||||
> User: [sephrat](https://github.com/sephrat){:target="_blank"}
|
||||
> User: [sephrat](https://github.com/sephrat)
|
||||
|
||||
|
||||
## Structure
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Recipes
|
||||
|
||||
## URL Import
|
||||
Adding a recipe can be as easy as clicking in the bottom-right corner, copying the recipe URL into Mealie and letting the web scraper organize information. Currently this scraper is implemented with [recipe-scrapers](https://github.com/hhursev/recipe-scrapers){:target="_blank"}. You may have mixed results on some websites, especially with blogs or non-specific recipe websites. See the bulk import Option below for another a convenient way to add blog style recipes into Mealie.
|
||||
Adding a recipe can be as easy as clicking in the bottom-right corner, copying the recipe URL into Mealie and letting the web scraper organize information. Currently this scraper is implemented with [recipe-scrapers](https://github.com/hhursev/recipe-scrapers). You may have mixed results on some websites, especially with blogs or non-specific recipe websites. See the bulk import Option below for another a convenient way to add blog style recipes into Mealie.
|
||||
|
||||
!!! tip
|
||||
You can find a list of some of the supported sites in the recipe-scrapers repo. If you're site isn't supported, you can work with the recipe-scrapers team to implement it and we can down-stream those changes into Mealie.
|
||||
|
@ -12,7 +12,7 @@ Adding a recipe can be as easy as clicking in the bottom-right corner, copying t
|
|||
|
||||
You can use bookmarklets to generate a bookmark that will take your current location, and open a new tab that will try to import that URL into Mealie.
|
||||
|
||||
You can use a [bookmarklet generator site](https://caiorss.github.io/bookmarklet-maker/){:target="_blank"} and the code below to generate a bookmark for your site. Just change the `http://localhost:8080` to your sites web address and follow the instructions. Note that there is no trailing `/`.
|
||||
You can use a [bookmarklet generator site](https://caiorss.github.io/bookmarklet-maker/) and the code below to generate a bookmark for your site. Just change the `http://localhost:8080` to your sites web address and follow the instructions. Note that there is no trailing `/`.
|
||||
|
||||
```js
|
||||
var url = document.URL ;
|
||||
|
@ -54,7 +54,7 @@ Mealie also supports bulk import of recipe instructions and ingredients. Select
|
|||
![](../../assets/gifs/bulk-add-demo.gif)
|
||||
|
||||
## Schema
|
||||
Recipes are stored in the json-like format in mongoDB and then sent and edited in json format on the frontend. Each recipes uses [Recipe Schema](https://schema.org/Recipe){:target="_blank"} as a general guide with some additional properties specific to Mealie.
|
||||
Recipes are stored in the json-like format in mongoDB and then sent and edited in json format on the frontend. Each recipes uses [Recipe Schema](https://schema.org/Recipe) as a general guide with some additional properties specific to Mealie.
|
||||
|
||||
### Example
|
||||
```json
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
## Apprise
|
||||
|
||||
Using the [Apprise](https://github.com/caronc/apprise/){:target="_blank"} library Mealie is able to provide notification services for nearly every popular service. Some of our favorites are...
|
||||
Using the [Apprise](https://github.com/caronc/apprise/) library Mealie is able to provide notification services for nearly every popular service. Some of our favorites are...
|
||||
|
||||
- [Gotify](https://github.com/caronc/apprise/wiki/Notify_gotify){:target="_blank"}
|
||||
- [Discord](https://github.com/caronc/apprise/wiki/Notify_discord){:target="_blank"}
|
||||
- [Home Assistant](https://github.com/caronc/apprise/wiki/Notify_homeassistant){:target="_blank"}
|
||||
- [Matrix](https://github.com/caronc/apprise/wiki/Notify_matrix){:target="_blank"}
|
||||
- [Pushover](https://github.com/caronc/apprise/wiki/Notify_pushover){:target="_blank"}
|
||||
- [Gotify](https://github.com/caronc/apprise/wiki/Notify_gotify)
|
||||
- [Discord](https://github.com/caronc/apprise/wiki/Notify_discord)
|
||||
- [Home Assistant](https://github.com/caronc/apprise/wiki/Notify_homeassistant)
|
||||
- [Matrix](https://github.com/caronc/apprise/wiki/Notify_matrix)
|
||||
- [Pushover](https://github.com/caronc/apprise/wiki/Notify_pushover)
|
||||
|
||||
But there are many more to choose from! Take a look at their wiki for information on how to create their URL formats that you can use to create a notification integration in Mealie.
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
|||
# Development Road Map
|
||||
|
||||
## Feature Requests
|
||||
See the [Github META issue for tracking feature requests](https://github.com/hay-kot/mealie/issues/122){:target="_blank"}
|
||||
See the [Github META issue for tracking feature requests](https://github.com/hay-kot/mealie/issues/122)
|
||||
|
||||
## Progress
|
||||
See the [Github Projects](https://github.com/hay-kot/mealie/projects){:target="_blank"} to see what is currently being worked on
|
||||
See the [Github Projects](https://github.com/hay-kot/mealie/projects) to see what is currently being worked on
|
|
@ -45,6 +45,8 @@ markdown_extensions:
|
|||
|
||||
extra_css:
|
||||
- assets/stylesheets/custom.css
|
||||
extra_javascript:
|
||||
- assets/js/extra.js
|
||||
repo_url: https://github.com/hay-kot/mealie
|
||||
repo_name: hay-kot/mealie
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:latest
|
||||
FROM node:lts-alpine
|
||||
|
||||
# # install simple http server for serving static content
|
||||
# RUN npm install -g http-server
|
||||
|
@ -13,7 +13,7 @@ COPY package*.json ./
|
|||
RUN npm install
|
||||
|
||||
# copy project files and folders to the current working directory (i.e. 'app' folder)
|
||||
COPY . .
|
||||
# COPY . .
|
||||
|
||||
# build app for production with minification
|
||||
# RUN npm run build
|
||||
|
|
69
gunicorn_conf.py
Normal file
69
gunicorn_conf.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
# https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/2daa3e3873c837d5781feb4ff6a40a89f791f81b/docker-images/gunicorn_conf.py
|
||||
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
|
||||
workers_per_core_str = os.getenv("WORKERS_PER_CORE", "1")
|
||||
max_workers_str = os.getenv("MAX_WORKERS")
|
||||
use_max_workers = None
|
||||
if max_workers_str:
|
||||
use_max_workers = int(max_workers_str)
|
||||
web_concurrency_str = os.getenv("WEB_CONCURRENCY", None)
|
||||
|
||||
host = os.getenv("HOST", "127.0.0.1") # 0.0.0.0
|
||||
port = os.getenv("PORT", "80")
|
||||
bind_env = os.getenv("BIND", None)
|
||||
use_loglevel = os.getenv("LOG_LEVEL", "info")
|
||||
if bind_env:
|
||||
use_bind = bind_env
|
||||
else:
|
||||
use_bind = f"{host}:{port}"
|
||||
|
||||
cores = multiprocessing.cpu_count()
|
||||
workers_per_core = float(workers_per_core_str)
|
||||
default_web_concurrency = workers_per_core * cores
|
||||
if web_concurrency_str:
|
||||
web_concurrency = int(web_concurrency_str)
|
||||
assert web_concurrency > 0
|
||||
else:
|
||||
web_concurrency = max(int(default_web_concurrency), 2)
|
||||
if use_max_workers:
|
||||
web_concurrency = min(web_concurrency, use_max_workers)
|
||||
accesslog_var = os.getenv("ACCESS_LOG", "-")
|
||||
use_accesslog = accesslog_var or None
|
||||
errorlog_var = os.getenv("ERROR_LOG", "-")
|
||||
use_errorlog = errorlog_var or None
|
||||
graceful_timeout_str = os.getenv("GRACEFUL_TIMEOUT", "120")
|
||||
timeout_str = os.getenv("TIMEOUT", "120")
|
||||
keepalive_str = os.getenv("KEEP_ALIVE", "5")
|
||||
|
||||
# Gunicorn config variables
|
||||
loglevel = use_loglevel
|
||||
workers = web_concurrency
|
||||
bind = use_bind
|
||||
errorlog = use_errorlog
|
||||
worker_tmp_dir = "/mem" # "/dev/shm"
|
||||
accesslog = use_accesslog
|
||||
graceful_timeout = int(graceful_timeout_str)
|
||||
timeout = int(timeout_str)
|
||||
keepalive = int(keepalive_str)
|
||||
|
||||
|
||||
# For debugging and testing
|
||||
log_data = {
|
||||
"loglevel": loglevel,
|
||||
"workers": workers,
|
||||
"bind": bind,
|
||||
"graceful_timeout": graceful_timeout,
|
||||
"timeout": timeout,
|
||||
"keepalive": keepalive,
|
||||
"errorlog": errorlog,
|
||||
"accesslog": accesslog,
|
||||
# Additional, non-gunicorn variables
|
||||
"workers_per_core": workers_per_core,
|
||||
"use_max_workers": use_max_workers,
|
||||
"host": host,
|
||||
"port": port,
|
||||
}
|
||||
print(json.dumps(log_data))
|
1
makefile
1
makefile
|
@ -85,6 +85,7 @@ docs: ## 📄 Start Mkdocs Development Server
|
|||
cd docs && poetry run python -m mkdocs serve
|
||||
|
||||
docker-dev: ## 🐳 Build and Start Docker Development Stack
|
||||
docker-compose -f docker-compose.dev.yml -p dev-mealie down && \
|
||||
docker-compose -f docker-compose.dev.yml -p dev-mealie up --build
|
||||
|
||||
docker-prod: ## 🐳 Build and Start Docker Production Stack
|
||||
|
|
|
@ -1,29 +1,58 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Get Reload Arg `run.sh reload` for dev server
|
||||
ARG1=${1:-production}
|
||||
|
||||
# # Initialize Database Prerun
|
||||
poetry run python /app/mealie/db/init_db.py
|
||||
poetry run python /app/mealie/services/image/minify.py
|
||||
# Get PUID/PGID
|
||||
PUID=${PUID:-911}
|
||||
PGID=${PGID:-911}
|
||||
|
||||
add_user() {
|
||||
groupmod -o -g "$PGID" abc
|
||||
usermod -o -u "$PUID" abc
|
||||
|
||||
echo "
|
||||
User uid: $(id -u abc)
|
||||
User gid: $(id -g abc)
|
||||
"
|
||||
chown -R abc:abc /app
|
||||
}
|
||||
|
||||
init() {
|
||||
# $MEALIE_HOME directory
|
||||
cd /app
|
||||
# Activate our virtual environment here
|
||||
. /opt/pysetup/.venv/bin/activate
|
||||
|
||||
# Initialize Database Prerun
|
||||
poetry run python /app/mealie/db/init_db.py
|
||||
poetry run python /app/mealie/services/image/minify.py
|
||||
}
|
||||
|
||||
# Migrations
|
||||
# TODO
|
||||
# Migrations
|
||||
# Set Port from ENV Variable
|
||||
|
||||
if [ "$ARG1" == "reload" ]
|
||||
then
|
||||
if [ "$ARG1" == "reload" ]; then
|
||||
echo "Hot Reload!"
|
||||
|
||||
init
|
||||
|
||||
# Start API
|
||||
python /app/mealie/app.py
|
||||
else
|
||||
echo "Production"
|
||||
|
||||
add_user
|
||||
init
|
||||
|
||||
# Web Server
|
||||
caddy start --config ./Caddyfile
|
||||
caddy start --config /app/Caddyfile
|
||||
|
||||
# Start API
|
||||
uvicorn mealie.app:app --host 0.0.0.0 --port 9000
|
||||
# uvicorn mealie.app:app --host 0.0.0.0 --port 9000
|
||||
gunicorn mealie.app:app -b 0.0.0.0:9000 -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py
|
||||
fi
|
||||
|
||||
|
|
74
poetry.lock
generated
74
poetry.lock
generated
|
@ -338,6 +338,20 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
|
|||
[package.extras]
|
||||
docs = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "gunicorn"
|
||||
version = "20.1.0"
|
||||
description = "WSGI HTTP Server for UNIX"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
eventlet = ["eventlet (>=0.24.1)"]
|
||||
gevent = ["gevent (>=1.4.0)"]
|
||||
setproctitle = ["setproctitle"]
|
||||
tornado = ["tornado (>=0.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.12.0"
|
||||
|
@ -667,12 +681,12 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|||
dev = ["pre-commit", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "psycopg2"
|
||||
version = "2.8.6"
|
||||
name = "psycopg2-binary"
|
||||
version = "2.9.1"
|
||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||
category = "main"
|
||||
optional = true
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
|
@ -1260,12 +1274,12 @@ docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
|
|||
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
||||
|
||||
[extras]
|
||||
pgsql = ["psycopg2"]
|
||||
pgsql = ["psycopg2-binary"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "abcb73eea538ec6c7e8b5f5f483fb0dc22609f2f9ba910748992b54a065e7e5a"
|
||||
content-hash = "a06d6cf8970f370f05958cc8190a97c731dd586405d51ed11b828de842fbe1d2"
|
||||
|
||||
[metadata.files]
|
||||
aiofiles = [
|
||||
|
@ -1529,6 +1543,10 @@ greenlet = [
|
|||
{file = "greenlet-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa4230234d02e6f32f189fd40b59d5a968fe77e80f59c9c933384fe8ba535535"},
|
||||
{file = "greenlet-1.1.0.tar.gz", hash = "sha256:c87df8ae3f01ffb4483c796fe1b15232ce2b219f0b18126948616224d3f658ee"},
|
||||
]
|
||||
gunicorn = [
|
||||
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
||||
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
||||
]
|
||||
h11 = [
|
||||
{file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
|
||||
{file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
|
||||
|
@ -1775,22 +1793,36 @@ pluggy = [
|
|||
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
||||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||
]
|
||||
psycopg2 = [
|
||||
{file = "psycopg2-2.8.6-cp27-cp27m-win32.whl", hash = "sha256:068115e13c70dc5982dfc00c5d70437fe37c014c808acce119b5448361c03725"},
|
||||
{file = "psycopg2-2.8.6-cp27-cp27m-win_amd64.whl", hash = "sha256:d160744652e81c80627a909a0e808f3c6653a40af435744de037e3172cf277f5"},
|
||||
{file = "psycopg2-2.8.6-cp34-cp34m-win32.whl", hash = "sha256:b8cae8b2f022efa1f011cc753adb9cbadfa5a184431d09b273fb49b4167561ad"},
|
||||
{file = "psycopg2-2.8.6-cp34-cp34m-win_amd64.whl", hash = "sha256:f22ea9b67aea4f4a1718300908a2fb62b3e4276cf00bd829a97ab5894af42ea3"},
|
||||
{file = "psycopg2-2.8.6-cp35-cp35m-win32.whl", hash = "sha256:26e7fd115a6db75267b325de0fba089b911a4a12ebd3d0b5e7acb7028bc46821"},
|
||||
{file = "psycopg2-2.8.6-cp35-cp35m-win_amd64.whl", hash = "sha256:00195b5f6832dbf2876b8bf77f12bdce648224c89c880719c745b90515233301"},
|
||||
{file = "psycopg2-2.8.6-cp36-cp36m-win32.whl", hash = "sha256:a49833abfdede8985ba3f3ec641f771cca215479f41523e99dace96d5b8cce2a"},
|
||||
{file = "psycopg2-2.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:f974c96fca34ae9e4f49839ba6b78addf0346777b46c4da27a7bf54f48d3057d"},
|
||||
{file = "psycopg2-2.8.6-cp37-cp37m-win32.whl", hash = "sha256:6a3d9efb6f36f1fe6aa8dbb5af55e067db802502c55a9defa47c5a1dad41df84"},
|
||||
{file = "psycopg2-2.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:56fee7f818d032f802b8eed81ef0c1232b8b42390df189cab9cfa87573fe52c5"},
|
||||
{file = "psycopg2-2.8.6-cp38-cp38-win32.whl", hash = "sha256:ad2fe8a37be669082e61fb001c185ffb58867fdbb3e7a6b0b0d2ffe232353a3e"},
|
||||
{file = "psycopg2-2.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:56007a226b8e95aa980ada7abdea6b40b75ce62a433bd27cec7a8178d57f4051"},
|
||||
{file = "psycopg2-2.8.6-cp39-cp39-win32.whl", hash = "sha256:2c93d4d16933fea5bbacbe1aaf8fa8c1348740b2e50b3735d1b0bf8154cbf0f3"},
|
||||
{file = "psycopg2-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7"},
|
||||
{file = "psycopg2-2.8.6.tar.gz", hash = "sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543"},
|
||||
psycopg2-binary = [
|
||||
{file = "psycopg2-binary-2.9.1.tar.gz", hash = "sha256:b0221ca5a9837e040ebf61f48899926b5783668b7807419e4adae8175a31f773"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c250a7ec489b652c892e4f0a5d122cc14c3780f9f643e1a326754aedf82d9a76"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aef9aee84ec78af51107181d02fe8773b100b01c5dfde351184ad9223eab3698"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123c3fb684e9abfc47218d3784c7b4c47c8587951ea4dd5bc38b6636ac57f616"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_24_aarch64.whl", hash = "sha256:995fc41ebda5a7a663a254a1dcac52638c3e847f48307b5416ee373da15075d7"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_24_ppc64le.whl", hash = "sha256:fbb42a541b1093385a2d8c7eec94d26d30437d0e77c1d25dae1dcc46741a385e"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-win32.whl", hash = "sha256:20f1ab44d8c352074e2d7ca67dc00843067788791be373e67a0911998787ce7d"},
|
||||
{file = "psycopg2_binary-2.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f6fac64a38f6768e7bc7b035b9e10d8a538a9fadce06b983fb3e6fa55ac5f5ce"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:1e3a362790edc0a365385b1ac4cc0acc429a0c0d662d829a50b6ce743ae61b5a"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8559617b1fcf59a9aedba2c9838b5b6aa211ffedecabca412b92a1ff75aac1a"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a36c7eb6152ba5467fb264d73844877be8b0847874d4822b7cf2d3c0cb8cdcb0"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:2f62c207d1740b0bde5c4e949f857b044818f734a3d57f1d0d0edc65050532ed"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:cfc523edecddaef56f6740d7de1ce24a2fdf94fd5e704091856a201872e37f9f"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-win32.whl", hash = "sha256:1e85b74cbbb3056e3656f1cc4781294df03383127a8114cbc6531e8b8367bf1e"},
|
||||
{file = "psycopg2_binary-2.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1473c0215b0613dd938db54a653f68251a45a78b05f6fc21af4326f40e8360a2"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:35c4310f8febe41f442d3c65066ca93cccefd75013df3d8c736c5b93ec288140"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c13d72ed6af7fd2c8acbd95661cf9477f94e381fce0792c04981a8283b52917"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14db1752acdd2187d99cb2ca0a1a6dfe57fc65c3281e0f20e597aac8d2a5bd90"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:aed4a9a7e3221b3e252c39d0bf794c438dc5453bc2963e8befe9d4cd324dff72"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:da113b70f6ec40e7d81b43d1b139b9db6a05727ab8be1ee559f3a69854a69d34"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-win32.whl", hash = "sha256:4235f9d5ddcab0b8dbd723dca56ea2922b485ea00e1dafacf33b0c7e840b3d32"},
|
||||
{file = "psycopg2_binary-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:988b47ac70d204aed01589ed342303da7c4d84b56c2f4c4b8b00deda123372bf"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:7360647ea04db2e7dff1648d1da825c8cf68dc5fbd80b8fb5b3ee9f068dcd21a"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca86db5b561b894f9e5f115d6a159fff2a2570a652e07889d8a383b5fae66eb4"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ced67f1e34e1a450cdb48eb53ca73b60aa0af21c46b9b35ac3e581cf9f00e31"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:0f2e04bd2a2ab54fa44ee67fe2d002bb90cee1c0f1cc0ebc3148af7b02034cbd"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:3242b9619de955ab44581a03a64bdd7d5e470cc4183e8fcadd85ab9d3756ce7a"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-win32.whl", hash = "sha256:0b7dae87f0b729922e06f85f667de7bf16455d411971b2043bbd9577af9d1975"},
|
||||
{file = "psycopg2_binary-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:b4d7679a08fea64573c969f6994a2631908bb2c0e69a7235648642f3d2e39a68"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"},
|
||||
|
|
|
@ -34,7 +34,8 @@ Pillow = "^8.2.0"
|
|||
pathvalidate = "^2.4.1"
|
||||
apprise = "^0.9.2"
|
||||
recipe-scrapers = "^13.2.7"
|
||||
psycopg2 = { version = "^2.8.6", optional = true }
|
||||
psycopg2-binary = {version = "^2.9.1", optional = true}
|
||||
gunicorn = "^20.1.0"
|
||||
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
@ -67,4 +68,4 @@ testpaths = [
|
|||
skip_empty = true
|
||||
|
||||
[tool.poetry.extras]
|
||||
pgsql = ["psycopg2"]
|
||||
pgsql = ["psycopg2-binary"]
|
Loading…
Reference in a new issue