diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index be96444..03c8099 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -33,7 +33,7 @@ jobs: name: 'app-clash' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && build_image app-clash latest docker_clash/clash.Dockerfile && push_image clash @@ -42,7 +42,7 @@ jobs: name: 'casdoor' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && build_image casdoor latest docker_casdoor/casdoor.Dockerfile && push_image casdoor @@ -51,7 +51,7 @@ jobs: name: 'keycloak' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && build_image keycloak latest docker_keycloak/keycloak.Dockerfile && push_image keycloak @@ -60,7 +60,7 @@ jobs: name: 'dev-hub' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh build_image dev-hub latest docker_devbox/hub.Dockerfile \ @@ -73,7 +73,7 @@ jobs: name: 'openresty' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && build_image openresty latest docker_openresty/openresty.Dockerfile && push_image openresty @@ -82,7 +82,7 @@ jobs: name: 'searxng' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && build_image searxng latest docker_searxng/searxng.Dockerfile && push_image searxng @@ -91,7 +91,7 @@ jobs: name: 'storebox' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh build_image storebox latest docker_storebox/storebox.Dockerfile && push_image storebox @@ -101,18 +101,28 @@ jobs: name: 'logent' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh build_image logent latest docker_logent/logent.Dockerfile && push_image logent + ## nocobase for low-code development platform + job-nocobase: + name: 'nocobase' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - run: | + source ./tool.sh + build_image nocobase latest docker_nocobase/nocobase.Dockerfile && push_image nocobase + ## DevBox - base job-base-dev: name: 'developer,base-dev' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && free_diskspace build_image base-dev latest docker_devbox/dev.Dockerfile \ @@ -126,7 +136,7 @@ jobs: name: 'data-science-dev' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && free_diskspace build_image data-science-dev latest docker_devbox/dev.Dockerfile \ @@ -141,7 +151,7 @@ jobs: name: 'full-stack-dev' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && free_diskspace build_image full-stack-dev latest docker_devbox/dev.Dockerfile \ @@ -156,7 +166,7 @@ jobs: name: 'full-cuda,cuda-dev' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: | source ./tool.sh && free_diskspace build_image cuda-dev latest docker_devbox/dev.Dockerfile \ @@ -168,10 +178,10 @@ jobs: ## Sync all images in this build (listed by "names") to mirror registry. sync_images: - needs: ["job-cuda-dev", "job-data-science-dev", "job-full-stack-dev"] + needs: ["job-cuda-dev", "job-data-science-dev", "job-full-stack-dev", "job-base-dev", "job-nocobase", "job-logent", "job-storebox", "job-searxng", "job-openresty", "job-dev-hub", "docker_keycloak", "docker_casdoor", "docker_clash"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - env: AUTH_FILE_CONTENT: ${{ secrets.AUTH_FILE_CONTENT }} DOCKER_MIRROR_REGISTRY: ${{ vars.DOCKER_MIRROR_REGISTRY }} diff --git a/docker_casdoor/casdoor.Dockerfile b/docker_casdoor/casdoor.Dockerfile index d4626a6..463b1e5 100644 --- a/docker_casdoor/casdoor.Dockerfile +++ b/docker_casdoor/casdoor.Dockerfile @@ -28,11 +28,13 @@ RUN set -eux \ LABEL maintainer="postmaster@labnow.ai" ENV RUNNING_IN_DOCKER=true -WORKDIR /opt/casdoor # 8000=web, 389=ldap, 1812=radius EXPOSE 8000 389 1812 ENTRYPOINT ["/bin/bash"] CMD ["/opt/casdoor/docker-entrypoint.sh"] +WORKDIR /opt/casdoor +# https://casdoor.org/zh/docs/provider/storage/localFileSystem/ +VOLUME [ "/opt/casdoor/files" ] HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD ["curl", "--head", "-fsSk", "http://localhost:8000/health/ready"] diff --git a/docker_logent/logent.Dockerfile b/docker_logent/logent.Dockerfile index 5fe1c88..d4992dd 100644 --- a/docker_logent/logent.Dockerfile +++ b/docker_logent/logent.Dockerfile @@ -5,6 +5,8 @@ ARG BASE_IMG="atom" FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG} +LABEL maintainer="postmaster@labnow.ai" + COPY work /opt/utils RUN set -eux \ diff --git a/docker_nocobase/nocobase.Dockerfile b/docker_nocobase/nocobase.Dockerfile new file mode 100644 index 0000000..79ecf71 --- /dev/null +++ b/docker_nocobase/nocobase.Dockerfile @@ -0,0 +1,45 @@ +# Distributed under the terms of the Modified BSD License. + +ARG BASE_NAMESPACE +ARG BASE_IMG="atom" + +FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG} + +COPY work /opt/utils + +RUN set -eux \ + && apt-get -qq update -yq --fix-missing && apt-get -qq install -yq --no-install-recommends \ + git jq libaio1t64 libgssapi-krb5-2 \ + libfreetype6 fontconfig fonts-liberation fonts-noto-cjk \ + ## ----------------------------- Install postgresql client + && source /opt/utils/script-setup-db-clients.sh && setup_postgresql_client \ + ## ----------------------------- Install supervisord + ## && source /opt/utils/script-setup-sys.sh && setup_supervisord \ + ## ----------------------------- Install caddy + ## && source /opt/utils/script-setup-net.sh && setup_caddy \ + ## ----------------------------- Install dependencies and build + && source /opt/utils/script-setup.sh && setup_node_base 20 && source /etc/profile.d/path-*.sh \ + && npm install -g yarn \ + && source /opt/utils/script-setup-nocobase.sh \ + && cd /opt && setup_nocobase_create_app \ + && mv /opt/utils/docker-entrypoint.sh /opt/nocobase/ \ + && chmod +x /opt/nocobase/*.sh \ + && ls -alh \ + # Clean up and display components version information... + && find ./node_modules -type f \( -name "README.md" -o -name "License" \) -delete 2>/dev/null \ + && find ./node_modules -type d \( -name "test" -o -name "tests" -o -name "__tests__" -o -name "docs" -o -name "doc" \) -exec rm -rf {} + 2>/dev/null \ + && list_installed_packages && install__clean + +LABEL maintainer="postmaster@labnow.ai" +EXPOSE 13000 +WORKDIR /opt/nocobase +VOLUME [ "/opt/nocobase/storage" ] + +# '-c' option make bash commands are read from string. +# If there are arguments after the string, they are assigned to the positional parameters, starting with $0. +# '-o pipefail' prevents errors in a pipeline from being masked. +# If any command in a pipeline fails, that return code will be used as the return code of the whole pipeline. +# '--login': make bash first reads and executes commands from the file /etc/profile, if that file exists. +# After that, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. +SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"] +CMD [ "/opt/nocobase/docker-entrypoint.sh" ] diff --git a/docker_nocobase/work/docker-entrypoint.sh b/docker_nocobase/work/docker-entrypoint.sh new file mode 100755 index 0000000..0b0a393 --- /dev/null +++ b/docker_nocobase/work/docker-entrypoint.sh @@ -0,0 +1,14 @@ +#! /usr/bin/env bash + +# run scripts in storage/scripts +if [ -d "/opt/nocobase/storage/scripts" ]; then + for f in /opt/nocobase/storage/scripts/*.sh; do + [ -e "$f" ] || continue + echo "Running $f" + sh "$f" + done +fi + +source /etc/profile.d/path-*.sh + +cd /opt/nocobase && yarn nocobase install --lang=${LOCALE:-"zh-CN"} && yarn start --quickstart diff --git a/docker_nocobase/work/script-setup-nocobase.sh b/docker_nocobase/work/script-setup-nocobase.sh new file mode 100755 index 0000000..41d9306 --- /dev/null +++ b/docker_nocobase/work/script-setup-nocobase.sh @@ -0,0 +1,19 @@ +setup_nocobase_create_app(){ + local VER_NOCO=${1:-"latest"} \ + && npx -y create-nocobase-app@${VER_NOCO} nocobase --empty-key --skip-dev-dependencies -a -e APP_ENV=production \ + && cd nocobase \ + && yarn install --production \ + && rm -rf yarn.lock \ + && find node_modules -type f -name "yarn.lock" -delete \ + && find node_modules -type f -name "bower.json" -delete \ + && find node_modules -type f -name "composer.json" -delete ; +} + +setup_nocobase_from_source(){ + local BRANCH_NOCO=${1:-"origin/main"} \ + && cd /opt/nocobase \ + && git config --global --add safe.directory /opt/nocobase \ + && git init && git remote add origin https://github.com/nocobase/nocobase \ + && git fetch && git checkout -t $BRANCH_NOCO \ + && yarn install --frozen-lockfile && yarn run build --not-dts ; +} diff --git a/docker_searxng/searxng.Dockerfile b/docker_searxng/searxng.Dockerfile index 63e6631..8339bc6 100644 --- a/docker_searxng/searxng.Dockerfile +++ b/docker_searxng/searxng.Dockerfile @@ -5,6 +5,8 @@ ARG BASE_IMG="base" FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG} +LABEL maintainer="postmaster@labnow.ai" + COPY work /tmp/searxng RUN set -eux \ @@ -51,6 +53,6 @@ ENTRYPOINT ["tini", "-g", "--"] # '--login': make bash first reads and executes commands from the file /etc/profile, if that file exists. # After that, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"] -WORKDIR /opt/searxng CMD ["/opt/searxng/start-supervisord.sh"] EXPOSE 8080 9001 8000 +WORKDIR /opt/searxng diff --git a/tool.sh b/tool.sh index 12114bf..804a990 100644 --- a/tool.sh +++ b/tool.sh @@ -5,13 +5,10 @@ CI_PROJECT_NAME=${CI_PROJECT_NAME:-$GITHUB_REPOSITORY} CI_PROJECT_BRANCH=${GITHUB_HEAD_REF:-"main"} CI_PROJECT_SPACE=$(echo "${CI_PROJECT_BRANCH}" | cut -f1 -d'/') -if [ "${CI_PROJECT_BRANCH}" = "main" ] ; then - # If on the main branch, docker images namespace will be same as CI_PROJECT_NAME's name space - export CI_PROJECT_NAMESPACE="$(dirname ${CI_PROJECT_NAME})" ; -else - # not main branch, docker namespace = {CI_PROJECT_NAME's name space} + "0" + {1st substr before / in CI_PROJECT_SPACE} - export CI_PROJECT_NAMESPACE="$(dirname ${CI_PROJECT_NAME})0${CI_PROJECT_SPACE}" ; -fi +# If on the main branch, image namespace will be same as CI_PROJECT_NAME's name space; +# else (not main branch), image namespace = {CI_PROJECT_NAME's name space} + "0" + {1st substr before / in CI_PROJECT_SPACE}. +[ "${CI_PROJECT_BRANCH}" = "main" ] && NAMESPACE_SUFFIX="" || NAMESPACE_SUFFIX="0${CI_PROJECT_SPACE}" ; +export CI_PROJECT_NAMESPACE="$(dirname ${CI_PROJECT_NAME})${NAMESPACE_SUFFIX}" ; export IMG_NAMESPACE=$(echo "${CI_PROJECT_NAMESPACE}" | awk '{print tolower($0)}') export IMG_PREFIX_SRC=$(echo "${REGISTRY_SRC:-"docker.io"}/${IMG_NAMESPACE}" | awk '{print tolower($0)}') @@ -24,41 +21,41 @@ echo "--------> DOCKER_IMG_PREFIX_SRC=${IMG_PREFIX_SRC}" echo "--------> DOCKER_IMG_PREFIX_DST=${IMG_PREFIX_DST}" echo "--------> DOCKER_TAG_SUFFIX=${TAG_SUFFIX}" -[ ! -f /etc/docker/daemon.json ] && sudo tee /etc/docker/daemon.json > /dev/null <<< '{}' -jq '.experimental=true | ."data-root"="/mnt/docker"' /etc/docker/daemon.json > /tmp/daemon.json && sudo mv /tmp/daemon.json /etc/docker/ -( sudo service docker restart || true ) && cat /etc/docker/daemon.json && docker info build_image() { echo "$@" ; IMG=$1; TAG=$2; FILE=$3; shift 3; VER=$(date +%Y.%m%d.%H%M)${TAG_SUFFIX}; WORKDIR="$(dirname $FILE)"; - docker build --compress --force-rm=true -t "${IMG_PREFIX_DST}/${IMG}:${TAG}" -f "$FILE" --build-arg "BASE_NAMESPACE=${IMG_PREFIX_SRC}" "$@" "${WORKDIR}" ; - docker tag "${IMG_PREFIX_DST}/${IMG}:${TAG}" "${IMG_PREFIX_DST}/${IMG}:${VER}" ; + docker build --compress --force-rm=true -t "${IMG_PREFIX_DST}/${IMG}:${TAG}" -f "$FILE" --build-arg "BASE_NAMESPACE=${IMG_PREFIX_SRC}" "$@" "${WORKDIR}" >&2 + docker tag "${IMG_PREFIX_DST}/${IMG}:${TAG}" "${IMG_PREFIX_DST}/${IMG}:${VER}" >&2 + echo "${IMG_PREFIX_DST}/${IMG}:${TAG}" } build_image_no_tag() { echo "$@" ; IMG=$1; TAG=$2; FILE=$3; shift 3; WORKDIR="$(dirname $FILE)"; - docker build --compress --force-rm=true -t "${IMG_PREFIX_DST}/${IMG}:${TAG}" -f "$FILE" --build-arg "BASE_NAMESPACE=${IMG_PREFIX_SRC}" "$@" "${WORKDIR}" ; + docker build --compress --force-rm=true -t "${IMG_PREFIX_DST}/${IMG}:${TAG}" -f "$FILE" --build-arg "BASE_NAMESPACE=${IMG_PREFIX_SRC}" "$@" "${WORKDIR}" >&2 + echo "${IMG_PREFIX_DST}/${IMG}:${TAG}" } build_image_common() { echo "$@" ; IMG=$1; TAG=$2; FILE=$3; shift 3; VER=$(date +%Y.%m%d.%H%M)${TAG_SUFFIX}; WORKDIR="$(dirname $FILE)"; - docker build --compress --force-rm=true -t "${IMG_PREFIX_DST}/${IMG}:${TAG}" -f "$FILE" --build-arg "BASE_NAMESPACE=${IMG_PREFIX_SRC}" "$@" "${WORKDIR}" ; - docker tag "${IMG_PREFIX_DST}/${IMG}:${TAG}" "${IMG_PREFIX_DST}/${IMG}:${VER}" ; + docker build --compress --force-rm=true -t "${IMG_PREFIX_DST}/${IMG}:${TAG}" -f "$FILE" --build-arg "BASE_NAMESPACE=${IMG_PREFIX_SRC}" "$@" "${WORKDIR}" >&2 + docker tag "${IMG_PREFIX_DST}/${IMG}:${TAG}" "${IMG_PREFIX_DST}/${IMG}:${VER}" >&2 + echo "${IMG_PREFIX_DST}/${IMG}:${TAG}" } alias_image() { IMG_1=$1; TAG_1=$2; IMG_2=$3; TAG_2=$4; shift 4; VER=$(date +%Y.%m%d.%H%M)${TAG_SUFFIX}; - docker tag "${IMG_PREFIX_DST}/${IMG_1}:${TAG_1}" "${IMG_PREFIX_DST}/${IMG_2}:${TAG_2}" ; - docker tag "${IMG_PREFIX_DST}/${IMG_2}:${TAG_2}" "${IMG_PREFIX_DST}/${IMG_2}:${VER}" ; + docker tag "${IMG_PREFIX_DST}/${IMG_1}:${TAG_1}" "${IMG_PREFIX_DST}/${IMG_2}:${TAG_2}" >&2 + docker tag "${IMG_PREFIX_DST}/${IMG_2}:${TAG_2}" "${IMG_PREFIX_DST}/${IMG_2}:${VER}" >&2 } push_image() { KEYWORD="${1:-second}"; docker image prune --force && docker images | sort; IMAGES=$(docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.CreatedSince}}" | grep "${KEYWORD}" | awk '{print $1 ":" $2}') ; - echo "$DOCKER_REGISTRY_PASSWORD" | docker login "$REGISTRY_DST" -u "$DOCKER_REGISTRY_USERNAME" --password-stdin ; + echo "$DOCKER_REGISTRY_PASSWORD" | docker login "${REGISTRY_DST}" -u "$DOCKER_REGISTRY_USERNAME" --password-stdin ; for IMG in $(echo "${IMAGES}" | tr " " "\n") ; do docker push "${IMG}"; @@ -80,13 +77,25 @@ clear_images() { remove_folder() { - sudo du -h -d1 "$1" || true ; - sudo rm -rf "$1" || true ; + for dir in "$@"; do + if [ -d "$dir" ]; then + echo "Removing folder: $dir" ; + sudo du -h -d1 "$dir" || true ; + sudo rm -rf "$dir" || true ; + else + echo "Warn: directory not found: $dir" ; + fi + done } free_diskspace() { - remove_folder /usr/share/dotnet - remove_folder /usr/local/lib/android - # remove_folder /var/lib/docker - df -h + remove_folder /usr/share/dotnet ; # /usr/local/lib/android /var/lib/docker + df -h ; +} + +setup_github_actions() { + [ ! -f /etc/docker/daemon.json ] && sudo tee /etc/docker/daemon.json > /dev/null <<< '{}' ; + jq '.experimental=true | ."data-root"="/mnt/docker"' /etc/docker/daemon.json > /tmp/daemon.json && sudo mv /tmp/daemon.json /etc/docker/ ; + ( sudo service docker restart || true ) && cat /etc/docker/daemon.json && docker info ; } +[ "$GITHUB_ACTIONS" = "true" ] && echo "Running in GitHub Actions and Setup Env: $(setup_github_actions)"