mealie: port container from Dockerfile to Nix (default.nix)
Wrap nixpkgs mealie in dockerTools.buildLayeredImage, replacing the Node+Python Dockerfile build. nixpkgs ships a single `mealie` gunicorn entrypoint serving the prebuilt frontend, so this is a clean single- process wrap; the run wrapper mirrors the NixOS module (init_db Alembic migrations, then gunicorn). DB stays SQLite on the mealie-data PVC. Self-pins nixos-unstable (stable lags at 3.9.2) for mealie 3.16.0 -- a forward 4-minor bump from v3.12.0 (the previously-deferred upgrade). Breaking-change review v3.13-v3.16: no schema breaks, SQLite auto-migrates forward; remaining changes minor (see service-versions.yaml notes). Source PVC retained for rollback. Build verified on ringtail (exit 0, assert ok). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
43047423c4
commit
4dbd93c4fc
3 changed files with 76 additions and 151 deletions
|
|
@ -1,145 +0,0 @@
|
|||
# Mealie — self-hosted recipe manager
|
||||
# Built from source via forge mirror of mealie-recipes/mealie
|
||||
# Based on upstream docker/Dockerfile (multi-stage: Node frontend + Python backend)
|
||||
|
||||
ARG CONTAINER_APP_VERSION=v3.12.0
|
||||
|
||||
###############################################
|
||||
# Frontend Build
|
||||
###############################################
|
||||
FROM node:24-slim AS frontend-builder
|
||||
|
||||
ARG CONTAINER_APP_VERSION
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y git ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN git clone --depth 1 --branch ${CONTAINER_APP_VERSION} \
|
||||
https://forge.ops.eblu.me/mirrors/mealie.git /src
|
||||
|
||||
WORKDIR /src/frontend
|
||||
|
||||
RUN yarn install \
|
||||
--prefer-offline \
|
||||
--frozen-lockfile \
|
||||
--non-interactive \
|
||||
--production=false \
|
||||
--network-timeout 1000000
|
||||
|
||||
RUN yarn generate
|
||||
|
||||
###############################################
|
||||
# Python Base
|
||||
###############################################
|
||||
FROM python:3.12-slim AS python-base
|
||||
|
||||
ENV MEALIE_HOME="/app"
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
PIP_NO_CACHE_DIR=off \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=on \
|
||||
PIP_DEFAULT_TIMEOUT=100 \
|
||||
VENV_PATH="/opt/mealie"
|
||||
|
||||
ENV PATH="$VENV_PATH/bin:$PATH"
|
||||
|
||||
RUN useradd -u 911 -U -d $MEALIE_HOME -s /bin/bash abc \
|
||||
&& usermod -G users abc \
|
||||
&& mkdir $MEALIE_HOME
|
||||
|
||||
###############################################
|
||||
# Backend Package Build
|
||||
###############################################
|
||||
FROM python-base AS backend-builder
|
||||
|
||||
ARG CONTAINER_APP_VERSION
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y curl git ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pip install uv
|
||||
|
||||
RUN git clone --depth 1 --branch ${CONTAINER_APP_VERSION} \
|
||||
https://forge.ops.eblu.me/mirrors/mealie.git /src
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY --from=frontend-builder /src/frontend/dist ./mealie/frontend
|
||||
|
||||
RUN uv build --out-dir dist
|
||||
|
||||
RUN uv export --no-editable --no-emit-project --extra pgsql --format requirements-txt --output-file dist/requirements.txt \
|
||||
&& MEALIE_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])") \
|
||||
&& echo "mealie[pgsql]==${MEALIE_VERSION} \\" >> dist/requirements.txt \
|
||||
&& pip hash dist/mealie-${MEALIE_VERSION}-py3-none-any.whl | tail -n1 | tr -d '\n' >> dist/requirements.txt \
|
||||
&& echo " \\" >> dist/requirements.txt \
|
||||
&& pip hash dist/mealie-${MEALIE_VERSION}.tar.gz | tail -n1 >> dist/requirements.txt
|
||||
|
||||
###############################################
|
||||
# Python Venv Build
|
||||
###############################################
|
||||
FROM python-base AS venv-builder
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
build-essential \
|
||||
libpq-dev \
|
||||
libwebp-dev \
|
||||
ffmpeg \
|
||||
libsasl2-dev libldap2-dev libssl-dev \
|
||||
gnupg gnupg2 gnupg1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN python3 -m venv --upgrade-deps $VENV_PATH
|
||||
|
||||
COPY --from=backend-builder /src/dist /dist
|
||||
|
||||
RUN . $VENV_PATH/bin/activate \
|
||||
&& pip install --require-hashes -r /dist/requirements.txt --find-links /dist
|
||||
|
||||
###############################################
|
||||
# Production Image
|
||||
###############################################
|
||||
FROM python-base AS production
|
||||
|
||||
ENV PRODUCTION=true
|
||||
ENV TESTING=false
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
curl \
|
||||
ffmpeg \
|
||||
gosu \
|
||||
iproute2 \
|
||||
libldap-common \
|
||||
libldap2 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN mkdir -p /run/secrets
|
||||
|
||||
COPY --from=venv-builder $VENV_PATH $VENV_PATH
|
||||
|
||||
ENV NLTK_DATA="/nltk_data/"
|
||||
RUN mkdir -p $NLTK_DATA
|
||||
RUN python -m nltk.downloader -d $NLTK_DATA averaged_perceptron_tagger_eng
|
||||
|
||||
VOLUME ["$MEALIE_HOME/data/"]
|
||||
ENV APP_PORT=9000
|
||||
|
||||
EXPOSE ${APP_PORT}
|
||||
|
||||
COPY --from=backend-builder /src/docker/healthcheck.sh $MEALIE_HOME/healthcheck.sh
|
||||
RUN chmod +x $MEALIE_HOME/healthcheck.sh
|
||||
HEALTHCHECK CMD $MEALIE_HOME/healthcheck.sh
|
||||
|
||||
ENV HOST=0.0.0.0
|
||||
|
||||
COPY --from=backend-builder /src/docker/entry.sh $MEALIE_HOME/run.sh
|
||||
RUN chmod +x $MEALIE_HOME/run.sh
|
||||
|
||||
ARG CONTAINER_APP_VERSION
|
||||
LABEL org.opencontainers.image.title="Mealie"
|
||||
LABEL org.opencontainers.image.description="Self-hosted recipe manager"
|
||||
LABEL org.opencontainers.image.version="${CONTAINER_APP_VERSION}"
|
||||
LABEL org.opencontainers.image.source="https://forge.eblu.me/eblume/blumeops"
|
||||
LABEL org.opencontainers.image.vendor="blumeops"
|
||||
|
||||
ENTRYPOINT ["/app/run.sh"]
|
||||
65
containers/mealie/default.nix
Normal file
65
containers/mealie/default.nix
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Nix-built Mealie for ringtail (amd64).
|
||||
#
|
||||
# Replaces the from-source Dockerfile build (Node frontend + Python venv)
|
||||
# with nixpkgs' mealie, which ships a single `mealie` gunicorn entrypoint
|
||||
# serving the prebuilt frontend + backend — so this is a clean single-
|
||||
# process wrap (unlike paperless, which is multi-process).
|
||||
#
|
||||
# Mealie stores its DB as SQLite under DATA_DIR (the mealie-data PVC at
|
||||
# /app/data); there is no postgres. The run wrapper mirrors the nixpkgs
|
||||
# mealie NixOS module: run `libexec/init_db` (Alembic migrations) first,
|
||||
# then exec gunicorn.
|
||||
#
|
||||
# Self-pins nixos-unstable: stable nixpkgs lags at 3.9.2, unstable carries
|
||||
# 3.16.0. This is a forward 4-minor bump from the v3.12.0 Dockerfile build
|
||||
# (the deferred upgrade) — mealie auto-migrates the SQLite DB forward on
|
||||
# startup via init_db; the source PVC is retained for rollback. The version
|
||||
# assertion makes nix-build fail if a pin bump changes the version.
|
||||
let
|
||||
nixpkgs = fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/331800de5053fcebacf6813adb5db9c9dca22a0c.tar.gz";
|
||||
sha256 = "1p54fm6dkbq62kpi55cr4wyx7b1nsajpsnjgs64cmp073fwi15f7";
|
||||
};
|
||||
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||
|
||||
version = "3.16.0";
|
||||
|
||||
app = pkgs.mealie;
|
||||
|
||||
# Mirror the NixOS module's mealie service: init_db (Alembic) then
|
||||
# gunicorn bound to the app port. DATA_DIR/env come from the image +
|
||||
# k8s manifest.
|
||||
mealie-run = pkgs.writeShellScriptBin "mealie-run" ''
|
||||
set -e
|
||||
${app}/libexec/init_db
|
||||
exec ${pkgs.lib.getExe app} -b 0.0.0.0:9000
|
||||
'';
|
||||
in
|
||||
|
||||
assert app.version == version;
|
||||
|
||||
pkgs.dockerTools.buildLayeredImage {
|
||||
name = "blumeops/mealie";
|
||||
|
||||
contents = [
|
||||
app
|
||||
mealie-run
|
||||
pkgs.bashInteractive
|
||||
pkgs.coreutils
|
||||
pkgs.cacert
|
||||
pkgs.tzdata
|
||||
];
|
||||
|
||||
config = {
|
||||
Cmd = [ "${mealie-run}/bin/mealie-run" ];
|
||||
Env = [
|
||||
"DATA_DIR=/app/data"
|
||||
"SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
|
||||
"PYTHONUNBUFFERED=1"
|
||||
"PRODUCTION=true"
|
||||
];
|
||||
ExposedPorts = {
|
||||
"9000/tcp" = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -328,14 +328,19 @@ services:
|
|||
|
||||
- name: mealie
|
||||
type: argocd
|
||||
last-reviewed: 2026-05-11
|
||||
current-version: "v3.12.0"
|
||||
last-reviewed: "2026-06-03"
|
||||
current-version: "v3.16.0"
|
||||
upstream-source: https://github.com/mealie-recipes/mealie/releases
|
||||
notes: >-
|
||||
Recipe manager; built from source via forge mirror.
|
||||
Upstream is at v3.17.0 as of 2026-05-11 (5 minor versions ahead).
|
||||
Container/manifest still pinned to v3.12.0 — upgrade deferred to a
|
||||
separate task (build new image, review changelog for breaking changes).
|
||||
Recipe manager. Container ported from Dockerfile to Nix
|
||||
(containers/mealie/default.nix wraps nixpkgs mealie from a pinned
|
||||
nixos-unstable; single gunicorn process, SQLite on the mealie-data
|
||||
PVC). Bumped v3.12.0 -> v3.16.0 as part of the port (the deferred
|
||||
upgrade). Breaking-change review v3.13-v3.16: no schema breaking
|
||||
changes, SQLite auto-migrates forward via init_db; notable items are
|
||||
minor (OIDC missing-claims log -> DEBUG, NLP parser uses user-defined
|
||||
units, Nuxt 3->4 frontend, new Announcements feature, path-traversal
|
||||
patches). Source PVC retained for rollback. Build verified on ringtail.
|
||||
|
||||
- name: paperless
|
||||
type: argocd
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue