Selaa lähdekoodia

:wrench: upgrade spring image to support sshd

Jeremy Zheng 1 vuosi sitten
vanhempi
sitoutus
4579955c3e

+ 339 - 77
docker/spring/Dockerfile

@@ -1,40 +1,90 @@
-FROM ubuntu:latest
+FROM archlinux:latest
 LABEL maintainer="Jeremy Zheng"
 
-ENV DEBIAN_FRONTEND noninteractive
-
-RUN apt update
-RUN apt -y upgrade
-RUN apt -y install zsh locales locales-all curl wget vim tzdata pwgen zip unzip tree tmux dialog asciidoc doxygen \
-    build-essential mold cmake supervisor \
-    composer php-xdebug php-cli php-fpm php-xml php-imap php-intl php-mbstring php-bcmath php-bz2 php-zip php-curl php-gd php-imagick php-pgsql php-mysql php-sqlite3 php-redis php-amqp \
-    nginx postgresql postgresql-contrib rabbitmq-server redis \
-    fonts-dejavu-extra fonts-opensymbol fonts-lxgw-wenkai fonts-smiley-sans \
-    fonts-noto-extra fonts-noto-cjk-extra fonts-noto-color-emoji \
-    fonts-arphic-ukai fonts-arphic-uming \
-    fonts-wqy-microhei fonts-wqy-zenhei \
-    fonts-cns11643-kai fonts-cns11643-sung \
-    fonts-moe-standard-kai fonts-moe-standard-song \
-    fonts-ipaexfont fonts-ipafont fonts-konatu fonts-ipafont-nonfree-jisx0208 fonts-ipafont-nonfree-uigothic \
-    fonts-mikachan \
-    fonts-tibetan-machine fonts-ddc-uchen fonts-monlam fonts-sambhota-tsugring fonts-sambhota-yigchung \
-    imagemagick ffmpeg graphviz pandoc texlive-full \
-    libssl-dev
-RUN apt -y autoremove
-RUN apt -y clean
-
-RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
-RUN locale-gen
-RUN update-locale LANG=en_US.UTF-8
-RUN update-alternatives --set editor /usr/bin/vim.basic
+RUN pacman-key --init
+RUN pacman -Sy --noconfirm archlinux-keyring
+RUN pacman-key --populate
+RUN pacman -Syu --noconfirm
+RUN pacman -S --needed --noconfirm base-devel aarch64-linux-gnu-gcc risc-v \
+    bzip2 bzip3 p7zip unarchiver \
+    vim git cmake thrift capnproto wget zsh man-db man-pages \
+    pwgen sshpass openssl openssh rsync zip unzip tree tmux asciidoc doxygen cpio net-tools bind-tools \
+    clang llvm lld lldb mold bison flex ninja bazel \
+    imagemagick ffmpeg xorg-font-util \
+    ansible ansible-lint \
+    wqy-bitmapfont wqy-microhei wqy-zenhei \
+    ttf-fira-code woff-fira-code woff2-fira-code \
+    adobe-source-code-pro-fonts adobe-source-serif-fonts adobe-source-sans-fonts \
+    adobe-source-han-serif-cn-fonts adobe-source-han-serif-hk-fonts adobe-source-han-serif-jp-fonts adobe-source-han-serif-kr-fonts adobe-source-han-serif-tw-fonts \
+    adobe-source-han-sans-cn-fonts adobe-source-han-sans-hk-fonts adobe-source-han-sans-jp-fonts adobe-source-han-sans-kr-fonts adobe-source-han-sans-tw-fonts \
+    ttf-dejavu nerd-fonts ttf-ubuntu-font-family \
+    ttf-arphic-ukai ttf-arphic-uming \
+    texlive texlive-lang graphviz pandoc \
+    hspell nuspell libvoikko hunspell hunspell-en_us \
+    xdebug php-fpm php-pgsql php-sqlite php-redis php-mongodb php-imagick php-gd php-intl php-enchant php-snmp php-tidy php-xsl php-sodium php-odbc php-pspell \
+    dart haxe lua \
+    erlang elixir rebar \
+    jdk-openjdk libxcrypt-compat \
+    nginx mariadb postgresql rabbitmq redis supervisor
+RUN pacman -Scc --noconfirm
 
+RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
+RUN useradd -s /bin/zsh -m deploy
+RUN passwd -l deploy
+RUN echo 'deploy ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/101-deploy
+USER deploy
 RUN mkdir -p $HOME/downloads $HOME/build $HOME/local $HOME/tmp
 
+# https://pkl-lang.org/main/current/pkl-cli/index.html#linux-executable
+ENV PKL_VERSION="0.25.1"
+RUN curl -L -o $HOME/downloads/pkl https://github.com/apple/pkl/releases/download/$PKL_VERSION/pkl-linux-amd64 \
+    && sudo cp $HOME/downloads/pkl /usr/local/bin/ \
+    && sudo chmod +x /usr/local/bin/pkl
+
+
+# https://github.com/envoyproxy/envoy
+ENV ENVOY_VERSION "1.32.2"
+RUN wget -q -O $HOME/downloads/envoy https://github.com/envoyproxy/envoy/releases/download/v${ENVOY_VERSION}/envoy-${ENVOY_VERSION}-linux-x86_64 \
+    && sudo cp $HOME/downloads/envoy /usr/local/bin/ \
+    && sudo chmod +x /usr/local/bin/envoy
+
+# https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos
+RUN wget -q -O $HOME/downloads/composer https://getcomposer.org/installer
+RUN cd $HOME/downloads \
+    && php composer \
+    && sudo cp composer.phar /usr/local/bin/composer
+
+
+# https://github.com/bazelbuild/bazelisk
+ENV BAZEL_VERSION "v1.25.0"
+RUN wget -q -O $HOME/downloads/bazel \
+    https://github.com/bazelbuild/bazelisk/releases/download/${BAZEL_VERSION}/bazelisk-linux-amd64
+RUN sudo cp $HOME/downloads/bazel /usr/local/bin && sudo chmod +x /usr/local/bin/bazel
+
+
+# https://min.io/download#/linux
+RUN wget -q -O $HOME/downloads/minio https://dl.min.io/server/minio/release/linux-amd64/minio \
+    && sudo cp $HOME/downloads/minio /usr/local/bin/ \
+    && sudo chmod +x /usr/local/bin/minio
+
+# https://github.com/amacneil/dbmate
+RUN curl -fsSL -o $HOME/downloads/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64 \
+    && sudo cp $HOME/downloads/dbmate /usr/local/bin/ \
+    && sudo chmod +x /usr/local/bin/dbmate
+
+# https://aur.archlinux.org/packages/ttf-arphic-tex-extra
+ENV ARPHIC_TTF_VERSION "20161212-1"
+RUN git clone https://aur.archlinux.org/ttf-arphic-tex-extra.git $HOME/downloads/ttf-arphic-tex-extra \
+    && cd $HOME/downloads/ttf-arphic-tex-extra/ \
+    && makepkg \
+    && sudo pacman -U --noconfirm ttf-arphic-tex-extra-${ARPHIC_TTF_VERSION}-any.pkg.tar.zst
+
 # https://github.com/ohmyzsh/ohmyzsh
 RUN git clone https://github.com/ohmyzsh/ohmyzsh.git $HOME/.oh-my-zsh
-RUN cp $HOME/.oh-my-zsh/templates/zshrc.zsh-template $HOME/.zshrc \
-    && echo 'export LANG=en_US.UTF-8' >> $HOME/.zshrc \
+RUN cp $HOME/.oh-my-zsh/templates/zshrc.zsh-template $HOME/.zshrc
+RUN echo 'export LANG=en_US.UTF-8' >> $HOME/.zshrc \
     && echo 'export LC_ALL=en_US.UTF-8' >> $HOME/.zshrc \
+    && echo 'export EDITOR=vim' >> $HOME/.zshrc \
     && echo 'export PATH=$HOME/.local/bin:$PATH' >> $HOME/.zshrc
 
 RUN git config --global core.quotepath false \
@@ -44,77 +94,289 @@ RUN git config --global core.quotepath false \
 RUN echo 'set-option -g history-limit 102400' > $HOME/.tmux.conf \
     && echo 'set-option -g default-shell "/bin/zsh"' >> $HOME/.tmux.conf
 
