Setup laconic-console in the stack
This commit is contained in:
parent
5b8c133c1c
commit
1e014e6b2e
@ -12,5 +12,16 @@ services:
|
|||||||
extra_hosts:
|
extra_hosts:
|
||||||
- "host.docker.internal:host-gateway"
|
- "host.docker.internal:host-gateway"
|
||||||
|
|
||||||
|
laconic-console:
|
||||||
|
restart: unless-stopped
|
||||||
|
image: cerc/laconic-console-host:local
|
||||||
|
environment:
|
||||||
|
- CERC_WEBAPP_FILES_DIR=${CERC_WEBAPP_FILES_DIR:-/usr/local/share/.config/yarn/global/node_modules/@cerc-io/console-app/dist/production}
|
||||||
|
- LACONIC_HOSTED_ENDPOINT=${LACONIC_HOSTED_ENDPOINT:-http://localhost:9473}
|
||||||
|
volumes:
|
||||||
|
- ../config/laconic-console/console/config.yml:/config.yml
|
||||||
|
ports:
|
||||||
|
- "80"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
laconic-registry-data:
|
laconic-registry-data:
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
# Config for laconic-console
|
||||||
|
|
||||||
|
services:
|
||||||
|
wns:
|
||||||
|
server: 'LACONIC_HOSTED_ENDPOINT/api'
|
||||||
|
webui: 'LACONIC_HOSTED_ENDPOINT/console'
|
@ -0,0 +1,12 @@
|
|||||||
|
FROM cerc/webapp-base:local
|
||||||
|
|
||||||
|
# Configure the cerc-io npm registry
|
||||||
|
RUN npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN echo "Installing dependencies" && yarn
|
||||||
|
RUN LACONIC_HOSTED_CONFIG_FILE=config-hosted.yml yarn dist
|
||||||
|
|
||||||
|
RUN npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/
|
||||||
|
RUN yarn global add file:$PWD
|
9
stack-orchestrator/container-build/cerc-laconic-console-host/build.sh
Executable file
9
stack-orchestrator/container-build/cerc-laconic-console-host/build.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build cerc/laconic-registry-cli
|
||||||
|
|
||||||
|
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
||||||
|
|
||||||
|
# See: https://stackoverflow.com/a/246128/1701505
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
|
docker build -t cerc/laconic-console-host:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${CERC_REPO_BASE_DIR}/laconic-console
|
@ -0,0 +1,58 @@
|
|||||||
|
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
|
||||||
|
# [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster
|
||||||
|
ARG VARIANT=20-bullseye-slim
|
||||||
|
FROM node:${VARIANT}
|
||||||
|
|
||||||
|
ARG USERNAME=node
|
||||||
|
ARG NPM_GLOBAL=/usr/local/share/npm-global
|
||||||
|
|
||||||
|
# Add NPM global to PATH.
|
||||||
|
ENV PATH=${NPM_GLOBAL}/bin:${PATH}
|
||||||
|
# Prevents npm from printing version warnings
|
||||||
|
ENV NPM_CONFIG_UPDATE_NOTIFIER=false
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
# Configure global npm install location, use group to adapt to UID/GID changes
|
||||||
|
if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \
|
||||||
|
&& usermod -a -G npm ${USERNAME} \
|
||||||
|
&& umask 0002 \
|
||||||
|
&& mkdir -p ${NPM_GLOBAL} \
|
||||||
|
&& touch /usr/local/etc/npmrc \
|
||||||
|
&& chown ${USERNAME}:npm ${NPM_GLOBAL} /usr/local/etc/npmrc \
|
||||||
|
&& chmod g+s ${NPM_GLOBAL} \
|
||||||
|
&& npm config -g set prefix ${NPM_GLOBAL} \
|
||||||
|
&& su ${USERNAME} -c "npm config -g set prefix ${NPM_GLOBAL}" \
|
||||||
|
# Install eslint
|
||||||
|
&& su ${USERNAME} -c "umask 0002 && npm install -g eslint" \
|
||||||
|
# Install semver
|
||||||
|
&& su ${USERNAME} -c "umask 0002 && npm install -g semver" \
|
||||||
|
# Install pnpm
|
||||||
|
&& su ${USERNAME} -c "umask 0002 && npm install -g pnpm" \
|
||||||
|
&& npm cache clean --force > /dev/null 2>&1
|
||||||
|
|
||||||
|
# [Optional] Uncomment this section to install additional OS packages.
|
||||||
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
&& apt-get -y install --no-install-recommends jq gettext-base
|
||||||
|
|
||||||
|
# [Optional] Uncomment if you want to install an additional version of node using nvm
|
||||||
|
# ARG EXTRA_NODE_VERSION=10
|
||||||
|
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
|
||||||
|
|
||||||
|
# We do this to get a yq binary from the published container, for the correct architecture we're building here
|
||||||
|
COPY --from=docker.io/mikefarah/yq:latest /usr/bin/yq /usr/local/bin/yq
|
||||||
|
|
||||||
|
COPY scripts /scripts
|
||||||
|
|
||||||
|
# [Optional] Uncomment if you want to install more global node modules
|
||||||
|
# RUN su node -c "npm install -g <your-package-list-here>"
|
||||||
|
|
||||||
|
RUN mkdir -p /config
|
||||||
|
|
||||||
|
# Install simple web server for now (use nginx perhaps later)
|
||||||
|
RUN yarn global add http-server
|
||||||
|
|
||||||
|
# Expose port for http
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Default command sleeps forever so docker doesn't kill it
|
||||||
|
CMD ["/scripts/start-serving-app.sh"]
|
@ -0,0 +1,12 @@
|
|||||||
|
FROM cerc/webapp-base:local as builder
|
||||||
|
|
||||||
|
ARG CERC_BUILD_TOOL
|
||||||
|
ARG CERC_BUILD_OUTPUT_DIR
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN rm -rf node_modules build dist .next*
|
||||||
|
RUN /scripts/build-app.sh /app /data
|
||||||
|
|
||||||
|
FROM cerc/webapp-base:local
|
||||||
|
COPY --from=builder /data /data
|
35
stack-orchestrator/container-build/cerc-webapp-base/build.sh
Executable file
35
stack-orchestrator/container-build/cerc-webapp-base/build.sh
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build cerc/webapp-base
|
||||||
|
|
||||||
|
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
||||||
|
|
||||||
|
# See: https://stackoverflow.com/a/246128/1701505
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
|
CERC_CONTAINER_BUILD_WORK_DIR=${CERC_CONTAINER_BUILD_WORK_DIR:-$SCRIPT_DIR}
|
||||||
|
CERC_CONTAINER_BUILD_DOCKERFILE=${CERC_CONTAINER_BUILD_DOCKERFILE:-$SCRIPT_DIR/Dockerfile}
|
||||||
|
CERC_CONTAINER_BUILD_TAG=${CERC_CONTAINER_BUILD_TAG:-cerc/webapp-base:local}
|
||||||
|
|
||||||
|
docker build -t $CERC_CONTAINER_BUILD_TAG ${build_command_args} -f $CERC_CONTAINER_BUILD_DOCKERFILE $CERC_CONTAINER_BUILD_WORK_DIR
|
||||||
|
rc=$?
|
||||||
|
|
||||||
|
if [ $rc -ne 0 ]; then
|
||||||
|
echo "BUILD FAILED" 1>&2
|
||||||
|
exit $rc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$CERC_CONTAINER_BUILD_TAG" != "cerc/webapp-base:local" ]; then
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
|
||||||
|
Built host container for $CERC_CONTAINER_BUILD_WORK_DIR with tag:
|
||||||
|
|
||||||
|
$CERC_CONTAINER_BUILD_TAG
|
||||||
|
|
||||||
|
To test locally run:
|
||||||
|
|
||||||
|
laconic-so run-webapp --image $CERC_CONTAINER_BUILD_TAG --env-file /path/to/environment.env
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
WORK_DIR="${1:-./}"
|
||||||
|
|
||||||
|
cd "${WORK_DIR}" || exit 1
|
||||||
|
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
TMP_ENV=`mktemp`
|
||||||
|
declare -px > $TMP_ENV
|
||||||
|
set -a
|
||||||
|
source .env
|
||||||
|
source $TMP_ENV
|
||||||
|
set +a
|
||||||
|
rm -f $TMP_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in $(find . -type f \( -regex '.*.html?' -or -regex ".*.[tj]s\(x\|on\)?$" \) | grep -v 'node_modules' | grep -v '.git'); do
|
||||||
|
for e in $(cat "${f}" | tr -s '[:blank:]' '\n' | tr -s '["/\\{},();]' '\n' | tr -s "[']" '\n' | egrep -o -e '^CERC_RUNTIME_ENV_.+$' -e '^LACONIC_HOSTED_CONFIG_.+$'); do
|
||||||
|
orig_name=$(echo -n "${e}" | sed 's/"//g')
|
||||||
|
cur_name=$(echo -n "${orig_name}" | sed 's/CERC_RUNTIME_ENV_//g')
|
||||||
|
cur_val=$(echo -n "\$${cur_name}" | envsubst)
|
||||||
|
if [ "$CERC_RETAIN_ENV_QUOTES" != "true" ]; then
|
||||||
|
cur_val=$(sed "s/^[\"']//" <<< "$cur_val" | sed "s/[\"']//")
|
||||||
|
fi
|
||||||
|
esc_val=$(sed 's/[&/\]/\\&/g' <<< "$cur_val")
|
||||||
|
echo "$f: $cur_name=$cur_val"
|
||||||
|
sed -i "s/$orig_name/$esc_val/g" $f
|
||||||
|
done
|
||||||
|
done
|
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
if [[ $# -ne 2 ]]; then
|
||||||
|
echo "Illegal number of parameters" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
config_file_name=$1
|
||||||
|
webapp_files_dir=$2
|
||||||
|
if ! [[ -f ${config_file_name} ]]; then
|
||||||
|
echo "Config file ${config_file_name} does not exist" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! [[ -d ${webapp_files_dir} ]]; then
|
||||||
|
echo "Webapp directory ${webapp_files_dir} does not exist" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# First some magic using yq to translate our yaml config file into an array of key value pairs like:
|
||||||
|
# LACONIC_HOSTED_CONFIG_<path-through-objects>=<value>
|
||||||
|
readarray -t config_kv_pair_array < <( yq '.. | ([path | join("_"), .] | join("=") )' ${config_file_name} | sort -r | sed -e '$ d' | sed 's/^/LACONIC_HOSTED_CONFIG_/' )
|
||||||
|
declare -p config_kv_pair_array
|
||||||
|
# Then iterate over that kv array making the template substitution in our web app files
|
||||||
|
for kv_pair_string in "${config_kv_pair_array[@]}"
|
||||||
|
do
|
||||||
|
kv_pair=(${kv_pair_string//=/ })
|
||||||
|
template_string_to_replace=${kv_pair[0]}
|
||||||
|
template_value_to_substitute=${kv_pair[1]}
|
||||||
|
template_value_to_substitute_expanded=${template_value_to_substitute//LACONIC_HOSTED_ENDPOINT/${LACONIC_HOSTED_ENDPOINT}}
|
||||||
|
# Run find and sed to do the substitution of one variable over all files
|
||||||
|
# See: https://stackoverflow.com/a/21479607/1701505
|
||||||
|
echo "Substituting: ${template_string_to_replace} = ${template_value_to_substitute_expanded}"
|
||||||
|
# Note: we do not escape our strings, on the expectation they do not container the '#' char.
|
||||||
|
find ${webapp_files_dir} -type f -exec sed -i 's#'${template_string_to_replace}'#'${template_value_to_substitute_expanded}'#g' {} +
|
||||||
|
done
|
61
stack-orchestrator/container-build/cerc-webapp-base/scripts/build-app.sh
Executable file
61
stack-orchestrator/container-build/cerc-webapp-base/scripts/build-app.sh
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
CERC_BUILD_TOOL="${CERC_BUILD_TOOL}"
|
||||||
|
CERC_BUILD_OUTPUT_DIR="${CERC_BUILD_OUTPUT_DIR}"
|
||||||
|
|
||||||
|
WORK_DIR="${1:-/app}"
|
||||||
|
DEST_DIR="${2:-/data}"
|
||||||
|
|
||||||
|
if [ -f "${WORK_DIR}/build-webapp.sh" ]; then
|
||||||
|
echo "Building webapp with ${WORK_DIR}/build-webapp.sh ..."
|
||||||
|
cd "${WORK_DIR}" || exit 1
|
||||||
|
|
||||||
|
rm -rf "${DEST_DIR}"
|
||||||
|
./build-webapp.sh "${DEST_DIR}" || exit 1
|
||||||
|
elif [ -f "${WORK_DIR}/package.json" ]; then
|
||||||
|
echo "Building node-based webapp ..."
|
||||||
|
cd "${WORK_DIR}" || exit 1
|
||||||
|
|
||||||
|
if [ -z "$CERC_BUILD_TOOL" ]; then
|
||||||
|
if [ -f "pnpm-lock.yaml" ]; then
|
||||||
|
CERC_BUILD_TOOL=pnpm
|
||||||
|
elif [ -f "yarn.lock" ]; then
|
||||||
|
CERC_BUILD_TOOL=yarn
|
||||||
|
else
|
||||||
|
CERC_BUILD_TOOL=npm
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
time $CERC_BUILD_TOOL install || exit 1
|
||||||
|
time $CERC_BUILD_TOOL build || exit 1
|
||||||
|
|
||||||
|
rm -rf "${DEST_DIR}"
|
||||||
|
if [ -z "${CERC_BUILD_OUTPUT_DIR}" ]; then
|
||||||
|
if [ -d "${WORK_DIR}/dist" ]; then
|
||||||
|
CERC_BUILD_OUTPUT_DIR="${WORK_DIR}/dist"
|
||||||
|
elif [ -d "${WORK_DIR}/build" ]; then
|
||||||
|
CERC_BUILD_OUTPUT_DIR="${WORK_DIR}/build"
|
||||||
|
else
|
||||||
|
echo "ERROR: Unable to locate build output. Set with --extra-build-args \"--build-arg CERC_BUILD_OUTPUT_DIR=path\"" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
mv "${CERC_BUILD_OUTPUT_DIR}" "${DEST_DIR}"
|
||||||
|
else
|
||||||
|
echo "Copying static app ..."
|
||||||
|
mv "${WORK_DIR}" "${DEST_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# One special fix ...
|
||||||
|
cd "${DEST_DIR}"
|
||||||
|
for f in $(find . -type f -name '*.htm*'); do
|
||||||
|
sed -i -e 's#/LACONIC_HOSTED_CONFIG_homepage/#LACONIC_HOSTED_CONFIG_homepage/#g' "$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
CERC_LISTEN_PORT=${CERC_LISTEN_PORT:-80}
|
||||||
|
CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}"
|
||||||
|
CERC_ENABLE_CORS="${CERC_ENABLE_CORS:-false}"
|
||||||
|
CERC_SINGLE_PAGE_APP="${CERC_SINGLE_PAGE_APP}"
|
||||||
|
|
||||||
|
if [ -z "${CERC_SINGLE_PAGE_APP}" ]; then
|
||||||
|
# If there is only one HTML file, assume an SPA.
|
||||||
|
if [ 1 -eq $(find "${CERC_WEBAPP_FILES_DIR}" -name '*.html' | wc -l) ]; then
|
||||||
|
CERC_SINGLE_PAGE_APP=true
|
||||||
|
else
|
||||||
|
CERC_SINGLE_PAGE_APP=false
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ${var,,} is a lower-case comparison
|
||||||
|
if [ "true" == "${CERC_ENABLE_CORS,,}" ]; then
|
||||||
|
CERC_HTTP_EXTRA_ARGS="$CERC_HTTP_EXTRA_ARGS --cors"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ${var,,} is a lower-case comparison
|
||||||
|
if [ "true" == "${CERC_SINGLE_PAGE_APP,,}" ]; then
|
||||||
|
echo "Serving content as single-page app. If this is wrong, set 'CERC_SINGLE_PAGE_APP=false'"
|
||||||
|
# Create a catchall redirect back to /
|
||||||
|
CERC_HTTP_EXTRA_ARGS="$CERC_HTTP_EXTRA_ARGS --proxy http://localhost:${CERC_LISTEN_PORT}?"
|
||||||
|
else
|
||||||
|
echo "Serving content normally. If this is a single-page app, set 'CERC_SINGLE_PAGE_APP=true'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
LACONIC_HOSTED_CONFIG_FILE=${LACONIC_HOSTED_CONFIG_FILE}
|
||||||
|
if [ -z "${LACONIC_HOSTED_CONFIG_FILE}" ]; then
|
||||||
|
if [ -f "/config/laconic-hosted-config.yml" ]; then
|
||||||
|
LACONIC_HOSTED_CONFIG_FILE="/config/laconic-hosted-config.yml"
|
||||||
|
elif [ -f "/config/config.yml" ]; then
|
||||||
|
LACONIC_HOSTED_CONFIG_FILE="/config/config.yml"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "${LACONIC_HOSTED_CONFIG_FILE}" ]; then
|
||||||
|
/scripts/apply-webapp-config.sh $LACONIC_HOSTED_CONFIG_FILE "${CERC_WEBAPP_FILES_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
/scripts/apply-runtime-env.sh ${CERC_WEBAPP_FILES_DIR}
|
||||||
|
http-server $CERC_HTTP_EXTRA_ARGS -p ${CERC_LISTEN_PORT} "${CERC_WEBAPP_FILES_DIR}"
|
@ -3,7 +3,10 @@ name: laconic-console
|
|||||||
description: "Laconic registry CLI and console"
|
description: "Laconic registry CLI and console"
|
||||||
repos:
|
repos:
|
||||||
- git.vdb.to/cerc-io/laconic-registry-cli@laconic2
|
- git.vdb.to/cerc-io/laconic-registry-cli@laconic2
|
||||||
|
- git.vdb.to/cerc-io/laconic-console@laconic2
|
||||||
containers:
|
containers:
|
||||||
- cerc/laconic2-registry-cli
|
- cerc/laconic2-registry-cli
|
||||||
|
- cerc/webapp-base
|
||||||
|
- cerc/laconic-console-host
|
||||||
pods:
|
pods:
|
||||||
- laconic-console
|
- laconic-console
|
||||||
|
Loading…
Reference in New Issue
Block a user