From 19aa572bd8a169371103f3b11f28169bfd09cee9 Mon Sep 17 00:00:00 2001 From: Usman Masood <355154+usma0118@users.noreply.github.com> Date: Sat, 2 Oct 2021 21:35:16 +0200 Subject: [PATCH] Docker/run as nonroot (#692) * changed python base image to 3.9.6 * bumped poetry version to 1.1.7 * user creation based on env variable PGID and PUID with default as PUID/PGID= 911 * App exposes APP_PORT=80 as env variable * Removed user mod and handled it in docker image. * moved scheduler.db to /app/temp dir * set app default port to 80 if envvariable null * Changed application port to env variable with default as 80 * Created sch. direcotry as part of image creation * minor logging improvements. * removed docker target * cleanup * fixed port * fixed port * fixed port * removed volume specification * fixing code quality warnings * fixing code quality warnings * fixing code quality warnings * bumped versions to fix vulnerabilities * corrected port * bumped uvicorn version to fix vulnerabilities * minor fix * added sticky permissions * adding port change info to docs * adding port change info to docs * adding port change info to docs * improved formatting * docs updated * added docker port change warning --- Caddyfile | 3 +- Dockerfile | 28 +++++++++++++------ docker-compose.yml | 2 +- .../documentation/getting-started/install.md | 11 +++++--- mealie/core/config.py | 5 ++-- mealie/run.sh | 23 +++------------ pyproject.toml | 6 ++-- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Caddyfile b/Caddyfile index 9e08f53c869b..bf312cbad13c 100644 --- a/Caddyfile +++ b/Caddyfile @@ -2,8 +2,7 @@ auto_https off admin off } - -:80 { +:{$APP_PORT} { @proxied path /api/* /docs /openapi.json @static { diff --git a/Dockerfile b/Dockerfile index 9e9088a01efd..144fa85bfe89 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN npm run build ############################################### # Base Image ############################################### -FROM python:3.9-slim as python-base +FROM python:3.9.6-slim as python-base ENV MEALIE_HOME="/app" @@ -29,9 +29,12 @@ ENV PYTHONUNBUFFERED=1 \ # prepend poetry and venv to path ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH" -# create user account -RUN useradd -u 911 -U -d $MEALIE_HOME -s /bin/bash abc \ - && usermod -G users abc \ +ENV PUID=911 \ + PGID=911 + +# create user account with default group +RUN groupadd -g $PGID mealie \ + && useradd -l -u $PUID -g $PGID -d $MEALIE_HOME -s /bin/bash mealie \ && mkdir $MEALIE_HOME ############################################### @@ -56,7 +59,7 @@ RUN apt-get update \ && pip install -U --no-cache-dir pip # install poetry - respects $POETRY_VERSION & $POETRY_HOME -ENV POETRY_VERSION=1.1.6 +ENV POETRY_VERSION=1.1.7 RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python - # copy project requirement files here to ensure they will be cached. @@ -96,6 +99,7 @@ ENTRYPOINT $MEALIE_HOME/mealie/run.sh "reload" ############################################### FROM python-base as production ENV PRODUCTION=true +ARG DEBIAN_FRONTEND=noninteractive # curl for used by healthcheck RUN apt-get update \ @@ -129,12 +133,20 @@ COPY --from=frontend-build /app/dist $MEALIE_HOME/dist COPY ./dev/data/templates $MEALIE_HOME/data/templates COPY ./Caddyfile $MEALIE_HOME +RUN mkdir $MEALIE_HOME/temp \ +&& id -u mealie | xargs -I{} chown -R {}:{} $MEALIE_HOME +USER $PUID:$PGID VOLUME [ "$MEALIE_HOME/data/" ] -ENV APP_PORT=80 +RUN chmod 755 "$MEALIE_HOME/data/" \ +&& chmod g+s "$MEALIE_HOME/data/" + +WORKDIR /app + +ENV APP_PORT=9080 EXPOSE ${APP_PORT} HEALTHCHECK CMD curl -fs http://localhost:${APP_PORT} || exit 1 -RUN chmod +x $MEALIE_HOME/mealie/run.sh -ENTRYPOINT $MEALIE_HOME/mealie/run.sh +RUN chmod +x mealie/run.sh +ENTRYPOINT mealie/run.sh diff --git a/docker-compose.yml b/docker-compose.yml index 4d48fe0682c7..f17cdec4c28c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: depends_on: - "postgres" ports: - - 9090:80 + - 9090:9080 environment: DB_ENGINE: postgres # Optional: 'sqlite', 'postgres' POSTGRES_USER: mealie diff --git a/docs/docs/documentation/getting-started/install.md b/docs/docs/documentation/getting-started/install.md index 6ebedf2a9eb0..d9ad621edee0 100644 --- a/docs/docs/documentation/getting-started/install.md +++ b/docs/docs/documentation/getting-started/install.md @@ -2,6 +2,9 @@ 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. +**Latest release has changed container port binding from port 80 to 9080, for existing container based installations, please change exposed port or service binindg accordingly** + + [Get Docker](https://docs.docker.com/get-docker/) [Mealie on Dockerhub](https://hub.docker.com/r/hkotel/mealie) @@ -116,8 +119,10 @@ services: | Variables | Default | Description | | ----------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| PUID | 911 | UserID permissions between host OS and container | -| PGID | 911 | GroupID permissions between host OS and container | +| APP_PORT | Default: 80 | Web app port binding/listening. **For Docker this is set to 9080 (Binding without elevated permissions)**. | +| API_PORT | 9000 | The port exposed by backend API. **Do not change this if you're running in Docker** | +| PUID | 911 | UserID permissions between host OS and container. **This ensures cotnainer will run as non-root** | +| PGID | 911 | GroupID permissions between host OS and container. **This ensures cotnainer will run as non-root** | | 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 | @@ -134,14 +139,12 @@ services: | RECIPE_LANDSCAPE_VIEW | True | Default Recipe Settings - Set Landscape View | | RECIPE_DISABLE_COMMENTS | False | Default Recipe Settings - Disable Comments | | RECIPE_DISABLE_AMOUNT | False | Default Recipe Settings - Disable Amount | -| 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" diff --git a/mealie/core/config.py b/mealie/core/config.py index 45a23fe37c9c..a99fb931b54b 100644 --- a/mealie/core/config.py +++ b/mealie/core/config.py @@ -59,6 +59,7 @@ class AppDirectories: self.USER_DIR: Path = data_dir.joinpath("users") self.RECIPE_DATA_DIR: Path = data_dir.joinpath("recipes") self.TEMP_DIR: Path = data_dir.joinpath(".temp") + self.SCHEDULER_DIR: Path = Path("/app/temp") self.ensure_directories() @@ -95,7 +96,7 @@ def determine_sqlite_path(path=False, suffix=DB_VERSION) -> str: class AppSettings(BaseSettings): global DATA_DIR PRODUCTION: bool = Field(True, env="PRODUCTION") - BASE_URL: str = "http://localhost:8080" + BASE_URL: str = "http://localhost:{}".format(os.getenv("APP_PORT")) IS_DEMO: bool = False API_PORT: int = 9000 API_DOCS: bool = True @@ -151,7 +152,7 @@ class AppSettings(BaseSettings): DEFAULT_EMAIL: str = "changeme@email.com" DEFAULT_PASSWORD: str = "MyPassword" - SCHEDULER_DATABASE = f"sqlite:///{app_dirs.DATA_DIR.joinpath('scheduler.db')}" + SCHEDULER_DATABASE = f"sqlite:///{app_dirs.SCHEDULER_DIR.joinpath('scheduler.db')}" TOKEN_TIME: int = 2 # Time in Hours diff --git a/mealie/run.sh b/mealie/run.sh index 935c38369cf4..90716097ce41 100755 --- a/mealie/run.sh +++ b/mealie/run.sh @@ -5,21 +5,6 @@ set -e # Get Reload Arg `run.sh reload` for dev server ARG1=${1:-production} -# 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 @@ -44,11 +29,11 @@ if [ "$ARG1" == "reload" ]; then # Start API python /app/mealie/app.py else - echo "Production" - - add_user + if [[ -z "$APP_PORT" ]];then + export APP_PORT=80 + fi + echo "Running in Production env as $(whoami) with id $(id -u) on port $APP_PORT" init - # Web Server caddy start --config /app/Caddyfile diff --git a/pyproject.toml b/pyproject.toml index 2f02353ce59a..5561199a87a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,8 +13,8 @@ python = "^3.9" aiofiles = "0.5.0" aniso8601 = "7.0.0" appdirs = "1.4.4" -fastapi = "^0.63.0" -uvicorn = {extras = ["standard"], version = "^0.13.0"} +fastapi = "^0.65.2" +uvicorn = {extras = ["standard"], version = "^0.15.0"} APScheduler = "^3.6.3" SQLAlchemy = "^1.3.22" Jinja2 = "^2.11.2" @@ -29,7 +29,7 @@ fastapi-camelcase = "^1.0.2" bcrypt = "^3.2.0" python-jose = "^3.3.0" passlib = "^1.7.4" -lxml = "4.6.2" +lxml = "4.6.3" Pillow = "^8.2.0" pathvalidate = "^2.4.1" apprise = "0.9.3"