+# https://musl.cc/
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/x86_64-linux-musl-cross.tgz \
+    && tar xf $HOME/downloads/x86_64-linux-musl-cross.tgz -C $HOME/local \
+    && echo 'export PATH=$HOME/local/x86_64-linux-musl-cross/bin:$PATH' >> $HOME/.zshrc
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/armv7l-linux-musleabihf-cross.tgz \
+    && tar xf $HOME/downloads/armv7l-linux-musleabihf-cross.tgz -C $HOME/local \
+    && echo 'export PATH=$HOME/local/armv7l-linux-musleabihf-cross/bin:$PATH' >> $HOME/.zshrc
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz \
+    && tar xf $HOME/downloads/aarch64-linux-musl-cross.tgz -C $HOME/local \
+    && echo 'export PATH=$HOME/local/aarch64-linux-musl-cross/bin:$PATH' >> $HOME/.zshrc
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/riscv64-linux-musl-cross.tgz \
+    && tar xf $HOME/downloads/riscv64-linux-musl-cross.tgz -C $HOME/local \
+    && echo 'export PATH=$HOME/local/riscv64-linux-musl-cross/bin:$PATH' >> $HOME/.zshrc
+
+
+# https://pip.pypa.io/en/stable/installation/
+RUN zsh -c ". $HOME/.zshrc \
+    && python3 -m venv $HOME/local/python3 \
+    && . $HOME/local/python3/bin/activate \
+    && pip install --upgrade pip \
+    && pip install ansible paramiko conan \
+    && pip install grpcio-tools grpcio-health-checking"
+RUN echo 'source $HOME/local/python3/bin/activate' >> $HOME/.zshrc
+RUN echo 'export ANSIBLE_HOST_KEY_CHECKING=False' >> $HOME/.zshrc \
+    && echo 'alias peony="ANSIBLE_LOG_PATH=$HOME/tmp/$(date +%Y%m%d%H%M%S).log ansible-playbook"' >> $HOME/.zshrc
+
+
+# https://github.com/rbenv/rbenv
+# https://github.com/rbenv/ruby-build/tree/master/share/ruby-build
+ENV RUBY_VERSION "3.3.6"
+RUN git clone https://github.com/rbenv/rbenv.git $HOME/.rbenv \
+    && git clone https://github.com/rbenv/ruby-build.git $HOME/.rbenv/plugins/ruby-build \
+    && git clone https://github.com/rbenv/rbenv-vars.git $HOME/.rbenv/plugins/rbenv-vars 
+RUN echo 'eval "$(~/.rbenv/bin/rbenv init - zsh)"' >> ~/.zshrc
+# https://github.com/rbenv/ruby-build
+RUN zsh -c "source $HOME/.zshrc \
+    && rbenv install ${RUBY_VERSION} \
+    && rbenv global ${RUBY_VERSION} \
+    && gem install bundler"
+
+# https://go.dev/doc/install
+ENV GO_VERSION "1.23.4"
+RUN wget -q -P $HOME/downloads https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
+RUN tar xf $HOME/downloads/go${GO_VERSION}.linux-amd64.tar.gz -C $HOME/local
+RUN echo 'export PATH=$HOME/local/go/bin:$PATH' >> $HOME/.zshrc \
+    && echo 'export GOPATH=$HOME/go' >> $HOME/.zshrc \
+    && echo 'export PATH="$(go env GOPATH)/bin:$PATH"' >> $HOME/.zshrc
+# https://code.visualstudio.com/docs/languages/go
+RUN zsh -c "source $HOME/.zshrc \
+    && go install golang.org/x/tools/gopls@latest \
+    && go install github.com/go-delve/delve/cmd/dlv@latest \
+    && go install honnef.co/go/tools/cmd/staticcheck@latest"
+
+# https://github.com/sdkman/sdkman-cli
+# https://docs.gradle.org/current/userguide/compatibility.html
+ENV JDK_VERSION "23-open"
+ENV GRADLE_VERSION "8.11.1"
+ENV THRIFT_JAVA_VERSION "19.0.2-open"
+ENV THRIFT_GRADLE_VERSION "7.6.4"
+RUN curl -s "https://get.sdkman.io" | bash
+RUN sed -i -e 's/sdkman_auto_answer=false/sdkman_auto_answer=true/g' $HOME/.sdkman/etc/config
+RUN zsh -c "source $HOME/.zshrc \
+    && sdk install java ${JDK_VERSION} \
+    && sdk install ant \
+    && sdk install maven \
+    && sdk install gradle ${GRADLE_VERSION} \
+    && sdk install kotlin \
+    && sdk install java  ${THRIFT_JAVA_VERSION} \
+    && sdk install gradle ${THRIFT_GRADLE_VERSION} \
+    && sdk default java ${JDK_VERSION} \
+    && sdk default gradle ${GRADLE_VERSION}"
+
 # https://github.com/nvm-sh/nvm
 ENV NVM_VERSION "v0.40.1"
 RUN git clone -b ${NVM_VERSION} https://github.com/nvm-sh/nvm.git $HOME/.nvm
 RUN echo 'export NVM_DIR="$HOME/.nvm"' >> $HOME/.zshrc \
     && echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $HOME/.zshrc \
     && echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> $HOME/.zshrc
-RUN zsh -c "source $HOME/.zshrc && nvm install --lts && npm install -g yarn"
+# https://stackoverflow.com/questions/37324519/node-sass-does-not-yet-support-your-current-environment-linux-64-bit-with-false
+RUN zsh -c "source $HOME/.zshrc \
+    && nvm install stable \
+    && nvm use stable \
+    && npm install -g yarn \
+    && nvm install --lts \
+    && nvm use --lts \
+    && npm install -g yarn \
+    && nvm install lts/fermium \
+    && nvm use lts/fermium \
+    && npm install -g yarn"
+
+# https://www.rust-lang.org/tools/install
+RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+# https://doc.rust-lang.org/nightly/rustc/platform-support.html
+RUN zsh -c "source $HOME/.cargo/env \
+    && rustup component add rust-analyzer \
+    && rustup target add armv7-unknown-linux-gnueabihf \
+    && rustup target add aarch64-unknown-linux-gnu \
+    && rustup target add x86_64-unknown-linux-musl \
+    && rustup target add aarch64-unknown-linux-musl \
+    && rustup target add loongarch64-unknown-linux-gnu"
+RUN zsh -c "source $HOME/.zshrc \
+    && cargo install --locked cargo-outdated \
+    && cargo install diesel_cli \
+    && cargo install mdbook"
+
+# https://www.swift.org/download/#releases
+ENV SWIFT_VERSION "6.0.2"
+RUN wget -q -P $HOME/downloads https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2404/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu24.04.tar.gz \
+    && tar xf $HOME/downloads/swift-${SWIFT_VERSION}-RELEASE-ubuntu24.04.tar.gz -C $HOME/local \
+    && echo "export PATH=\$HOME/local/swift-${SWIFT_VERSION}-RELEASE-ubuntu24.04/bin:\$PATH" >> $HOME/.zshrc
+
+# https://github.com/microsoft/vcpkg
+RUN git clone https://github.com/microsoft/vcpkg.git $HOME/local/vcpkg
+RUN $HOME/local/vcpkg/bootstrap-vcpkg.sh \
+    && echo 'export VCPKG_DISABLE_METRICS=1' >> $HOME/.zshrc
 
-RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
-    && locale-gen \
-    && update-locale LANG=en_US.UTF-8 
-RUN update-alternatives --set editor /usr/bin/vim.basic
-RUN mkdir -p $HOME/downloads $HOME/tmp
 
 # https://opensearch.org/downloads.html#opensearch
-ENV OPENSEARCH_VERSION "2.17.1"
-ENV OPENSEARCH_JAVA_HOME "/opt/opensearch-${OPENSEARCH_VERSION}/jdk"
+ENV OPENSEARCH_VERSION "2.18.0"
 RUN wget -q -P $HOME/downloads \
     https://artifacts.opensearch.org/releases/bundle/opensearch/${OPENSEARCH_VERSION}/opensearch-${OPENSEARCH_VERSION}-linux-x64.tar.gz
