diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 58f67b7..be96444 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -35,7 +35,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - source ./tool.sh && build_image app-clash latest docker_app_clash/clash.Dockerfile && push_image + source ./tool.sh && build_image app-clash latest docker_clash/clash.Dockerfile && push_image clash ## Casdoor docker_casdoor: @@ -44,7 +44,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - source ./tool.sh && build_image casdoor latest docker_casdoor/Dockerfile && push_image + source ./tool.sh && build_image casdoor latest docker_casdoor/casdoor.Dockerfile && push_image casdoor ## Keycloak docker_keycloak: @@ -53,7 +53,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - source ./tool.sh && build_image keycloak latest docker_keycloak/Dockerfile && push_image + source ./tool.sh && build_image keycloak latest docker_keycloak/keycloak.Dockerfile && push_image keycloak ## DevHub job-dev-hub: @@ -66,7 +66,7 @@ jobs: build_image dev-hub latest docker_devbox/hub.Dockerfile \ --build-arg "BASE_IMG=node" \ --build-arg "ARG_PROFILE_JUPYTER=hub" - push_image + push_image dev-hub ## OpenResty as gateway job-openresty: @@ -75,7 +75,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - source ./tool.sh && build_image openresty latest docker_openresty/Dockerfile && push_image + source ./tool.sh && build_image openresty latest docker_openresty/openresty.Dockerfile && push_image openresty ## SearchNGX for searching job-searxng: @@ -84,7 +84,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - source ./tool.sh && build_image searxng latest docker_searxng/searxng.Dockerfile && push_image + source ./tool.sh && build_image searxng latest docker_searxng/searxng.Dockerfile && push_image searxng ## StoreBox job-storebox: @@ -94,9 +94,17 @@ jobs: - uses: actions/checkout@v4 - run: | source ./tool.sh - build_image storebox latest docker_storebox/storebox.Dockerfile \ - --build-arg "BASE_IMG=node" - push_image + build_image storebox latest docker_storebox/storebox.Dockerfile && push_image storebox + + ## lognet for log management + job-logent: + name: 'logent' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: | + source ./tool.sh + build_image logent latest docker_logent/logent.Dockerfile && push_image logent ## DevBox - base @@ -126,7 +134,7 @@ jobs: --build-arg "ARG_PROFILE_JUPYTER=base,kernels,extensions" \ --build-arg "ARG_PROFILE_VSCODE=base" \ --build-arg "ARG_PROFILE_R=rstudio,rshiny" - push_image + push_image dev ## DevBox - full stack job-full-stack-dev: @@ -141,7 +149,7 @@ jobs: --build-arg "ARG_PROFILE_JUPYTER=base,kernels,extensions" \ --build-arg "ARG_PROFILE_VSCODE=base" \ --build-arg "ARG_PROFILE_R=rstudio,rshiny" - push_image + push_image dev ## DevBox - cuda job-cuda-dev: @@ -155,7 +163,7 @@ jobs: --build-arg "BASE_IMG=core-cuda" \ --build-arg "ARG_PROFILE_JUPYTER=base,kernels,extensions" \ --build-arg "ARG_PROFILE_VSCODE=base" - alias_image cuda-dev latest full-cuda latest && push_image + alias_image cuda-dev latest full-cuda latest && push_image dev ## Sync all images in this build (listed by "names") to mirror registry. diff --git a/docker_casdoor/README.md b/docker_casdoor/README.md index 5d29e0e..1cbea91 100644 --- a/docker_casdoor/README.md +++ b/docker_casdoor/README.md @@ -2,23 +2,4 @@ Identity and Access Management (IAM) / Single-Sign-On (SSO) platform: https://github.com/casdoor/casdoor -## debug - -```shell -docker build -t labnow/casdoor \ - -f docker_casdoor/Dockerfile \ - --build-arg="BASE_NAMESPACE=labnow" \ - docker_casdoor - -docker run -it \ - -p 8000:8000 \ - labnow/casdoor \ - bash - - -docker run --rm -it \ - -p 8000:8000 \ - -v $(pwd):/root/docker_casdoor \ - labnow/go-stack \ - bash -``` +For configuration file (`/opt/casdoor/conf/app.conf`), refer to: https://casdoor.org/de/docs/basic/configuration/ diff --git a/docker_casdoor/Dockerfile b/docker_casdoor/casdoor.Dockerfile similarity index 63% rename from docker_casdoor/Dockerfile rename to docker_casdoor/casdoor.Dockerfile index 56fee60..d4626a6 100644 --- a/docker_casdoor/Dockerfile +++ b/docker_casdoor/casdoor.Dockerfile @@ -20,11 +20,19 @@ COPY work/app.conf /opt/casdoor/conf/app.conf RUN set -eux \ && apt-get -qq update -yq --fix-missing && apt-get -qq install -yq --no-install-recommends lsof \ && mkdir -pv /root/web && ln -sf /opt/casdoor/web/build /root/web/ && ls -alh /opt/casdoor/web \ - && chmod +x /opt/casdoor/docker-entrypoint.sh && ls -alh /opt/casdoor + && chmod +x /opt/casdoor/docker-entrypoint.sh \ + && ln -sf /opt/casdoor/server /server \ + && ln -sf /opt/casdoor/conf /conf \ + && ls -alh /opt/casdoor \ + && echo "@ Version of Casdoor $(cat /opt/casdoor/version_info.txt)" LABEL maintainer="postmaster@labnow.ai" ENV RUNNING_IN_DOCKER=true WORKDIR /opt/casdoor -EXPOSE 8000 -# ENTRYPOINT ["/bin/bash"] -# CMD ["/opt/casdoor/docker-entrypoint.sh"] +# 8000=web, 389=ldap, 1812=radius +EXPOSE 8000 389 1812 +ENTRYPOINT ["/bin/bash"] +CMD ["/opt/casdoor/docker-entrypoint.sh"] + +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD ["curl", "--head", "-fsSk", "http://localhost:8000/health/ready"] diff --git a/docker_casdoor/demo/docker-compose.dev.yml b/docker_casdoor/demo/docker-compose.dev.yml deleted file mode 100644 index 42623ab..0000000 --- a/docker_casdoor/demo/docker-compose.dev.yml +++ /dev/null @@ -1,38 +0,0 @@ -services: - db-postgres-casdoor: - # su postgres && psql -d casdoor -U pg-casdoor-username - image: docker.io/labnow/postgres-16:latest - container_name: db-postgres - environment: - POSTGRES_DB: casdoor - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - - svc-casdoor: - build: - context: ../ - dockerfile: Dockerfile - args: - BASE_NAMESPACE: labnow - tags: - - labnow/casdoor - container_name: svc-casdoor - # command: ["/bin/bash", "--login", "/opt/casdoor/server", "--createDatabase=true"] - command: | - /bin/bash -l -c ' - ls -alh /opt/casdoor - echo "driverName = postgres" >> /opt/casdoor/conf/app.conf - echo "dataSourceName = \"user=postgres password=postgres host=db-postgres port=5432 sslmode=disable dbname=casdoor\"" >> /opt/casdoor/conf/app.conf - sleep 8s - cat /opt/casdoor/conf/app.conf - /opt/casdoor/server -createDatabase=true' - ports: - - 8000:8000 - depends_on: - - db-postgres-casdoor - healthcheck: - test: ["CMD-SHELL", "curl", "--head", "-fsSk", "https://localhost:8000/health/ready" ] - interval: 30s - timeout: 30s - start_period: 5s - retries: 3 diff --git a/docker_casdoor/demo/docker-compose.yml b/docker_casdoor/demo/docker-compose.yml index d07d943..c533f40 100644 --- a/docker_casdoor/demo/docker-compose.yml +++ b/docker_casdoor/demo/docker-compose.yml @@ -11,7 +11,6 @@ services: svc-casdoor: image: docker.io/labnow/casdoor container_name: svc-casdoor - # command: ["/bin/bash", "--login", "/opt/casdoor/server", "--createDatabase=true"] command: | /bin/bash -l -c ' ls -alh /opt/casdoor @@ -25,8 +24,8 @@ services: depends_on: - db-postgres-casdoor healthcheck: - test: ["CMD-SHELL", "curl", "--head", "-fsSk", "https://localhost:8000/health/ready" ] + test: ["CMD-SHELL", "curl --head -fsSk http://localhost:8000/health/ready" ] interval: 30s - timeout: 30s + timeout: 10s start_period: 5s retries: 3 diff --git a/docker_casdoor/work/app.conf b/docker_casdoor/work/app.conf index f91c686..1373c45 100644 --- a/docker_casdoor/work/app.conf +++ b/docker_casdoor/work/app.conf @@ -2,7 +2,6 @@ appname = casdoor authState = "casdoor" batchSize = 100 copyrequestbody = true -dbName = casdoor defaultStorageProvider = enableGzip = true frontendBaseDir = "../casdoor" @@ -11,8 +10,9 @@ initDataFile = "./init_data.json" initScore = 0 isCloudIntranet = false isDemoMode = false -isUsernameLowered = false +isUsernameLowered = true ldapServerPort = 389 +ldapsServerPort = 636 logConfig = {"filename": "logs/casdoor.log", "maxdays":99999, "perm":"0770"} logPostOnly = true origin = @@ -21,11 +21,12 @@ quota = {"organization": -1, "user": -1, "application": -1, "provider": -1} radiusSecret = "secret" radiusServerPort = 1812 redisEndpoint = -runmode = dev -showSql = false +runmode = prod +showSql = true socks5Proxy = "127.0.0.1:10808" staticBaseUrl = "https://cdn.casbin.org" tableNamePrefix = verificationCodeTimeout = 10 +dbName=casdoor # driverName = postgres # dataSourceName = "user=postgres password=postgres host=localhost port=5432 sslmode=disable dbname=casdoor" diff --git a/docker_casdoor/work/script-setup-casdoor.sh b/docker_casdoor/work/script-setup-casdoor.sh index 1855218..3091550 100644 --- a/docker_casdoor/work/script-setup-casdoor.sh +++ b/docker_casdoor/work/script-setup-casdoor.sh @@ -4,32 +4,30 @@ setup_casdoor() { export ARCH=$(dpkg --print-architecture) # ref: https://github.com/casdoor/casdoor/blob/master/Dockerfile - # Install the latest release of casdoor + # Download the latest release of casdoor VER_CASDOOR=$(curl -sL https://github.com/casdoor/casdoor/releases.atom | grep 'releases/tag' | head -1 | grep -Po '\d[\d.]+' ) \ && URL_CASDOOR="https://github.com/casdoor/casdoor/archive/refs/tags/v${VER_CASDOOR}.tar.gz" \ && echo "Downloading casdoor version ${VER_CASDOOR} from: ${URL_CASDOOR}" \ && install_tar_gz $URL_CASDOOR \ && mv /opt/casdoor-* /tmp/casdoor \ - && sed -i '/userId := user.GetId()/a\ c.SetSessionUsername(userId)' /tmp/casdoor/controllers/account.go \ - && sed -i 's|paidUserName != c.GetSessionUsername()|userId != c.GetSessionUsername()|' /tmp/casdoor/controllers/product.go \ && mkdir -pv /opt/casdoor/web/build /opt/casdoor/conf echo "--> Building Backend..." \ - && cd /tmp/casdoor && ./build.sh \ - && echo "${VER_CASDOOR}" > version_info.txt \ - && mv "./server_linux_${ARCH}" ./swagger ./version_info.txt /opt/casdoor/ \ - && ln -sf "/opt/casdoor/server_linux_${ARCH}" /opt/casdoor/server \ + && cd /tmp/casdoor && echo "${VER_CASDOOR}" > /tmp/casdoor/version_info.txt \ + && ./build.sh \ + && mv "./server_linux_${ARCH}" ./swagger ./docker-entrypoint.sh ./version_info.txt /opt/casdoor/ \ && cat ./conf/app.conf | sort > /opt/casdoor/conf/app.conf \ - && mv ./docker-entrypoint.sh /opt/casdoor/ - # && go test -v -run TestGetVersionInfo ./util/system_test.go ./util/system.go > version_info.txt \ + && ln -sf "/opt/casdoor/server_linux_${ARCH}" /opt/casdoor/server + # && go test -v -run TestGetVersionInfo ./util/system_test.go ./util/system.go ./util/variable.go \ echo "--> Building Frontend..." \ && cd /tmp && npm install -g yarn && yarn -v \ && cd /tmp/casdoor/web \ - && yarn set version berry && yarn install && yarn run build \ + && yarn set version berry \ + && yarn install --frozen-lockfile --network-timeout 1000000 \ + && NODE_OPTIONS="--max-old-space-size=4096" yarn run build \ && mv ./build*/* /opt/casdoor/web/build/ - # && yarn install --frozen-lockfile && yarn run build \ - + echo "--> Finished building casdoor to /opt/casdoor!" \ && rm -rf /tmp/casdoor \ && echo "@ Version of Casdoor $(cat /opt/casdoor/version_info.txt)" diff --git a/docker_app_clash/README.md b/docker_clash/README.md similarity index 100% rename from docker_app_clash/README.md rename to docker_clash/README.md diff --git a/docker_app_clash/clash.Dockerfile b/docker_clash/clash.Dockerfile similarity index 100% rename from docker_app_clash/clash.Dockerfile rename to docker_clash/clash.Dockerfile diff --git a/docker_app_clash/demo/docker-compose.yml b/docker_clash/demo/docker-compose.yml similarity index 72% rename from docker_app_clash/demo/docker-compose.yml rename to docker_clash/demo/docker-compose.yml index c825a29..014b7a8 100644 --- a/docker_app_clash/demo/docker-compose.yml +++ b/docker_clash/demo/docker-compose.yml @@ -8,10 +8,8 @@ services: ipc: host # When your system is Linux, you can use `network_mode: "host"` directly. # network_mode: "host" - ports: - - "7890:7890" - - "9090:9090" + ports: ["7890:7890", "9090:9090"] # volumes: # - ../work/clash/config.yaml:/opt/clash/config/config.yaml environment: - - PROXY_PROVIDER="https://subs.zeabur.app/clash" + - PROXY_PROVIDER=https://raw.githubusercontent.com/snakem982/proxypool/main/source/clash-meta.yaml diff --git a/docker_app_clash/work/clash/config.yaml b/docker_clash/work/clash/config.yaml similarity index 100% rename from docker_app_clash/work/clash/config.yaml rename to docker_clash/work/clash/config.yaml diff --git a/docker_app_clash/work/clash/script-setup-clash.sh b/docker_clash/work/clash/script-setup-clash.sh similarity index 100% rename from docker_app_clash/work/clash/script-setup-clash.sh rename to docker_clash/work/clash/script-setup-clash.sh diff --git a/docker_app_clash/work/clash/start-clash.sh b/docker_clash/work/clash/start-clash.sh similarity index 100% rename from docker_app_clash/work/clash/start-clash.sh rename to docker_clash/work/clash/start-clash.sh diff --git a/docker_keycloak/Dockerfile b/docker_keycloak/keycloak.Dockerfile similarity index 100% rename from docker_keycloak/Dockerfile rename to docker_keycloak/keycloak.Dockerfile diff --git a/docker_logent/README.md b/docker_logent/README.md new file mode 100644 index 0000000..6ea22c7 --- /dev/null +++ b/docker_logent/README.md @@ -0,0 +1,85 @@ +# logent (log-agent) + +`logent` is a containerized logging control component designed to provide a unified log management layer across heterogeneous environments (bare-metal, Docker, Kubernetes). + +It bundles: + +- supervisord — process supervision +- logrotate — local log lifecycle management +- vector — log collection, transformation, and forwarding + +## Purpose + +logent serves as a log control plane inside containerized infrastructure. +It separates application logging from log processing and routing logic. + +The design goals are: + +- Provide local log retention and compression +- Enable structured log collection and routing +- Maintain environment portability (VM / Docker / K8s) +- Avoid tight coupling with specific log backends + +## Responsibilities + +1. Local Log Lifecycle + - Rotate logs on schedule + - Compress and retain history + - Prevent disk overflow + +2. Log Pipeline + - Collect from file or stdout + - Apply transforms if required + - Forward to one or multiple backends + +3. Process Management + - Ensure vector and auxiliary services are supervised + - Maintain consistent runtime behavior + +## Architecture Model + +Application → Log file / stdout +→ logent +→ Backend (ClickHouse / Elasticsearch / PostgreSQL / S3 / etc.) + +logent does not impose a specific storage backend. + +## Deployment Modes + +### Docker (Single Host) + +- Mount application log directory +- Run logent container +- Configure vector sources and sinks + +### Kubernetes + +Two typical patterns: + +- Sidecar mode (per Pod) +- DaemonSet mode (per Node) + +logent can be adapted depending on cluster design. + +## Why Not Rely Only on stdout? + +While stdout-based logging is cloud-native friendly, certain environments require: + +- Local compressed archives +- Regulatory retention +- Offline debugging capability + +logent supports both file-based and stream-based workflows. + +## Design Principles + +- Decoupled from specific log storage +- Portable across environments +- Minimal assumptions about infrastructure +- Future-proof against backend replacement + +## Notes + +- Avoid embedding backend-specific logic in image name. +- Vector configuration should be externalized. +- logrotate configuration should be environment-aware. diff --git a/docker_logent/logent.Dockerfile b/docker_logent/logent.Dockerfile new file mode 100644 index 0000000..5fe1c88 --- /dev/null +++ b/docker_logent/logent.Dockerfile @@ -0,0 +1,18 @@ +# 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 \ + # ----------------------------- Install logrotate + && apt-get -qq update -yq --fix-missing && apt-get -qq install -yq --no-install-recommends logrotate \ + # ----------------------------- Install supervisord + && source /opt/utils/script-setup-sys.sh && setup_supervisord \ + # ----------------------------- Install vector + && source /opt/utils/script-setup-logent.sh && setup_vector \ + # Clean up and display components version information... + && list_installed_packages && install__clean diff --git a/docker_logent/work/script-setup-logent.sh b/docker_logent/work/script-setup-logent.sh new file mode 100644 index 0000000..c121cc5 --- /dev/null +++ b/docker_logent/work/script-setup-logent.sh @@ -0,0 +1,18 @@ +setup_vector() { + ARCH=$(uname -m | sed -e 's/armv7l/armv7/' ) + [[ "$ARCH" =~ ^(x86_64|aarch64|armv7)$ ]] || { + echo "Unsupported architecture for Vector: $(uname -m)" && return 1 ; + } + + VER_VECTOR=$(curl -sL -o /dev/null -w "%{url_effective}" https://github.com/vectordotdev/vector/releases/latest | grep -oP 'v\K[\d.]+') \ + && PKG_VECTOR="vector-${VER_VECTOR}-${ARCH}-unknown-linux-gnu.tar.gz" \ + && URL_VECTOR="https://github.com/vectordotdev/vector/releases/download/v${VER_VECTOR}/${PKG_VECTOR}" \ + && echo "Installing Vector v${VER_VECTOR} for arch ${ARCH} from: ${URL_VECTOR}" \ + && curl -fSL "${URL_VECTOR}" -o /tmp/vector.tar.gz \ + && tar -xzf /tmp/vector.tar.gz -C /tmp \ + && install -m 0755 -D /tmp/vector-*-linux-*/bin/vector /opt/bin/vector \ + && ln -sf /opt/bin/vector /usr/bin/vector \ + && rm -rf /tmp/vector* + + type vector && echo "@ Installed Vector: $(vector --version)" +} diff --git a/docker_openresty/README.md b/docker_openresty/README.md index 1f18e88..ff1457e 100644 --- a/docker_openresty/README.md +++ b/docker_openresty/README.md @@ -7,21 +7,47 @@ What's inside this docker image: ## How to apply for certificates using ACME.sh ```bash -# docker exec -it svc-proxy-openresty bash (enter into the container) - +# enter into the container and see existing domain certs +docker exec -it svc-proxy-openresty bash cd /etc/nginx/ssl && ls -alh +``` -# If you don't have any certs yet, set your DOMAIN list to DOMAINS -DOMAINS='a1.example.com a2.example.com a3.example.com' +And then, choose your mode: -# If you already have certs in this folder, run the command below to get a list of DOMAINS -DOMAINS=$(printf "%s\n" *.crt *.key 2>/dev/null | sed 's/\.[^.]*$//' | sort -u) +### Mode 1: HTTP-01 mode +Not working for wild-card domain names, and requires nginx `letsencrypt-acme-challenge.conf`. +```bash +# If you don't have any certs yet, set your DOMAIN list to env var DOMAINS +DOMAINS='a1.example.com a2.example.com a3.example.com' +# Or if you already have certs in this folder, run the command below to get a list of DOMAINS +DOMAINS=$(printf "%s\n" *.crt *.key 2>/dev/null | sed 's/\.[^.]*$//' | sort -u) + +# Then apply for certs using acme.sh HTTP-01 method: /opt/utils/script-acme-sh.sh 'your@email.com' "${DOMAINS}" ``` -## Custom Configs +### Mode 2: DNS-01 mode + +Can work for wild-card domain names, and requires DNS service provider token. + +Refer to: [`acme.sh` supported DNS service provider](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) to find how to get a token and use the token in cli. + +e.g.: the `CF_Token` and `dns_cf` below is for [Cloudflare](https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf). + +```bash +# define variable to apply cert for multiple domains in a same cert file (the one without wild-card goes first): +DOMAINS='example.com *.example.com' + +# Then apply for certs using acme.sh DNS-01 method: +## Firstly apply for DNS service provider token and export the variable +export CF_Token='' +## Then Apply for certs using acme.sh DNS-01 method: +/opt/utils/script-acme-sh.sh 'your@email.com' "${DOMAINS}" "dns_cf" +``` + +## Custom Configs for Openresty - Refer to [source code](https://github.com/NginxProxyManager/nginx-proxy-manager/tree/develop/docker/rootfs/etc/nginx/conf.d) and [docs](https://nginxproxymanager.com/advanced-config/#custom-nginx-configurations) of [Nginx Proxy Manager](https://nginxproxymanager.com/). @@ -39,11 +65,3 @@ You can add your custom configuration snippet files at /data/nginx/custom as fol - `conf/server_stream_tcp.conf`: Included at the end of every TCP stream server block - `conf/server_stream_udp.conf`: Included at the end of every UDP stream server block - `/data/nginx/custom/server_dead.conf`: Included at the end of every 404 server block - -## Debug - -```bash -docker run -it --rm labnow/openresty bash - -docker build -t openresty --build-arg BASE_NAMESPACE=labnow . -``` diff --git a/docker_openresty/Dockerfile b/docker_openresty/openresty.Dockerfile similarity index 89% rename from docker_openresty/Dockerfile rename to docker_openresty/openresty.Dockerfile index fed334a..e862ffc 100644 --- a/docker_openresty/Dockerfile +++ b/docker_openresty/openresty.Dockerfile @@ -13,13 +13,16 @@ ENV NGINX_ENVSUBST_TEMPLATE_SUFFIX=.template COPY work /opt/utils/ RUN set -eux \ + && chmod +x /opt/utils/*.sh \ + # ----------------------------- Install acme.sh + && source /opt/utils/script-setup-acme.sh && setup_acme \ + # ----------------------------- Install lua and lua-rocks + && source /opt/utils/script-setup.sh && setup_lua_base && setup_lua_rocks \ + # ----------------------------- Install openresty && useradd nginx -G www-data \ && mkdir -pv /var/cache/nginx /var/log/nginx \ && chown -R nginx:www-data /var/cache/nginx /var/log/nginx \ - && chmod +x /opt/utils/*.sh \ - && source /opt/utils/script-setup.sh && setup_lua_base && setup_lua_rocks \ && source /opt/utils/script-setup-openresty.sh && setup_openresty \ - && source /opt/utils/script-setup-acme.sh && setup_acme \ && mv /opt/utils/entrypoint/* / && rm -rf /opt/utils/entrypoint \ && cp -rf /opt/utils/nginx/* /etc/nginx/ && rm -rf /opt/utils/nginx \ && chmod -R +x /docker-entrypoint.* && ls -alh /docker-entrypoint.* /etc/nginx/* \ diff --git a/docker_storebox/README.md b/docker_storebox/README.md new file mode 100644 index 0000000..e1b7985 --- /dev/null +++ b/docker_storebox/README.md @@ -0,0 +1,25 @@ +# Storebox + +`storebox` is a storage-focused container image built on top of a shared base image, with extra tooling for file serving, proxying, and cloud storage operations. + +## Included Components + +- `supervisord`: process supervisor for running multiple long-lived services in one container. +- `caddy`: modern web server and reverse proxy, useful for HTTP routing and TLS automation. +- `alist`: web-based file listing and management service, installed from the latest GitHub release during build. +- `rclone`: cloud storage sync/mount/copy CLI, also installed from the latest GitHub release during build. + +## Potential Use Cases + +- Personal or team file gateway: expose multiple storage backends through `alist` with a browser-friendly UI. +- Lightweight storage hub: use `rclone` for scheduled sync/copy tasks between local paths and cloud providers. +- Reverse-proxied storage service: put `alist` (and related endpoints) behind `caddy` for domain routing and HTTPS. +- Multi-service single container setup: use `supervisord` to orchestrate `alist`, `caddy`, and helper processes together. + +## Use Case Example: Serving static files (after CDN) using net-disk storage + +1. Refer to [alist config](https://alistgo.com/zh/config/configuration.html) and add a net-disk (e.g.: [Baidu NetDisk](https://alistgo.com/zh/guide/drivers/baidu.html) ) as storage backend. + +2. Go to alist global settings to set: 1) set `Sign all` to disabled and 2) set `Link expiration` to 0. + +3. Then you can use alist to serve static files from backend storage, better use nginx (openresty) and CDN to cache static files. diff --git a/docker_storebox/work/script-setup-alist.sh b/docker_storebox/work/script-setup-alist.sh index c790746..4d04e77 100644 --- a/docker_storebox/work/script-setup-alist.sh +++ b/docker_storebox/work/script-setup-alist.sh @@ -1,21 +1,16 @@ source /opt/utils/script-utils.sh setup_alist() { - local ARCH=$(dpkg --print-architecture) - local ALIST_ARCH + ARCH=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/' -e 's/armv7l/arm-7/') \ + && [[ "$ARCH" =~ ^(amd64|arm64|arm-7)$ ]] || { + echo "Unsupported architecture for alist: $(uname -m)" && return 1 ; + } - case "$ARCH" in - amd64|x86_64) ALIST_ARCH="amd64" ;; - arm64|aarch64) ALIST_ARCH="arm64" ;; - armhf|armv7l) ALIST_ARCH="arm-7" ;; - *) echo "Unsupported architecture for alist: $ARCH"; return 1 ;; - esac + VER_ALIST=$(curl -sL -o /dev/null -w "%{url_effective}" https://github.com/alist-org/alist/releases/latest | grep -oP 'v\K[\d.]+') + URL_ALIST="https://github.com/alist-org/alist/releases/download/v${VER_ALIST}/alist-linux-${ARCH}.tar.gz" - local VER=$(curl -sL -o /dev/null -w "%{url_effective}" https://github.com/alist-org/alist/releases/latest | grep -oP 'v\K[\d.]+') - local URL="https://github.com/alist-org/alist/releases/download/v${VER}/alist-linux-${ALIST_ARCH}.tar.gz" - - echo "Installing alist v${VER} for arch ${ARCH} (${ALIST_ARCH})" \ - && curl -fSL "${URL}" | tar -xz -C /tmp/ \ + echo "Installing alist v${VER_ALIST} for arch $(dpkg --print-architecture) (${ARCH})" \ + && curl -fSL "${URL_ALIST}" | tar -xz -C /tmp/ \ && install -m 0755 -D /tmp/alist /opt/bin/alist \ && ln -sf /opt/bin/alist /usr/bin/alist \ && rm -f /tmp/alist \ diff --git a/docker_storebox/work/script-setup-rclone.sh b/docker_storebox/work/script-setup-rclone.sh index 9e5e6fc..c58028a 100644 --- a/docker_storebox/work/script-setup-rclone.sh +++ b/docker_storebox/work/script-setup-rclone.sh @@ -1,24 +1,16 @@ source /opt/utils/script-utils.sh setup_rclone() { - local ARCH=$(dpkg --print-architecture) - local RCLONE_ARCH + ARCH=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/' -e 's/armv7l/arm-7/') \ + && [[ "$ARCH" =~ ^(amd64|arm64|arm-7)$ ]] || { + echo "Unsupported architecture for rclone: $(uname -m)" && return 1 ; + } - case "$ARCH" in - amd64|x86_64) RCLONE_ARCH="amd64" ;; - arm64|aarch64) RCLONE_ARCH="arm64" ;; - armhf|armv7l) RCLONE_ARCH="arm-v7" ;; - i386|i486|i686) RCLONE_ARCH="386" ;; - s390x) RCLONE_ARCH="s390x" ;; - ppc64el|ppc64le) RCLONE_ARCH="ppc64le" ;; - *) echo "Unsupported architecture for rclone: $ARCH"; return 1 ;; - esac + VER_RCLONE=$(curl -sL -o /dev/null -w "%{url_effective}" https://github.com/rclone/rclone/releases/latest | grep -oP 'v\K[\d.]+') + URL_RCLONE="https://github.com/rclone/rclone/releases/download/v${VER_RCLONE}/rclone-v${VER_RCLONE}-linux-${ARCH}.zip" - local VER=$(curl -sL -o /dev/null -w "%{url_effective}" https://github.com/rclone/rclone/releases/latest | grep -oP 'v\K[\d.]+') - local URL="https://github.com/rclone/rclone/releases/download/v${VER}/rclone-v${VER}-linux-${RCLONE_ARCH}.zip" - - echo "Installing rclone v${VER} for arch ${ARCH} (${RCLONE_ARCH})" \ - && curl -fSL -o /tmp/rclone.zip "${URL}" \ + echo "Installing rclone v${VER_RCLONE} for arch $(dpkg --print-architecture) (${ARCH})" \ + && curl -fSL -o /tmp/rclone.zip "${URL_RCLONE}" \ && unzip -oj /tmp/rclone.zip "*/rclone" -d /tmp/ \ && install -m 0755 -D /tmp/rclone /opt/bin/rclone \ && ln -sf /opt/bin/rclone /usr/bin/rclone \ diff --git a/tool.sh b/tool.sh index 7424d58..12114bf 100644 --- a/tool.sh +++ b/tool.sh @@ -57,8 +57,8 @@ alias_image() { push_image() { KEYWORD="${1:-second}"; docker image prune --force && docker images | sort; - IMAGES=$(docker images | grep "${KEYWORD}" | awk '{print $1 ":" $2}') ; - echo "$DOCKER_REGISTRY_PASSWORD" | docker login "${REGISTRY_DST}" -u "$DOCKER_REGISTRY_USERNAME" --password-stdin ; + 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 ; for IMG in $(echo "${IMAGES}" | tr " " "\n") ; do docker push "${IMG}";