diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..e81b79f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,43 @@ +name: build + +on: + workflow_dispatch: + push: + branches: + - "main" + paths: + - "Dockerfile" + - "entrypoint.sh" + workflow_run: + workflows: ["pre-build"] + types: + - completed + +jobs: + build-v1: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push BASE + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + platforms: linux/amd64, linux/arm64, linux/s390x, linux/ppc64le, linux/arm + tags: ${{ secrets.DOCKERHUB_USERNAME }}/docker-instant-ai \ No newline at end of file diff --git a/.github/workflows/pre-build.yml b/.github/workflows/pre-build.yml new file mode 100644 index 0000000..6ec10d7 --- /dev/null +++ b/.github/workflows/pre-build.yml @@ -0,0 +1,40 @@ +name: pre-build + +on: + workflow_dispatch: + schedule: + - cron: '0 6 */6 * *' + push: + branches: + - "main" + paths: + - "dev/BASE" + +jobs: + base: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push BASE + uses: docker/build-push-action@v5 + with: + context: . + file: ./dev/BASE + push: true + platforms: linux/amd64, linux/arm64, linux/s390x, linux/ppc64le, linux/arm + tags: ${{ secrets.DOCKERHUB_USERNAME }}/docker-instant-ai:base \ No newline at end of file diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 0000000..f58948d --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,25 @@ +name: verify + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +on: + workflow_dispatch: + workflow_run: + workflows: ["build"] + types: + - completed + +jobs: + verify: + runs-on: ubuntu-latest + env: + name: ${{ github.job }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - run: | + docker run --name DIA -p 80:80 -p 443:443 --restart=always -itd ${{ secrets.DOCKERHUB_USERNAME }}/docker-instant-ai + - id: check + run: echo trace=$(curl -v -fsSL 127.0.0.1:80) >> $GITHUB_OUTPUT + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65d07c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +.vscode/ +.test/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4a98caa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM monius/docker-instant-ai:base + +COPY entrypoint.sh /run/entrypoint.sh +ENTRYPOINT ["/run/entrypoint.sh"] + +EXPOSE 80 443 + +CMD ["nginx"] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2f626cc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 AUTOM77 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..81d3219 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# instant-ai-deploy + +[![CI Status](https://github.com/AUTOM77/Docker-instant-ai/workflows/build/badge.svg)](https://github.com/AUTOM77/Docker-instant-ai/actions?query=workflow:build) +[![CI Status](https://github.com/AUTOM77/Docker-instant-ai/workflows/verify/badge.svg)](https://github.com/AUTOM77/Docker-instant-ai/actions?query=workflow:verify) +[![Docker Pulls](https://flat.badgen.net/docker/pulls/monius/docker-instant-ai)](https://hub.docker.com/r/monius/docker-instant-ai) +[![Code Size](https://img.shields.io/github/languages/code-size/AUTOM77/Docker-instant-ai)](https://github.com/AUTOM77/Docker-instant-ai) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE) +[![Open Issues](https://img.shields.io/github/issues/AUTOM77/Docker-instant-ai)](https://github.com/AUTOM77/Docker-instant-ai/issues) + +> AI Infra on Multi-platform: `linux/amd64`, `linux/arm64`, `linux/arm`, `linux/s390x` and `linux/ppc64le`; + +🚧 Building .. 🚧 + +Test +```sh +doas podman run --name ii -p 80:80 -p 443:443 -itd monius/docker-instant-ai +doas podman run --name ii -itd monius/docker-instant-ai +``` + +```bash +doas podman run --rm monius/docker-instant-ai +doas podman run --name ii -it monius/docker-instant-ai /bin/sh +doas podman run --name ii -p 80:80 -p 443:443 -it monius/docker-instant-ai /bin/sh + +doas podman run -itd \ + --name instant-ai \ + -e DOMAIN=domain \ + -e CLOUDFLARE_DNS_API_TOKEN=cf_api_token \ + -e AI_SERVICE_NAME=ai_name \ + -e AI_SERVICE_PORT=ai_port \ + -p 80:80 \ + -p 443:443 \ + monius/docker-instant-ai + +doas podman logs ii +doas podman inspect -f '{{.NetworkSettings.IPAddress}}' ii +doas podman rm -f $(doas podman ps -a -q) +doas podman rmi -f $(doas podman images -a -q) +``` \ No newline at end of file diff --git a/dev/BASE b/dev/BASE new file mode 100644 index 0000000..7a93871 --- /dev/null +++ b/dev/BASE @@ -0,0 +1,65 @@ +FROM alpine:3.19 as NGINX + +LABEL maintainer="M0nius " \ + alpine-version="3.19" \ + nginx-version="1.25.3" + +ENV XUSER="nginx" +ENV VER="1.25.3" +ENV NGINX_SRC="https://nginx.org/download/nginx-${VER}.tar.gz" +ENV PKG="build-base linux-headers openssl-dev pcre-dev curl zlib-dev" + +RUN \ + apk --no-cache add ${PKG} && \ + curl -fsSL "${NGINX_SRC}" | tar -C /tmp -xz && \ + cd /tmp/nginx-"${VER}" && \ + ./configure \ + --prefix=/etc/nginx \ + --sbin-path=/usr/sbin/nginx \ + --conf-path=/etc/nginx/nginx.conf \ + --error-log-path=/var/log/nginx/error.log \ + --http-log-path=/var/log/nginx/access.log \ + --pid-path=/var/run/nginx.pid \ + --lock-path=/var/run/nginx.lock \ + --http-client-body-temp-path=/var/cache/nginx/client_temp \ + --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ + --user=$XUSER \ + --group=$XUSER \ + --with-http_ssl_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_stub_status_module \ + --with-http_auth_request_module \ + --with-file-aio \ + --with-threads \ + --with-stream \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-http_slice_module \ + --with-http_v2_module && \ + make -j"$(nproc)" && make install + +RUN curl -fsSL https://get.acme.sh | sh -s email=a@b.c + +FROM alpine:3.19 +ENV XUSER nginx + +RUN apk --no-cache add ca-certificates openssl pcre zlib tzdata git + +COPY --from=NGINX /usr/sbin/nginx /usr/sbin/nginx +COPY --from=NGINX /root/.acme.sh/acme.sh /root/acme.sh + +# RUN du -sh / >> /etc/store.debug + +RUN addgroup -S ${XUSER} && \ + adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G ${XUSER} ${XUSER} + +# RUN du -sh / >> /etc/store.debug \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..a42b3fd --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,261 @@ +#!/bin/sh + +set -e + +sleep 3 + +NG_ACME=~/acme.sh +NG_SSL=/etc/nginx/ssl +NG_CONF=/etc/nginx/nginx.conf +NG_DEBUG=/etc/nginx/service.d/default +NG_HTTP_UPGRADE='$http_upgrade' +NG_HOST='$host' + +SSL_KEY="$NG_SSL/$DOMAIN.key" +SSL_FULL_CHAIN="$NG_SSL/$DOMAIN.pem" +SSL_DHPARAM="$NG_SSL/$DOMAIN.dpr" + +mkdir -p /var/log/nginx +mkdir -p /etc/nginx/conf.d +mkdir -p /etc/nginx/service.d +mkdir -p /etc/nginx/html + + +cat <<'EOF' | tee /etc/nginx/conf.d/gzip.conf +types_hash_max_size 2048; +server_names_hash_bucket_size 256; + +gzip on; +gzip_vary on; +gzip_proxied any; +gzip_comp_level 6; +gzip_buffers 16 8k; +gzip_http_version 1.1; +gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml application/xml+rss application/sla application/vnd.ms-pki.stl; +EOF + +cat <<'EOF' | tee /etc/nginx/conf.d/log.conf +access_log /var/log/nginx/access.log warn; +error_log /var/log/nginx/error.log warn; +log_format main '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; +EOF + +cat <<'EOF' | tee /etc/nginx/conf.d/tcp.conf +sendfile on; +tcp_nopush on; +tcp_nodelay on; +port_in_redirect off; +server_name_in_redirect on; +keepalive_timeout 65; +set_real_ip_from 127.0.0.1; +real_ip_header proxy_protocol; +EOF + +cat <<'EOF' | tee /etc/nginx/conf.d/ssl.conf +server_tokens off; +ssl_prefer_server_ciphers on; +ssl_protocols TLSv1.3 TLSv1.2; +ssl_ecdh_curve secp384r1; +ssl_session_cache shared:SSL:40m; +ssl_session_tickets off; +ssl_session_timeout 21h; +ssl_stapling on; +ssl_stapling_verify on; +ssl_buffer_size 4k; +ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS:ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; +EOF + +cat < + + +This is Instant-AI system by M0nius + + + +

This is Instant-AI system by M0nius

+

If you see this page, the nginx web server is successfully installed and +working. Further configuration is required.

+

Thank you for using Instant-AI system by M0nius.

+ + +EOF + +if [ ! -d $NG_SSL ] && [ -e $NG_ACME ]; then + mkdir -p $NG_SSL + $NG_ACME --install-cert -d "$DOMAIN" \ + --key-file "$SSL_KEY" \ + --fullchain-file "$SSL_FULL_CHAIN" +fi + +if [ ! -e $NG_CONF ]; then + cat <