-RUN cd /opt && tar xf $HOME/downloads/opensearch-${OPENSEARCH_VERSION}-linux-x64.tar.gz \
-    && mv /opt/opensearch-${OPENSEARCH_VERSION} /opt/opensearch \
-    && echo "network.host: 0.0.0.0" >> /opt/opensearch/config/opensearch.yml \
+RUN tar xf $HOME/downloads/opensearch-${OPENSEARCH_VERSION}-linux-x64.tar.gz -C $HOME/tmp \
+    && sudo mv $HOME/tmp/opensearch-${OPENSEARCH_VERSION} /opt/opensearch
+
+# https://github.com/grpc/grpc
+ENV GRPC_VERSION "v1.69.0"
+RUN git clone --recurse-submodules -b $GRPC_VERSION https://github.com/grpc/grpc.git $HOME/downloads/grpc
+# ENV PROTOBUF_VERSION "v3.21.8"
+# RUN cd $HOME/downloads/grpc/third_party/protobuf \
+#     && git checkout ${PROTOBUF_VERSION} \
+#     && git submodule update --init --recursive
+RUN zsh -c "source $HOME/.zshrc \
+    && mkdir -pv $HOME/build/grpc \
+    && cd $HOME/build/grpc \
+    && CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Release \
+    -DgRPC_INSTALL=ON \
+    -DgRPC_SSL_PROVIDER=package \
+    -DgRPC_BUILD_TESTS=OFF \
+    -DCMAKE_INSTALL_PREFIX=$HOME/.local $HOME/downloads/grpc \
+    && make -j $(nproc --ignore=2) \
+    && make install"
+
+# https://github.com/grpc/grpc-web#code-generator-plugin
+ENV GRPC_WEB_PLUGIN_VERSION "1.5.0"
+RUN wget -q -O $HOME/.local/bin/protoc-gen-grpc-web \
+    https://github.com/grpc/grpc-web/releases/download/${GRPC_WEB_PLUGIN_VERSION}/protoc-gen-grpc-web-${GRPC_WEB_PLUGIN_VERSION}-linux-x86_64
+RUN chmod +x $HOME/.local/bin/protoc-gen-grpc-web
+
+# https://github.com/protocolbuffers/protobuf-javascript
+ENV GRPC_JS_PLUGIN_VERSION "3.21.4"
+RUN wget -q -P $HOME/downloads \
+    https://github.com/protocolbuffers/protobuf-javascript/releases/download/v${GRPC_JS_PLUGIN_VERSION}/protobuf-javascript-${GRPC_JS_PLUGIN_VERSION}-linux-x86_64.tar.gz
+RUN mkdir -p $HOME/build/protobuf-javascript \
+    && tar xf $HOME/downloads/protobuf-javascript-${GRPC_JS_PLUGIN_VERSION}-linux-x86_64.tar.gz -C $HOME/build/protobuf-javascript \
+    && cp $HOME/build/protobuf-javascript/bin/protoc-gen-js $HOME/.local/bin/
+
+# https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/
+# https://github.com/grpc/grpc-java
+ENV GRPC_JAVA_PLUGIN_VERSION "1.68.2"
+RUN wget -q -O $HOME/.local/bin/grpc_java_plugin \
+    https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/${GRPC_JAVA_PLUGIN_VERSION}/protoc-gen-grpc-java-${GRPC_JAVA_PLUGIN_VERSION}-linux-x86_64.exe
+RUN chmod +x $HOME/.local/bin/grpc_java_plugin
+
+# https://github.com/grpc/grpc-node
+# https://github.com/grpc/grpc-node/tree/master/examples/helloworld/static_codegen
+RUN zsh -c "source $HOME/.zshrc && npm install -g grpc-tools"
+
+# https://grpc.io/docs/languages/go/quickstart/
+RUN zsh -c "source $HOME/.zshrc \
+    && go install google.golang.org/protobuf/cmd/protoc-gen-go@latest \
+    && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest"
+
+# https://github.com/fullstorydev/grpcurl?tab=readme-ov-file#from-source
+RUN zsh -c "source $HOME/.zshrc \
+    go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest"
+
+# https://github.com/google/flatbuffers
+ENV FLATBUFFERS_VERSION "v24.3.25"
+RUN git clone -b $FLATBUFFERS_VERSION https://github.com/google/flatbuffers.git $HOME/downloads/flatbuffers
+RUN zsh -c "source $HOME/.zshrc \
+    && mkdir -pv $HOME/build/flatbuffers \
+    && cd $HOME/build/flatbuffers \
+    && CC=clang CXX=clang++ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF \
+    -DCMAKE_INSTALL_PREFIX=$HOME/.local $HOME/downloads/flatbuffers \
+    && make -j $(nproc --ignore=2) \
+    && make install"
+
+
+# https://opensearch.org/docs/latest/opensearch/install/tar/
+RUN echo "network.host: 0.0.0.0" >> /opt/opensearch/config/opensearch.yml \
     && echo "discovery.type: single-node" >> /opt/opensearch/config/opensearch.yml \
-    && echo "plugins.security.disabled: true" >> /opt/opensearch/config/opensearch.yml
+    && echo "plugins.security.disabled: true" >> /opt/opensearch/config/opensearch.yml \
+    && sudo chown -R nobody:nobody /opt/opensearch
 
-RUN wget -q -O /usr/local/bin/minio https://dl.min.io/server/minio/release/linux-amd64/minio
-RUN chmod 555 /usr/local/bin/minio \
-    && mkdir -p /var/lib/minio/data \
-    && chown -R nobody /var/lib/minio
+RUN sudo mkdir -p /var/lib/minio/data && sudo chown -R nobody:nobody /var/lib/minio
 
 # https://www.rabbitmq.com/access-control.html#loopback-users
-RUN echo 'loopback_users = none' >> /etc/rabbitmq/rabbitmq.conf \
-    && sed -i "s/NODENAME.*/NODENAME=palm/g" /etc/rabbitmq/rabbitmq-env.conf \
-    && rabbitmq-plugins enable rabbitmq_mqtt \
-    && rabbitmq-plugins enable rabbitmq_management
+RUN echo 'loopback_users = none' | sudo tee -a /etc/rabbitmq/rabbitmq.conf \
+    && sudo sed -i "s/NODENAME.*/NODENAME=palm/g" /etc/rabbitmq/rabbitmq-env.conf \
+    && sudo rabbitmq-plugins enable rabbitmq_mqtt \
+    && sudo rabbitmq-plugins enable rabbitmq_management
+
+RUN cd /usr && sudo mariadb-install-db --datadir=/var/lib/mysql --user=mysql
 
-RUN mkdir /var/lib/postgres && chown -R postgres:postgres /var/lib/postgres
-RUN su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D /var/lib/postgres/data"
-RUN echo "listen_addresses = '0.0.0.0'" >> /var/lib/postgres/data/postgresql.conf \
-    && echo "host  all  all 0.0.0.0/0 md5" >> /var/lib/postgres/data/pg_hba.conf 
+RUN sudo -s -u postgres /usr/bin/initdb -D /var/lib/postgres/data
+RUN echo "listen_addresses = '0.0.0.0'" | sudo tee -a /var/lib/postgres/data/postgresql.conf \
+    && echo "host  all  all 0.0.0.0/0 md5" | sudo tee -a /var/lib/postgres/data/pg_hba.conf \
+    && sudo mkdir /run/postgresql \
+    && sudo chown -R postgres:postgres /run/postgresql
 
 ADD etc/redis/* /etc/redis/
-RUN mkdir -p /var/lib/redis \
-    && cd /var/lib/redis \
-    && mkdir single node-1 node-2 node-3 node-4 node-5 node-6 \
-    && chown -R redis:redis /var/lib/redis \
-    && chmod 750 /var/lib/redis
-
-RUN mkdir -p /var/www/html \
-    && echo "<?php phpinfo(); ?>" > /var/www/html/info.php \
-    && echo "daemon off;" >> /etc/nginx/nginx.conf \
-    && sed -i '35,79d' /etc/nginx/nginx.conf \
-    && sed -i '35i include sites-enabled/*.conf;' /etc/nginx/nginx.conf \
-    && sed -i "s/error_log =.*/error_log = log\/php-fpm.log/g" /etc/php/8.3/fpm/php-fpm.conf
-ADD etc/nginx/sites-enabled/default.conf /etc/nginx/sites-enabled/default.conf
+RUN sudo mkdir -p /var/lib/redis \
+    && sudo mkdir /var/lib/redis/single /var/lib/redis/node-1 /var/lib/redis/node-2 /var/lib/redis/node-3 /var/lib/redis/node-4 /var/lib/redis/node-5 /var/lib/redis/node-6 \
+    && sudo chown -R redis:redis /var/lib/redis \
+    && sudo chmod 750 /var/lib/redis
 
-ADD etc/supervisor /etc/supervisor
+RUN sudo mkdir -p /var/www/html \
+    && echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php \
+    && echo "daemon off;" | sudo tee -a /etc/nginx/nginx.conf \
+    && sudo sed -i '35,79d' /etc/nginx/nginx.conf \
+    && sudo sed -i '35i include sites-enabled/*.conf;' /etc/nginx/nginx.conf \
+    && sudo sed -i "s/error_log =.*/error_log = log\/php-fpm.log/g" /etc/php/php-fpm.conf
+ADD etc/nginx/sites-enabled/localhost.conf /etc/nginx/sites-enabled/localhost.conf
 
