diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index d11cc87e..a6ee8e44 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -34,16 +34,6 @@ on: workflow_dispatch: jobs: - v12: - uses: ./.github/workflows/docker-build-push.yml - with: - repo: erpnext - version: "12" - push: ${{ github.repository == 'frappe/frappe_docker' && github.event_name != 'pull_request' }} - secrets: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - v13: uses: ./.github/workflows/docker-build-push.yml with: diff --git a/custom_app/README.md b/custom_app/README.md index d11b55bf..07ada233 100644 --- a/custom_app/README.md +++ b/custom_app/README.md @@ -7,9 +7,9 @@ You can see that there's four files in this folder: - `docker-bake.hcl`, - `compose.override.yaml`. -Python code will `backend.Dockerfile`. JS and CSS (and other fancy frontend stuff) files will be built in `frontend.Dockerfile` if required and served from there. +Python code will be built in `backend.Dockerfile`. JS and CSS (and other fancy frontend stuff) files will be built in `frontend.Dockerfile`. -`docker-bake.hcl` is reference file for cool new [Buildx Bake](https://github.com/docker/buildx/blob/master/docs/reference/buildx_bake.md). It helps to build images without having to remember all build arguments. +`docker-bake.hcl` is reference file for [Buildx Bake](https://github.com/docker/buildx/blob/master/docs/reference/buildx_bake.md). It helps to build images without having to remember all build arguments. `compose.override.yaml` is [Compose](https://docs.docker.com/compose/compose-file/) override that replaces images from [main compose file](https://github.com/frappe/frappe_docker/blob/main/compose.yaml) so it would use your own images. @@ -21,7 +21,7 @@ Before the next step—to build images—replace "custom_app" with your app's na FRAPPE_VERSION=... ERPNEXT_VERSION=... docker buildx bake ``` -> 💡 We assume that majority of our users use ERPNext, that's why images in this tutorial are based on ERPNext images. If don't want ERPNext, change base image in Dockerfiles and remove ERPNEXT_VERSION from bake file. +> 💡 We assume that majority of our users use ERPNext, that's why images in this tutorial are based on ERPNext images. If don't want ERPNext, change base image in Dockerfile and remove ERPNEXT_VERSION from bake file. To know more about steps used to build frontend image read comments in `frontend.Dockerfile`. If something goes wrong feel free to leave an issue. @@ -41,6 +41,6 @@ Cool! You just containerized your app! ## Installing multiple apps -Both backend and frontend builds contain `install-app` script that places app where it should be. Each call to script installs given app. Usage: `install-app [APP_NAME]`. +Backend builds contain `install-app` script that places app where it should be. Each call to script installs given app. Usage: `install-app [APP_NAME]`. If you want to install an app from git, clone it locally, COPY in Dockerfile. diff --git a/custom_app/frontend.Dockerfile b/custom_app/frontend.Dockerfile index 205934c7..7b3c8473 100644 --- a/custom_app/frontend.Dockerfile +++ b/custom_app/frontend.Dockerfile @@ -1,13 +1,37 @@ -ARG FRAPPE_VERSION -ARG ERPNEXT_VERSION - -FROM frappe/assets-builder:${FRAPPE_VERSION} as assets +ARG FRAPPE_VERSION=version-14 +# Prepare builder image +FROM frappe/bench:latest as assets +ARG FRAPPE_VERSION=version-14 +ARG ERPNEXT_VERSION=version-14 ARG APP_NAME -COPY . apps/${APP_NAME} -RUN install-app ${APP_NAME} + +# Setup frappe-bench using FRAPPE_VERSION +RUN bench init --version=${FRAPPE_VERSION} --skip-redis-config-generation --verbose --skip-assets /home/frappe/frappe-bench +WORKDIR /home/frappe/frappe-bench + +# Comment following if ERPNext is not required +RUN bench get-app --branch=${ERPNEXT_VERSION} --skip-assets --resolve-deps erpnext + +# Copy custom app(s) +COPY --chown=frappe:frappe . apps/${APP_NAME} + +# Setup dependencies +RUN bench setup requirements + +# Build static assets, copy files instead of symlink +RUN bench build --production --verbose --hard-link -FROM frappe/erpnext-nginx:${ERPNEXT_VERSION} +# Use frappe-nginx image with nginx template and env vars +FROM frappe/frappe-nginx:${FRAPPE_VERSION} -COPY --from=assets /out /usr/share/nginx/html +# Remove existing assets +USER root +RUN rm -fr /usr/share/nginx/html/assets + +# Copy built assets +COPY --from=assets /home/frappe/frappe-bench/sites/assets /usr/share/nginx/html/assets + +# Use non-root user +USER 1000 diff --git a/docker-bake.hcl b/docker-bake.hcl index bf8eeca7..4196372d 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -45,7 +45,7 @@ target "bench-test" { # Base for all other targets group "frappe" { - targets = ["frappe-worker", "frappe-nginx", "frappe-socketio", "assets-builder"] + targets = ["frappe-worker", "frappe-nginx", "frappe-socketio"] } group "erpnext" { @@ -73,8 +73,7 @@ target "default-args" { BENCH_REPO = "${BENCH_REPO}" FRAPPE_VERSION = "${FRAPPE_VERSION}" ERPNEXT_VERSION = "${ERPNEXT_VERSION}" - # If `ERPNEXT_VERSION` variable contains "v12" use Python 3.7. If "v13" — 3.9. Else 3.10. - PYTHON_VERSION = can(regex("v12", "${ERPNEXT_VERSION}")) ? "3.7" : can(regex("v13", "${ERPNEXT_VERSION}")) ? "3.9" : "3.10" + PYTHON_VERSION = can(regex("v13", "${ERPNEXT_VERSION}")) ? "3.9" : "3.10" } } @@ -99,13 +98,6 @@ target "frappe-nginx" { tags = tag("frappe-nginx", "${FRAPPE_VERSION}") } -target "assets-builder" { - inherits = ["default-args"] - context = "images/nginx" - target = "assets_builder" - tags = tag("assets-builder", "${FRAPPE_VERSION}") -} - target "erpnext-nginx" { inherits = ["default-args"] context = "images/nginx" diff --git a/images/nginx/Dockerfile b/images/nginx/Dockerfile index eb4da5cc..bbbed49c 100644 --- a/images/nginx/Dockerfile +++ b/images/nginx/Dockerfile @@ -1,46 +1,30 @@ -FROM node:14-bullseye-slim as assets_builder - -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - git \ - build-essential \ - python \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /frappe-bench - -RUN mkdir -p sites/assets /out/assets \ - && echo frappe >sites/apps.txt +FROM frappe/bench:latest as assets_builder ARG FRAPPE_VERSION ARG FRAPPE_REPO=https://github.com/frappe/frappe -# Install development node modules -RUN git clone --depth 1 -b ${FRAPPE_VERSION} ${FRAPPE_REPO} apps/frappe \ - && yarn --cwd apps/frappe \ - # TODO: Currently `yarn run production` doesn't create .build on develop branch: https://github.com/frappe/frappe/issues/15396 - && if [ ! -f sites/.build ]; then touch sites/.build; fi \ - && cp sites/.build /out +RUN bench init --version=${FRAPPE_VERSION} --frappe-path=${FRAPPE_REPO} --skip-redis-config-generation --verbose --skip-assets /home/frappe/frappe-bench -COPY install-app.sh /usr/local/bin/install-app +WORKDIR /home/frappe/frappe-bench FROM assets_builder as frappe_assets -RUN install-app frappe +RUN bench setup requirements \ + && if [ -z "${FRAPPE_VERSION##*v14*}" ] || [ "$FRAPPE_VERSION" = "develop" ]; then \ + export BUILD_OPTS="--production";\ + fi \ + && FRAPPE_ENV=production bench build --verbose --hard-link ${BUILD_OPTS} FROM assets_builder as erpnext_assets -ARG PAYMENTS_VERSION=develop -ARG PAYMENTS_REPO=https://github.com/frappe/payments ARG ERPNEXT_VERSION ARG ERPNEXT_REPO=https://github.com/frappe/erpnext -RUN if [ -z "${ERPNEXT_VERSION##*v14*}" ] || [ "$ERPNEXT_VERSION" = "develop" ]; then \ - git clone --depth 1 -b ${PAYMENTS_VERSION} ${PAYMENTS_REPO} apps/payments && install-app payments; \ +RUN bench get-app --branch=${ERPNEXT_VERSION} --skip-assets --resolve-deps erpnext ${ERPNEXT_REPO}\ + && if [ -z "${ERPNEXT_VERSION##*v14*}" ] || [ "$ERPNEXT_VERSION" = "develop" ]; then \ + export BUILD_OPTS="--production"; \ fi \ - && git clone --depth 1 -b ${ERPNEXT_VERSION} ${ERPNEXT_REPO} apps/erpnext \ - && install-app erpnext + && FRAPPE_ENV=production bench build --verbose --hard-link ${BUILD_OPTS} FROM alpine/git as bench @@ -49,8 +33,8 @@ FROM alpine/git as bench ARG BENCH_REPO=https://github.com/frappe/bench RUN git clone --depth 1 ${BENCH_REPO} /tmp/bench \ && mkdir /out \ - && mv /tmp/bench/bench/config/templates/502.html /out/ - + && mv /tmp/bench/bench/config/templates/502.html /out \ + && touch /out/.build FROM nginxinc/nginx-unprivileged:1.23.1-alpine as frappe @@ -60,11 +44,11 @@ COPY nginx-template.conf /etc/nginx/templates/default.conf.template COPY entrypoint.sh /docker-entrypoint.d/frappe-entrypoint.sh COPY --from=bench /out /usr/share/nginx/html/ -COPY --from=frappe_assets /out /usr/share/nginx/html +COPY --from=frappe_assets /home/frappe/frappe-bench/sites/assets /usr/share/nginx/html/assets USER 1000 FROM frappe as erpnext -COPY --from=erpnext_assets /out /usr/share/nginx/html +COPY --from=erpnext_assets /home/frappe/frappe-bench/sites/assets /usr/share/nginx/html/assets diff --git a/images/nginx/install-app.sh b/images/nginx/install-app.sh deleted file mode 100755 index 4d634cf6..00000000 --- a/images/nginx/install-app.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -set -e -set -x - -APP=$1 - -cleanup() { - rm -rf "apps/$APP" - rm -rf sites/assets/* -} - -cd /frappe-bench - -if ! test -d "apps/$APP/$APP/public"; then - cleanup - exit 0 -fi - -# Add all not built assets -cp -r "apps/$APP/$APP/public" "/out/assets/$APP" - -# Add production node modules -yarn --cwd "apps/$APP" --prod -cp -r "apps/$APP/node_modules" "/out/assets/$APP/node_modules" - -# Add built assets -yarn --cwd "apps/$APP" -echo "$APP" >>sites/apps.txt -yarn --cwd apps/frappe run production --app "$APP" -cp -r sites/assets /out - -cleanup