-# git rev-parse --short HEAD
-ENV MING_VERSION "530977a93"
-RUN git clone --depth=1 --branch development https://github.com/iapt-platform/mint.git $HOME/workspace/mint
-RUN zsh -c "source $HOME/.zshrc \
-    && cd $HOME/workspace/mint && git checkout ${MING_VERSION} \
-    && cd $HOME/workspace/mint/api-v8 && composer install && npm install \
-    && cd $HOME/workspace/mint/api-v8/public && composer install && npm install \
-    && cd $HOME/workspace/mint/dashboard-v4/dashboard && yarn install"
+# php -i
+# <?php php_info(); ?>
+# <?php xdebug_info(); ?>
+RUN sudo sed -i 's/memory_limit =.*/memory_limit = 1G/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=bcmath/extension=bcmath/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=bz2/extension=bz2/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=calendar/extension=calendar/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=enchant/extension=enchant/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=exif/extension=exif/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=ftp/extension=ftp/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=gd/extension=gd/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=gettext/extension=gettext/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=gmp/extension=gmp/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=iconv/extension=iconv/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=intl/extension=intl/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=mysqli/extension=mysqli/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=odbc/extension=odbc/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=pdo_mysql/extension=pdo_mysql/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=pdo_odbc/extension=pdo_odbc/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=pdo_pgsql/extension=pdo_pgsql/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=pdo_sqlite/extension=pdo_sqlite/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=pgsql/extension=pgsql/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=pspell/extension=pspell/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=snmp/extension=snmp/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=soap/extension=soap/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=sockets/extension=sockets/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=sodium/extension=sodium/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=sqlite3/extension=sqlite3/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=tidy/extension=tidy/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=xsl/extension=xsl/' /etc/php/php.ini \
+    && sudo sed -i 's/;extension=redis/extension=redis/' /etc/php/conf.d/redis.ini \
+    && sudo sed -i 's/;extension=igbinary/extension=igbinary/' /etc/php/conf.d/igbinary.ini \
+    && sudo sed -i 's/; extension = imagick/extension=imagick/' /etc/php/conf.d/imagick.ini \
+    && sudo sed -i 's/;zend_extension=opcache/zend_extension=opcache/' /etc/php/php.ini \
+    && sudo sed -i 's/;zend_extension=xdebug/zend_extension=xdebug/' /etc/php/conf.d/xdebug.ini \
+    && sudo sed -i 's/;xdebug.mode=debug/xdebug.mode=develop,profile,coverage,debug/' /etc/php/conf.d/xdebug.ini \
+    && echo 'xdebug.start_with_request=yes' | sudo tee -a /etc/php/conf.d/xdebug.ini \
+    && echo 'xdebug.client_host=0.0.0.0' | sudo tee -a /etc/php/conf.d/xdebug.ini \
+    && echo 'xdebug.client_port=9003' | sudo tee -a /etc/php/conf.d/xdebug.ini \
+    && echo 'xdebug.cli_color = 2' | sudo tee -a /etc/php/conf.d/xdebug.ini
+
+
+RUN mkdir -p $HOME/.ssh \
+    && touch $HOME/.ssh/authorized_keys \
+    && echo 'GSSAPIAuthentication no' | sudo tee -a /etc/ssh/sshd_config \
+    && echo 'UseDNS no' | sudo tee -a /etc/ssh/sshd_config \
+    && echo 'PasswordAuthentication no' | sudo tee -a /etc/ssh/sshd_config \
+    && echo 'PermitRootLogin no' | sudo tee -a /etc/ssh/sshd_config \
+    && echo 'AllowUsers deploy' | sudo tee -a /etc/ssh/sshd_config \
+    && echo 'PrintLastLog no' | sudo tee -a /etc/ssh/sshd_config \
+    && sudo /usr/bin/ssh-keygen -A
+
+ADD etc/envoy.yaml /etc/
+RUN sudo mkdir -p /var/log/envoy
+ADD etc/supervisor /etc/supervisor
 
-RUN echo "$(date -u +%4Y%m%d%H%M%S)" | tee /VERSION
+RUN echo "$(date -u +%4Y%m%d%H%M%S)" | sudo tee /VERSION
 
 VOLUME /workspace
 WORKDIR /workspace
-EXPOSE 5432/tcp 6379/tcp 6371/tcp 6372/tcp 6373/tcp 6374/tcp 6375/tcp 6376/tcp 5672/tcp 15672/tcp 9200/tcp 9000/tcp 9001/tcp 10001/tcp
 
 CMD ["/bin/zsh", "-l"]

+ 65 - 0
docker/spring/README.md

@@ -0,0 +1,65 @@
+# USAGE
+
+- add to `/etc/sysctl.d/60-palm.conf` and then `reboot` or `sysctl --system`
+
+  ```text
+  vm.overcommit_memory = 1
+  vm.max_map_count = 262144
+  ```
+
+- start container [dashboard](http://localhost:10001)
+
+  ```bash
+  $ cd ~/workspace
+  $ ./saturn-xiv/palm/docker/spring/start.sh
+  > sudo supervisord -c /etc/supervisor/supervisord.conf
+  # init redis cluster
+  > sudo /etc/redis/clusters-init.sh
+  ```
+
+- PostgreSql
+
+  ```bash
+  psql -h 127.0.0.1 -p 5432 -U postgres
+  ```
+
+- MySql
+
+  ```bash
+  # reset root's password
+  > sudo mariadb-secure-installation
+  mariadb -h 127.0.0.1 -P 3306 -u root -p
+  ```
+
+- Redis
+
+  ```bash
+  # connect to redis cluster
+  redis-cli -c -h 127.0.0.1 -p 6371
+  # check cluster status
+  redis-cli --cluster check 127.0.0.1:6371
+  ```
+
+- Minio [dashboard](http://localhost:9091) (`admin:12345678`)
+
+- RabbitMQ [dashboard](http://localhost:15672) (`guest:guest`)
+
+- Php [info.php](http://localhost:8080/info.php) [XDebug](https://wiki.archlinux.org/index.php/PHP#XDebug) [XDebug mode](https://xdebug.org/docs/install#mode)
+
+  ```bash
+  php -r "var_dump(extension_loaded('xdebug'));"
+  ```
+
+- OpenSearch
+
+  ```bash
+  # show info
+  curl -X GET http://localhost:9200
+  curl -X GET http://localhost:9200/_cat/plugins?v
+  ```
+
+- Vcpkg
+
+  ```bash
+  $HOME/local/vcpkg/vcpkg upgrade --no-dry-run
+  ```

+ 6 - 4
docker/spring/build.sh

@@ -3,12 +3,14 @@
 set -e
 
 export VERSION=$(date "+%4Y%m%d%H%M%S")
-export CODE="mint-spring"
+export CODE="palm-spring"
 
-podman pull ubuntu:latest
+podman pull archlinux:latest
 podman build -t $CODE .
-# podman save --format=oci-archive -o $CODE-$VERSION.tar $CODE
-# md5sum $CODE-$VERSION.tar >$CODE-$VERSION.md5
+podman save --format=oci-archive -o $CODE-$VERSION.tar $CODE
+split -d -b 1G $CODE-$VERSION.tar $CODE-$VERSION.tar.
+md5sum $CODE-$VERSION.tar* >$CODE-$VERSION.md5
+# cat $CODE-$VERSION.tar.?? >$CODE-$VERSION.tar
 
 echo "done($CODE-$VERSION.tar)."
 

+ 49 - 0
docker/spring/conan/conanfile.txt

@@ -0,0 +1,49 @@
+[requires]
+libxcrypt/4.4.28
+zlib/1.2.13
+libcurl/7.85.0
+openssl/1.1.1q
+boost/1.80.0
+cpp-httplib/0.11.2
+cpr/1.9.0
+nlohmann_json/3.11.2
+inja/3.3.0
+tomlplusplus/3.2.0
+yaml-cpp/0.7.0
+cppcodec/0.2
+libpq/14.5
+libpqxx/7.7.4
+# libmysqlclient/8.0.17
+mariadb-connector-c/3.1.12
+sqlite3/3.39.4
+sqlitecpp/3.2.0
+soci/4.0.3
+mongo-cxx-driver/3.6.7
+redis-plus-plus/1.3.3
+rabbitmq-c/0.11.0
+amqp-cpp/4.3.18
+zmqpp/4.2.0
+paho-mqtt-cpp/1.2.0
+libgit2/1.5.0
+libssh2/1.10.0
+# libpng/1.6.37
+serial/1.2.1
+# net-snmp/5.9.1
+# imgui/1.88
+flatbuffers/2.0.8
+protobuf/3.21.4
+grpc/1.50.0 
+
+[options]
+zeromq:encryption=None
+sqlite3:build_executable=False
+soci:with_sqlite3=True
+# soci:with_mysql=True
+soci:with_postgresql=True
+soci:with_boost=True
+boost:without_stacktrace=True
+boost:without_python=True
+
+[generators]
+cmake
+cmake_find_package

+ 26 - 0
docker/spring/conan/install.sh

@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -e
+
+. /etc/os-release
+export WORKSPACE=$PWD
+
+if [ "$#" -ne 1 ]
+then
+    echo "USAGE: $0 PROFILE"
+    exit 1
+fi
+
+export TARGET=$HOME/build/conan-$1
+
+if [ -d $TARGET ]
+then
+    rm -r $TARGET
+fi
+mkdir -p $TARGET
+cd $TARGET
+conan install --build=missing --profile:build=default --profile:host=$WORKSPACE/profiles/$1 $WORKSPACE
+
+echo "done($1)."
+
+exit 0

+ 18 - 0
docker/spring/conan/profiles/amd64

@@ -0,0 +1,18 @@
+target=x86_64-linux-gnu
+clang_version=15
+
+[settings]
+os=Linux
+arch=x86_64
+compiler=clang
+compiler.version=$clang_version
+compiler.libcxx=libstdc++11
+compiler.cppstd=20
+build_type=Release
+
+[env]
+CC=clang-$clang_version
+CXX=clang++-$clang_version
+CFLAGS="-target $target"
+CXXFLAGS="-target $target"
+LDFLAGS="--ld-path=mold"

+ 34 - 0
docker/spring/conan/profiles/arm64

@@ -0,0 +1,34 @@
+target=aarch64-linux-gnu
+gcc_version=12
+clang_version=15
+
+[settings]
+os=Linux
+arch=armv8
+compiler=clang
+compiler.version=$clang_version
+compiler.libcxx=libstdc++11
+compiler.cppstd=20
+build_type=Release
+
+boost:compiler=gcc
+boost:compiler.cppstd=11
+boost:compiler.version=$gcc_version
+boost:compiler.libcxx=libstdc++11
+
+[env]
+CHOST=$target
+CC=clang-$clang_version
+CXX=clang++-$clang_version
+CFLAGS="-target $target -ccc-gcc-name $target-gcc-$gcc_version"
+CXXFLAGS="-target $target -ccc-gcc-name $target-gcc-$gcc_version"
+LDFLAGS="--ld-path=ld.lld-$clang_version"
+
+boost:CC=$target-gcc-$gcc_version
+boost:CXX=$target-g++-$gcc_version
+boost:CFLAGS=""
+boost:CXXFLAGS=""
+boost:LDFLAGS=""
+
+[options]
+libpng:neon=False

+ 34 - 0
docker/spring/conan/profiles/armhf

@@ -0,0 +1,34 @@
+target=arm-linux-gnueabihf
+gcc_version=12
+clang_version=15
+
+[settings]
+os=Linux
+arch=armv7hf
+compiler=clang
+compiler.version=$clang_version
+compiler.libcxx=libstdc++11
+compiler.cppstd=20
+build_type=Release
+
+boost:compiler=gcc
+boost:compiler.cppstd=11
+boost:compiler.version=$gcc_version
+boost:compiler.libcxx=libstdc++11
+
+[env]
+CHOST=$target
+CC=clang-$clang_version
+CXX=clang++-$clang_version
+CFLAGS="-target $target -ccc-gcc-name $target-gcc-$gcc_version"
+CXXFLAGS="-target $target -ccc-gcc-name $target-gcc-$gcc_version"
+LDFLAGS="--ld-path=ld.lld-$clang_version"
+
+boost:CC=$target-gcc-$gcc_version
+boost:CXX=$target-g++-$gcc_version
+boost:CFLAGS=""
+boost:CXXFLAGS=""
+boost:LDFLAGS=""
+
+[options]
+libpng:neon=False

+ 12 - 0
docker/spring/conan/toolchains/amd64.cmake

@@ -0,0 +1,12 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+
+set(target x86_64-linux-gnu)
+set(clang_version 15)
+
+set(CMAKE_C_COMPILER clang-${clang_version})
+set(CMAKE_C_COMPILER_TARGET ${target})
+set(CMAKE_CXX_COMPILER clang++-${clang_version})
+set(CMAKE_CXX_COMPILER_TARGET ${target})
+set(CMAKE_CXX_FLAGS "-stdlib=libstdc++")
+set(CMAKE_EXE_LINKER_FLAGS "--ld-path=mold -Wl,--build-id=sha1")

+ 18 - 0
docker/spring/conan/toolchains/arm64.cmake

@@ -0,0 +1,18 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+set(target aarch64-linux-gnu)
+set(gcc_version 12)
+set(clang_version 15)
+
+set(CMAKE_C_COMPILER clang-${clang_version})
+set(CMAKE_C_COMPILER_TARGET ${target})
+set(CMAKE_CXX_COMPILER clang++-${clang_version})
+set(CMAKE_CXX_COMPILER_TARGET ${target})
+set(CMAKE_C_FLAGS "-ccc-gcc-name ${target}-gcc-${gcc_version}")
+set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -ccc-gcc-name ${target}-gcc-${gcc_version}")
+set(CMAKE_EXE_LINKER_FLAGS "--ld-path=ld.lld-${clang_version} -Wl,--build-id=sha1")
+
+set(CMAKE_FIND_ROOT_PATH /usr/${target})
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+

+ 17 - 0
docker/spring/conan/toolchains/armhf.cmake

@@ -0,0 +1,17 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR armv7l)
+
+set(target arm-linux-gnueabihf)
+set(gcc_version 12)
+set(clang_version 15)
+
+set(CMAKE_C_COMPILER clang-${clang_version})
+set(CMAKE_C_COMPILER_TARGET ${target})
+set(CMAKE_CXX_COMPILER clang++-${clang_version})
+set(CMAKE_CXX_COMPILER_TARGET ${target})
+set(CMAKE_C_FLAGS "-ccc-gcc-name ${target}-gcc-${gcc_version}")
+set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -ccc-gcc-name ${target}-gcc-${gcc_version}")
+set(CMAKE_EXE_LINKER_FLAGS "--ld-path=ld.lld-${clang_version} -Wl,--build-id=sha1")
+
+set(CMAKE_FIND_ROOT_PATH /usr/${target})
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

+ 86 - 0
docker/spring/etc/envoy.yaml

@@ -0,0 +1,86 @@
+admin:
+  access_log:
+    - name: envoy.admin_access_loggers.stdout
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
+  address:
+    socket_address: { address: 0.0.0.0, port_value: 18081 }
+
+overload_manager:
+  resource_monitors:
+    - name: "envoy.resource_monitors.global_downstream_max_connections"
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+        max_active_downstream_connections: 1000
+
+static_resources:
+  listeners:
+    - name: listener_0
+      address:
+        socket_address:
+          address: 0.0.0.0
+          port_value: 18080
+      filter_chains:
+        - filters:
+            - name: envoy.filters.network.http_connection_manager
+              typed_config:
+                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+                stat_prefix: ingress_http
+                upgrade_configs:
+                  - upgrade_type: websocket
+                access_log:
+                  - name: envoy.access_loggers.stdout
+                    typed_config:
+                      "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
+                http_filters:
+                  - name: envoy.filters.http.grpc_web
+                    typed_config:
+                      "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
+                  - name: envoy.filters.http.cors
+                    typed_config:
+                      "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
+                  - name: envoy.filters.http.router
+                    typed_config:
+                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+                route_config:
+                  name: web_route
+                  virtual_hosts:
+                    - name: lilac_service
+                      domains: ["*"]
+                      typed_per_filter_config:
+                        envoy.filters.http.cors:
+                          "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy
+                          allow_origin_string_match:
+                            - prefix: "*"
+                          allow_methods: GET, PUT, DELETE, POST, OPTIONS
+                          allow_headers: accept-language,authorization,keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
+                          allow_credentials: true
+                          max_age: "1728000"
+                          expose_headers: custom-header-1,grpc-status,grpc-message
+                      routes:
+                        - match: { prefix: "/" }
+                          route:
+                            cluster: lilac_service
+                            timeout: 0s
+                            max_stream_duration:
+                              grpc_timeout_header_max: 0s
+  clusters:
+    - name: lilac_service
+      connect_timeout: 0.25s
+      type: LOGICAL_DNS
+      dns_lookup_family: V4_ONLY
+      typed_extension_protocol_options:
+        envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+          "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+          explicit_http_config:
+            http2_protocol_options: {}
+      lb_policy: round_robin
+      load_assignment:
+        cluster_name: lilac_service_0
+        endpoints:
+          - lb_endpoints:
+              - endpoint:
+                  address:
+                    socket_address:
+                      address: 127.0.0.1
+                      port_value: 10001

+ 1 - 1
docker/spring/etc/nginx/sites-enabled/default.conf → docker/spring/etc/nginx/sites-enabled/localhost.conf

@@ -2,7 +2,7 @@ log_format custom '$remote_addr - [$time_iso8601] "$request" $status $body_bytes
 types_hash_bucket_size 1024;
 
 server {
-    listen 8080;
+    listen 1080;
     server_name _;
     index index.html index.php;
     root /var/www/html;

+ 5 - 0
docker/spring/etc/supervisor/conf.d/envoy.conf

@@ -0,0 +1,5 @@
+[program:envoy]
+command=/usr/local/bin/envoy -c /etc/envoy.yaml --log-level info --log-path /var/log/envoy/access.log
+autostart=true
+autorestart=true
+user=root

+ 1 - 1
docker/spring/etc/supervisor/conf.d/minio.conf

@@ -4,4 +4,4 @@ autostart=true
 autorestart=true
 user=nobody
 directory=/var/lib/minio
-environment=MINIO_ADDRESS="0.0.0.0:9000",MINIO_CONSOLE_ADDRESS="0.0.0.0:9001",MINIO_ROOT_USER="admin",MINIO_ROOT_PASSWORD="12345678"
+environment=MINIO_ADDRESS="0.0.0.0:9090",MINIO_CONSOLE_ADDRESS="0.0.0.0:9091",MINIO_ROOT_USER="admin",MINIO_ROOT_PASSWORD="12345678"

+ 5 - 0
docker/spring/etc/supervisor/conf.d/mysql.conf

@@ -0,0 +1,5 @@
+[program:mysql]
+command=/usr/bin/mariadbd-safe --datadir='/var/lib/mysql' --user=mysql
+autostart=true
+autorestart=true
+user=root

+ 1 - 1
docker/spring/etc/supervisor/conf.d/redis.conf

@@ -1,5 +1,5 @@
 [program:redis-single]
-command=/usr/bin/redis-server /etc/redis/node-single.conf
+command=/usr/bin/redis-server /etc/redis/single.conf
 autostart=true
 autorestart=true
 user=redis

+ 5 - 0
docker/spring/etc/supervisor/conf.d/sshd.conf

@@ -0,0 +1,5 @@
+[program:sshd]
+command=/usr/bin/sshd -D -4 -p 10022
+autostart=true
+autorestart=true
+user=root

+ 0 - 21
docker/spring/forward.sh

@@ -1,21 +0,0 @@
-#!/bin/bash
-
-ssh -p 22 -L 3000:localhost:3000 $1
-
-export USAGE="$0 SSH_USER SSH_HOST SSH_PORT frontend|backend"
-
-if [ "$#" -ne 4 ]; then
-    echo $USAGE
-    exit 1
-fi
-
-if [[ "$4" == "backend" ]]
-then
-    ssh -p $3 -L 8000:localhost:8000 $1@$2
-elif [[ "$1" == "frontend" ]]
-then
-    ssh -p $3 -L 3000:localhost:3000 $1@$2
-else
-    echo $USAGE
-    exit 1
-fi

+ 4 - 28
docker/spring/start.sh

@@ -1,34 +1,10 @@
 #!/bin/bash
 
-export CODE="mint-spring"
+export CODE="palm-spring"
 export NAME="$CODE-$USER"
 
-export USAGE="USAGE: $0 services|frontend|backend|shell"
-export PODMAN="podman run --rm -it --events-backend=file --hostname=mint --network host -v $PWD:/workspace:z $CODE"
-
-if [ "$#" -ne 1 ]; then
-    echo $USAGE
-    exit 1
-fi
-
-if [[ "$1" == "services" ]]
-then
-    echo "start mint services"
-elif [[ "$1" == "backend" ]]
-then
-    echo "start mint frontend services"
-elif [[ "$1" == "frontend" ]]
-then
-    $PODMAN /usr/bin/zsh -c 'source $HOME/.zshrc && cd /workspace/dashboard-v4/dashboard && yarn start'
-elif [[ "$1" == "shell" ]]
-then
-    $PODMAN /usr/bin/zsh -l
+if podman container exists $NAME; then
+    podman start -i -a $NAME
 else
-    echo $USAGE
+    podman run --name $NAME -it --events-backend=file --hostname=palm --network host -v $PWD:/workspace:z $CODE
 fi
-
-# if podman container exists $NAME; then
-#     podman start -i -a $NAME
-# else
-#     podman run --name $NAME -it --events-backend=file --hostname=mint --network host -v $PWD:/workspace:z $CODE
-# fi

+ 400 - 0
docker/spring/ubuntu.Dockerfile

@@ -0,0 +1,400 @@
+# latest rolling devel
+FROM ubuntu:latest
+LABEL maintainer="Jeremy Zheng"
+
+ENV DEBIAN_FRONTEND noninteractive
+
+RUN apt update \
+    && apt -y upgrade \
+    && apt -y install debian-keyring debian-archive-keyring apt-transport-https software-properties-common curl wget gnupg
+
+# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test
+ENV AMD64_GCC_VERSION 13
+ENV GCC_VERSION 12
+RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
+RUN echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ $(lsb_release -cs) main restricted universe multiverse" > /etc/apt/sources.list
+RUN echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ $(lsb_release -cs)-updates main restricted universe multiverse" >> /etc/apt/sources.list
+RUN echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ $(lsb_release -cs)-security main restricted universe multiverse" >> /etc/apt/sources.list
+# https://apt.llvm.org/
+ENV CLANG_VERSION 16
+RUN echo "deb [arch=amd64] http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${CLANG_VERSION} main" > /etc/apt/sources.list.d/llvm.list
+RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
+# https://dart.dev/get-dart
+RUN wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/dart.gpg
+RUN echo 'deb [signed-by=/usr/share/keyrings/dart.gpg arch=amd64] https://storage.googleapis.com/download.dartlang.org/linux/debian stable main' | tee /etc/apt/sources.list.d/dart_stable.list
+# https://wiki.debian.org/ToolChain/Cross
+RUN dpkg --add-architecture armhf
+RUN dpkg --add-architecture arm64
+RUN dpkg --add-architecture riscv64
+RUN echo "deb [arch=armhf,arm64,riscv64] http://ports.ubuntu.com/ $(lsb_release -cs) main restricted universe multiverse" >> /etc/apt/sources.list
+RUN echo "deb [arch=armhf,arm64,riscv64] http://ports.ubuntu.com/ $(lsb_release -cs)-security main restricted universe multiverse" >> /etc/apt/sources.list
+RUN echo "deb [arch=armhf,arm64,riscv64] http://ports.ubuntu.com/ $(lsb_release -cs)-updates main restricted universe multiverse" >> /etc/apt/sources.list
+
+# https://launchpad.net/~ondrej/+archive/ubuntu/php
+RUN add-apt-repository -y ppa:ondrej/php
+# https://launchpad.net/~ondrej/+archive/ubuntu/nginx
+RUN add-apt-repository -y ppa:ondrej/nginx
+# https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa
+RUN add-apt-repository -y ppa:deadsnakes/ppa
+
+# https://www.envoyproxy.io/docs/envoy/latest/start/install#install-envoy-on-ubuntu-linux
+RUN curl -sL 'https://deb.dl.getenvoy.io/public/gpg.8115BA8E629CC074.key' | gpg --dearmor -o /usr/share/keyrings/getenvoy-keyring.gpg
+RUN echo a077cb587a1b622e03aa4bf2f3689de14658a9497a9af2c427bba5f4cc3c4723 /usr/share/keyrings/getenvoy-keyring.gpg | sha256sum --check
+RUN echo "deb [arch=amd64 signed-by=/usr/share/keyrings/getenvoy-keyring.gpg] https://deb.dl.getenvoy.io/public/deb/ubuntu $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/getenvoy.list
+RUN apt update && apt -y upgrade
+
+ENV LUA_VERSION "5.4"
+RUN apt-get install -y zsh git locales locales-all rsync openssh-client sshpass \
+    vim tzdata pwgen zip unzip tree tmux dialog asciidoc doxygen \
+    net-tools dnsutils net-tools iputils-arping iputils-ping telnet \
+    imagemagick ffmpeg fonts-dejavu-extra texlive-full \
+    build-essential g++-${GCC_VERSION} libstdc++-${GCC_VERSION}-dev \
+    g++-${AMD64_GCC_VERSION} libstdc++-${AMD64_GCC_VERSION}-dev \
+    crossbuild-essential-arm64 g++-${GCC_VERSION}-aarch64-linux-gnu libstdc++-${GCC_VERSION}-dev:arm64 \
+    crossbuild-essential-armhf g++-${GCC_VERSION}-arm-linux-gnueabihf libstdc++-${GCC_VERSION}-dev:armhf \
+    crossbuild-essential-riscv64 g++-${GCC_VERSION}-riscv64-linux-gnu libstdc++-${GCC_VERSION}-dev:riscv64 \
+    clang-${CLANG_VERSION} clangd-${CLANG_VERSION} clang-tools-${CLANG_VERSION} clang-format-${CLANG_VERSION} lldb-${CLANG_VERSION} lld-${CLANG_VERSION} \
+    cmake pkg-config libtool automake autoconf autoconf-archive binutils cpio mold \
+    debhelper bison flex ninja-build \
+    musl-tools musl-dev \
+    python3-full python3-dev \
+    php-fpm php-mbstring php-json php-xml php-pear php-bcmath php-curl php-zip \
+    php-mysql php-pgsql php-sqlite3 php-redis php-mongodb php-amqp php-zmq \
+    php-imagick php-gd phpunit \
+    php-intl php-soap \
+    liblua${LUA_VERSION}-dev dart haxe \
+    erlang rebar \
+    nginx-full rabbitmq-server redis postgresql mariadb-server getenvoy-envoy
+
+RUN update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${CLANG_VERSION} 100 \
+    && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${CLANG_VERSION} 100 \
+    && update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-${CLANG_VERSION} 100 \
+    && update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-${CLANG_VERSION} 100 \
+    && update-alternatives --install /usr/bin/lld lld /usr/bin/lld-${CLANG_VERSION} 100 \
+    && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${AMD64_GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${AMD64_GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/aarch64-linux-gnu-gcc aarch64-linux-gnu-gcc /usr/bin/aarch64-linux-gnu-gcc-${GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/aarch64-linux-gnu-g++ aarch64-linux-gnu-g++ /usr/bin/aarch64-linux-gnu-g++-${GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-${GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /usr/bin/arm-linux-gnueabihf-g++-${GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/riscv64-linux-gnu-gcc riscv64-linux-gnu-gcc /usr/bin/riscv64-linux-gnu-gcc-${GCC_VERSION} 100 \
+    && update-alternatives --install /usr/bin/riscv64-linux-gnu-g++ riscv64-linux-gnu-g++ /usr/bin/riscv64-linux-gnu-g++-${GCC_VERSION} 100
+
+
+# https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/
+# RUN wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | apt-key add -
+# RUN echo "deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
+# RUN apt update
+# RUN apt install -y mongodb
+# sudo chown root:root /usr/local/bin/pkl
+# && sudo chown root:root /usr/local/bin/envoy
+# && sudo chown root:root /usr/local/bin/minio
+# && sudo chown root:root /usr/local/bin/dbmate
+
+RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
+RUN useradd -s /bin/zsh -m deploy
+RUN passwd -l deploy
+RUN echo 'deploy ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/101-deploy
+USER deploy
+USER deploy
+
+RUN apt -y autoremove && apt -y clean
+
+RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
+    && locale-gen \
+    && update-locale LANG=en_US.UTF-8
+
+RUN update-alternatives --set editor /usr/bin/vim.basic
+
+RUN mkdir -p $HOME/downloads $HOME/build $HOME/local $HOME/tmp
+
+
+# https://github.com/ohmyzsh/ohmyzsh
+RUN git clone https://github.com/ohmyzsh/ohmyzsh.git $HOME/.oh-my-zsh
+RUN cp $HOME/.oh-my-zsh/templates/zshrc.zsh-template $HOME/.zshrc
+RUN echo 'export LANG=en_US.UTF-8' >> $HOME/.zshrc \
+    && echo 'export LC_ALL=en_US.UTF-8' >> $HOME/.zshrc \
+    && echo 'export PATH=$HOME/.local/bin:$PATH' >> $HOME/.zshrc \
+    && echo 'export PATH=$HOME/.yarn/bin:$PATH' >> $HOME/.zshrc
+
+RUN git config --global core.quotepath false \
+    && git config --global http.version HTTP/1.1 \
+    && git config --global pull.rebase false \
+    && git config --global url."https://".insteadOf git://
+RUN echo 'set-option -g history-limit 102400' > $HOME/.tmux.conf \
+    && echo 'set-option -g default-shell "/bin/zsh"' >> $HOME/.tmux.conf
+
+# https://musl.cc/
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/x86_64-linux-musl-cross.tgz \
+    && cd /opt \
+    && tar xf $HOME/downloads/x86_64-linux-musl-cross.tgz \
+    && echo 'export PATH=/opt/x86_64-linux-musl-cross/bin:$PATH' >> $HOME/.zshrc
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/armv7l-linux-musleabihf-cross.tgz \
+    && cd /opt \
+    && tar xf $HOME/downloads/armv7l-linux-musleabihf-cross.tgz \
+    && echo 'export PATH=/opt/armv7l-linux-musleabihf-cross/bin:$PATH' >> $HOME/.zshrc
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/aarch64-linux-musl-cross.tgz \
+    && cd /opt \
+    && tar xf $HOME/downloads/aarch64-linux-musl-cross.tgz \
+    && echo 'export PATH=/opt/aarch64-linux-musl-cross/bin:$PATH' >> $HOME/.zshrc
+RUN wget -q -P $HOME/downloads https://more.musl.cc/x86_64-linux-musl/riscv64-linux-musl-cross.tgz \
+    && cd /opt \
+    && tar xf $HOME/downloads/riscv64-linux-musl-cross.tgz \
+    && echo 'export PATH=/opt/riscv64-linux-musl-cross/bin:$PATH' >> $HOME/.zshrc
+
+
+# https://pip.pypa.io/en/stable/installation/
+# RUN sh -c ". $HOME/.profile && python3 -m ensurepip --upgrade"
+RUN sh -c ". $HOME/.profile \
+    && python3 -m venv $HOME/local/python3 \
+    && . $HOME/local/python3/bin/activate \
+    && pip install --upgrade pip \
+    && pip install cmake ansible paramiko conan supervisor"
+RUN echo 'source $HOME/local/python3/bin/activate' >> $HOME/.zshrc
+RUN echo 'export ANSIBLE_HOST_KEY_CHECKING=False' >> $HOME/.zshrc \
+    && echo 'alias peony="ANSIBLE_LOG_PATH=$HOME/tmp/$(date +%Y%m%d%H%M%S).log ansible-playbook"' >> $HOME/.zshrc
+
+# https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos
+RUN wget -q -O $HOME/downloads/composer https://getcomposer.org/installer
+RUN cd $HOME/downloads \
+    && php composer \
+    && mkdir -p $HOME/.local/bin \
+    && mv composer.phar $HOME/.local/bin/composer
+
+
+# https://github.com/bazelbuild/bazelisk
+ENV BAZEL_VERSION "v1.18.0"
+RUN wget -q -O $HOME/.local/bin/bazel \
+    https://github.com/bazelbuild/bazelisk/releases/download/${BAZEL_VERSION}/bazelisk-linux-amd64
+RUN chmod +x $HOME/.local/bin/bazel
+
+# https://github.com/rbenv/rbenv
+ENV RUBY_VERSION "3.2.2"
+RUN git clone https://github.com/rbenv/rbenv.git $HOME/.rbenv \
+    && git clone https://github.com/rbenv/ruby-build.git $HOME/.rbenv/plugins/ruby-build \
+    && git clone https://github.com/rbenv/rbenv-vars.git $HOME/.rbenv/plugins/rbenv-vars 
+RUN echo 'eval "$(~/.rbenv/bin/rbenv init - zsh)"' >> ~/.zshrc
+# https://github.com/rbenv/ruby-build
+# https://github.com/rbenv/ruby-build/wiki#ubuntudebianmint
+RUN apt-get install -y autoconf patch build-essential rustc libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev
+# FIXME
+# RUN zsh -c "source $HOME/.zshrc \
+#     && rbenv install ${RUBY_VERSION} \
+#     && rbenv global ${RUBY_VERSION} \
+#     && gem install bundler"
+
+# https://go.dev/doc/install
+ENV GO_VERSION "1.20.6"
+RUN wget -q -P $HOME/downloads https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
+RUN tar xf $HOME/downloads/go${GO_VERSION}.linux-amd64.tar.gz -C $HOME/local
+RUN echo 'export GOROOT=$HOME/local/go' >> $HOME/.zshrc \
+    && echo 'export PATH=$GOROOT/bin:$PATH' >> $HOME/.zshrc \
+    && echo 'export GOPATH=$HOME/go' >> $HOME/.zshrc
+
+# https://github.com/sdkman/sdkman-cli
+ENV JDK_VERSION "20.0.2-open"
+ENV GRADLE_VERSION "8.2.1"
+ENV THRIFT_JAVA_VERSION "19.0.2-open"
+ENV THRIFT_GRADLE_VERSION "7.6.2"
+RUN curl -s "https://get.sdkman.io" | bash
+RUN sed -i -e 's/sdkman_auto_answer=false/sdkman_auto_answer=true/g' $HOME/.sdkman/etc/config
+RUN zsh -c "source $HOME/.zshrc \
+    && sdk install java ${JDK_VERSION} \
+    && sdk install ant \
+    && sdk install maven \
+    && sdk install gradle ${GRADLE_VERSION} \
+    && sdk install kotlin \
+    && sdk install java  ${THRIFT_JAVA_VERSION} \
+    && sdk install gradle ${THRIFT_GRADLE_VERSION} \
+    && sdk default java ${JDK_VERSION} \
+    && sdk default gradle ${GRADLE_VERSION}"
+
+# https://github.com/nvm-sh/nvm
+ENV NVM_VERSION "v0.39.5"
+RUN git clone -b ${NVM_VERSION} https://github.com/nvm-sh/nvm.git $HOME/.nvm
+RUN echo 'export NVM_DIR="$HOME/.nvm"' >> $HOME/.zshrc \
+    && echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $HOME/.zshrc \
+    && echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> $HOME/.zshrc
+# https://stackoverflow.com/questions/37324519/node-sass-does-not-yet-support-your-current-environment-linux-64-bit-with-false
+RUN zsh -c "source $HOME/.zshrc \
+    && nvm install node \
+    && nvm use node \
+    && npm i yarn -g \
+    && nvm install --lts \
+    && nvm use --lts \
+    && npm i yarn -g \
+    && nvm install lts/fermium \
+    && nvm use lts/fermium \
+    && npm i yarn -g"
+RUN echo 'export PATH=$HOME/.yarn/bin:$PATH' >> $HOME/.zshrc
+
+# https://www.rust-lang.org/tools/install
+RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
+# https://doc.rust-lang.org/nightly/rustc/platform-support.html
+RUN zsh -c "source $HOME/.cargo/env \
+    && rustup component add rust-analyzer \
+    && rustup target add armv7-unknown-linux-gnueabihf \
+    && rustup target add aarch64-unknown-linux-gnu \
+    && rustup target add x86_64-unknown-linux-musl \
+    && rustup target add aarch64-unknown-linux-musl \
+    && rustup target add loongarch64-unknown-linux-gnu"
+
+RUN apt install -y libpq-dev libmysqlclient-dev libsqlite3-dev
+RUN zsh -c "source $HOME/.zshrc \
+    && cargo install diesel_cli \
+    && cargo install --locked cargo-outdated \
+    && cargo install mdbook"
+
+# https://www.swift.org/download/#releases
+ENV SWIFT_VERSION "5.8.1"
+RUN wget -q -P $HOME/downloads https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz \
+    && cd /opt \
+    && tar xf $HOME/downloads/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz \
+    && echo "export PATH=/opt/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04/bin:\$PATH" >> $HOME/.zshrc
+
+# https://github.com/microsoft/vcpkg
+RUN git clone https://github.com/microsoft/vcpkg.git $HOME/local/vcpkg
+RUN $HOME/local/vcpkg/bootstrap-vcpkg.sh \
+    && echo 'export VCPKG_DISABLE_METRICS=1' >> $HOME/.zshrc
+
+# https://opensearch.org/downloads.html#opensearch
+ENV OPENSEARCH_VERSION "2.9.0"
+RUN wget -q -P $HOME/downloads \
+    https://artifacts.opensearch.org/releases/bundle/opensearch/${OPENSEARCH_VERSION}/opensearch-${OPENSEARCH_VERSION}-linux-x64.tar.gz
+RUN tar xf $HOME/downloads/opensearch-${OPENSEARCH_VERSION}-linux-x64.tar.gz -C /opt \
+    && mv /opt/opensearch-${OPENSEARCH_VERSION} /opt/opensearch
+
+# https://min.io/download#/linux
+RUN wget -q -O /usr/bin/minio \
+    https://dl.min.io/server/minio/release/linux-amd64/minio
+RUN chmod +x /usr/bin/minio
+
+# https://github.com/grpc/grpc
+ENV GRPC_VERSION "v1.57.0"
+RUN git clone --recurse-submodules -b $GRPC_VERSION https://github.com/grpc/grpc.git $HOME/downloads/grpc
+# ENV PROTOBUF_VERSION "v3.21.8"
+# RUN cd $HOME/downloads/grpc/third_party/protobuf \
+#     && git checkout ${PROTOBUF_VERSION} \
+#     && git submodule update --init --recursive
+RUN zsh -c "source $HOME/.zshrc \
+    && mkdir -pv $HOME/build/grpc \
+    && cd $HOME/build/grpc \
+    && cmake -DCMAKE_BUILD_TYPE=Release \
+    -DgRPC_INSTALL=ON \
+    -DgRPC_SSL_PROVIDER=package \
+    -DgRPC_BUILD_TESTS=OFF \
+    -DCMAKE_INSTALL_PREFIX=$HOME/.local $HOME/downloads/grpc \
+    && make \
+    && make install"
+
+# https://github.com/grpc/grpc-web#code-generator-plugin
+ENV GRPC_WEB_PLUGIN_VERSION "1.4.2"
+RUN wget -q -O $HOME/.local/bin/protoc-gen-grpc-web \
+    https://github.com/grpc/grpc-web/releases/download/${GRPC_WEB_PLUGIN_VERSION}/protoc-gen-grpc-web-${GRPC_WEB_PLUGIN_VERSION}-linux-x86_64
+RUN chmod +x $HOME/.local/bin/protoc-gen-grpc-web
+
+# https://github.com/protocolbuffers/protobuf-javascript
+ENV GRPC_JS_PLUGIN_VERSION "3.21.2"
+RUN wget -q -P $HOME/downloads \
+    https://github.com/protocolbuffers/protobuf-javascript/releases/download/v${GRPC_JS_PLUGIN_VERSION}/protobuf-javascript-${GRPC_JS_PLUGIN_VERSION}-linux-x86_64.tar.gz
+RUN mkdir -p $HOME/build/protobuf-javascript \
+    && cd $HOME/build/protobuf-javascript \
+    && tar xf $HOME/downloads/protobuf-javascript-${GRPC_JS_PLUGIN_VERSION}-linux-x86_64.tar.gz \
+    && cp bin/protoc-gen-js $HOME/.local/bin/
+
+# https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/
+# https://github.com/grpc/grpc-java
+ENV GRPC_JAVA_PLUGIN_VERSION "1.57.2"
+RUN wget -q -O $HOME/.local/bin/grpc_java_plugin \
+    https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/${GRPC_JAVA_PLUGIN_VERSION}/protoc-gen-grpc-java-${GRPC_JAVA_PLUGIN_VERSION}-linux-x86_64.exe
+RUN chmod +x $HOME/.local/bin/grpc_java_plugin
+
+# https://github.com/grpc/grpc-node
+# https://github.com/grpc/grpc-node/tree/master/examples/helloworld/static_codegen
+RUN zsh -c "source $HOME/.zshrc \
+    && yarn global add grpc-tools"
+
+# https://grpc.io/docs/languages/go/quickstart/
+RUN zsh -c "source $HOME/.zshrc \
+    && go install google.golang.org/protobuf/cmd/protoc-gen-go@latest \
+    && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest"
+
+# https://github.com/google/flatbuffers
+ENV FLATBUFFERS_VERSION "v23.5.26"
+RUN git clone -b $FLATBUFFERS_VERSION https://github.com/google/flatbuffers.git $HOME/downloads/flatbuffers
+RUN zsh -c "source $HOME/.zshrc \
+    && mkdir -pv $HOME/build/flatbuffers \
+    && cd $HOME/build/flatbuffers \
+    && CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF \
+    -DCMAKE_INSTALL_PREFIX=$HOME/.local $HOME/downloads/flatbuffers \
+    && make \
+    && make install"
+
+# https://github.com/amacneil/dbmate
+RUN curl -fsSL -o $HOME/.local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
+RUN chmod +x $HOME/.local/bin/dbmate
+
+# https://github.com/apache/thrift
+# https://thrift.apache.org/docs/install/
+ENV THRIFT_VERSION "v0.18.1"
+RUN git clone -b $THRIFT_VERSION https://github.com/apache/thrift.git $HOME/downloads/thrift
+RUN apt install -y libboost-all-dev libevent-dev libz-dev zlib1g-dev \
+    mono-devel \
+    libglib2.0-dev \
+    libbit-vector-perl libclass-accessor-perl
+# Could not find method classifier() for arguments [test] on task ':testJar'
+
+# TODO 
+# composer: Continue as root/super user confirm
+# haxelib setup
+# haxelib install uuid
+# haxelib install hxcpp
+# FIXME make install && make install/fast
+# RUN zsh -c "source $HOME/.zshrc \
+#     && cd $HOME/downloads/thrift \
+#     && sdk use java ${THRIFT_JAVA_VERSION} \
+#     && sdk use gradle ${THRIFT_GRADLE_VERSION} \
+#     && ./bootstrap.sh \
+#     && ./configure MAKE=gmake CXXFLAGS='-g -O2' CFLAGS='-g -O2' --prefix=$HOME/.local --disable-tests"
+
+
+# ADD conan /opt/conan
+# RUN zsh -c "source $HOME/.zshrc && cd /opt/conan && ./install.sh amd64"
+# RUN zsh -c "source $HOME/.zshrc && cd /opt/conan && ./install.sh arm64"
+# RUN zsh -c "source $HOME/.zshrc && cd /opt/conan && ./install.sh armhf"
+
+# https://opensearch.org/docs/latest/opensearch/install/tar/
+RUN echo "network.host: 0.0.0.0" >> /opt/opensearch/config/opensearch.yml \
+    && echo "discovery.type: single-node" >> /opt/opensearch/config/opensearch.yml \
+    && echo "plugins.security.disabled: true" >> /opt/opensearch/config/opensearch.yml \
+    && chown -R nobody /opt/opensearch
+
+RUN mkdir -p /var/lib/minio/data \
+    && chown -R nobody /var/lib/minio
+
+RUN sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/mariadb.conf.d/50-server.cnf
+
+RUN su - postgres -c "/usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/data"
+RUN echo "listen_addresses = '0.0.0.0'" >> /var/lib/postgresql/data/postgresql.conf \
+    && echo "host  all  all 0.0.0.0/0 md5" >> /var/lib/postgresql/data/pg_hba.conf
+
+ADD etc/redis/* /etc/redis/
+RUN cd /var/lib \
+    && mkdir redis-s redis-1 redis-2 redis-3 redis-4 redis-5 redis-6 \
+    && chown redis:redis redis-s redis-1 redis-2 redis-3 redis-4 redis-5 redis-6 \
+    && chmod 750 redis-s redis-1 redis-2 redis-3 redis-4 redis-5 redis-6
+
+RUN mkdir -p /run/php \
+    && echo "<?php phpinfo(); ?>" > /var/www/html/info.php \
+    && echo "daemon off;" >> /etc/nginx/nginx.conf
+ADD etc/nginx.conf /etc/nginx/sites-enabled/default
+
+ADD etc/envoy.yaml /etc/
+ADD etc/supervisor /etc/supervisor
+
+RUN echo "$(date -u +%4Y%m%d%H%M%S)" | tee /VERSION
+
+VOLUME /workspace
+WORKDIR /workspace
+
+CMD ["/bin/zsh", "-l"]