Support other webapp types (react, static).
This commit is contained in:
parent
b398050787
commit
8fa7efc2c5
@ -25,10 +25,11 @@ from decouple import config
|
|||||||
import click
|
import click
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from stack_orchestrator.build import build_containers
|
from stack_orchestrator.build import build_containers
|
||||||
|
from stack_orchestrator.deploy.webapp.util import determine_base_container
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option('--base-container', default="cerc/nextjs-base")
|
@click.option('--base-container')
|
||||||
@click.option('--source-repo', help="directory containing the webapp to build", required=True)
|
@click.option('--source-repo', help="directory containing the webapp to build", required=True)
|
||||||
@click.option("--force-rebuild", is_flag=True, default=False, help="Override dependency checking -- always rebuild")
|
@click.option("--force-rebuild", is_flag=True, default=False, help="Override dependency checking -- always rebuild")
|
||||||
@click.option("--extra-build-args", help="Supply extra arguments to build")
|
@click.option("--extra-build-args", help="Supply extra arguments to build")
|
||||||
@ -57,6 +58,9 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
|
|||||||
if not quiet:
|
if not quiet:
|
||||||
print(f'Dev Root is: {dev_root_path}')
|
print(f'Dev Root is: {dev_root_path}')
|
||||||
|
|
||||||
|
if not base_container:
|
||||||
|
base_container = determine_base_container(source_repo)
|
||||||
|
|
||||||
# First build the base container.
|
# First build the base container.
|
||||||
container_build_env = build_containers.make_container_build_env(dev_root_path, container_build_dir, debug,
|
container_build_env = build_containers.make_container_build_env(dev_root_path, container_build_dir, debug,
|
||||||
force_rebuild, extra_build_args)
|
force_rebuild, extra_build_args)
|
||||||
@ -64,7 +68,6 @@ def command(ctx, base_container, source_repo, force_rebuild, extra_build_args, t
|
|||||||
build_containers.process_container(None, base_container, container_build_dir, container_build_env, dev_root_path, quiet,
|
build_containers.process_container(None, base_container, container_build_dir, container_build_env, dev_root_path, quiet,
|
||||||
verbose, dry_run, continue_on_error)
|
verbose, dry_run, continue_on_error)
|
||||||
|
|
||||||
|
|
||||||
# Now build the target webapp. We use the same build script, but with a different Dockerfile and work dir.
|
# Now build the target webapp. We use the same build script, but with a different Dockerfile and work dir.
|
||||||
container_build_env["CERC_WEBAPP_BUILD_RUNNING"] = "true"
|
container_build_env["CERC_WEBAPP_BUILD_RUNNING"] = "true"
|
||||||
container_build_env["CERC_CONTAINER_BUILD_WORK_DIR"] = os.path.abspath(source_repo)
|
container_build_env["CERC_CONTAINER_BUILD_WORK_DIR"] = os.path.abspath(source_repo)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile
|
# 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
|
# [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=18-bullseye
|
ARG VARIANT=20-bullseye
|
||||||
FROM node:${VARIANT}
|
FROM node:${VARIANT}
|
||||||
|
|
||||||
ARG USERNAME=node
|
ARG USERNAME=node
|
||||||
@ -28,7 +28,7 @@ RUN \
|
|||||||
|
|
||||||
# [Optional] Uncomment this section to install additional OS packages.
|
# [Optional] Uncomment this section to install additional OS packages.
|
||||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
&& apt-get -y install --no-install-recommends jq
|
&& apt-get -y install --no-install-recommends jq gettext-base
|
||||||
|
|
||||||
# [Optional] Uncomment if you want to install an additional version of node using nvm
|
# [Optional] Uncomment if you want to install an additional version of node using nvm
|
||||||
# ARG EXTRA_NODE_VERSION=10
|
# ARG EXTRA_NODE_VERSION=10
|
||||||
@ -37,9 +37,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
|||||||
# We do this to get a yq binary from the published container, for the correct architecture we're building here
|
# 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 --from=docker.io/mikefarah/yq:latest /usr/bin/yq /usr/local/bin/yq
|
||||||
|
|
||||||
RUN mkdir -p /scripts
|
COPY scripts /scripts
|
||||||
COPY ./apply-webapp-config.sh /scripts
|
|
||||||
COPY ./start-serving-app.sh /scripts
|
|
||||||
|
|
||||||
# [Optional] Uncomment if you want to install more global node modules
|
# [Optional] Uncomment if you want to install more global node modules
|
||||||
# RUN su node -c "npm install -g <your-package-list-here>"
|
# RUN su node -c "npm install -g <your-package-list-here>"
|
||||||
@ -51,7 +49,7 @@ COPY ./config.yml /config
|
|||||||
RUN yarn global add http-server
|
RUN yarn global add http-server
|
||||||
|
|
||||||
# Expose port for http
|
# Expose port for http
|
||||||
EXPOSE 80
|
EXPOSE 3000
|
||||||
|
|
||||||
# Default command sleeps forever so docker doesn't kill it
|
# Default command sleeps forever so docker doesn't kill it
|
||||||
CMD ["/scripts/start-serving-app.sh"]
|
CMD ["/scripts/start-serving-app.sh"]
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
FROM cerc/webapp-base:local as builder
|
||||||
|
|
||||||
|
ARG CERC_BUILD_TOOL
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN rm -rf node_modules build .next*
|
||||||
|
RUN /scripts/build-app.sh /app build /data
|
||||||
|
|
||||||
|
FROM cerc/webapp-base:local
|
||||||
|
COPY --from=builder /data /data
|
@ -1,9 +1,29 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Build cerc/laconic-registry-cli
|
# Build cerc/webapp-base
|
||||||
|
|
||||||
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
source ${CERC_CONTAINER_BASE_DIR}/build-base.sh
|
||||||
|
|
||||||
# See: https://stackoverflow.com/a/246128/1701505
|
# See: https://stackoverflow.com/a/246128/1701505
|
||||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
docker build -t cerc/webapp-base:local ${build_command_args} -f ${SCRIPT_DIR}/Dockerfile ${SCRIPT_DIR}
|
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
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] && [ "$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 . -regex ".*.[tj]sx?$" -type f | grep -v 'node_modules'); do
|
||||||
|
for e in $(cat "${f}" | tr -s '[:blank:]' '\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,36 @@
|
|||||||
|
#!/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}"
|
||||||
|
WORK_DIR="${1:-/app}"
|
||||||
|
OUTPUT_DIR="${2:-build}"
|
||||||
|
DEST_DIR="${3:-/data}"
|
||||||
|
|
||||||
|
if [ -f "${WORK_DIR}/package.json" ]; then
|
||||||
|
echo "Building node-based webapp ..."
|
||||||
|
cd "${WORK_DIR}" || exit 1
|
||||||
|
|
||||||
|
if [ -z "$CERC_BUILD_TOOL" ]; then
|
||||||
|
if [ -f "yarn.lock" ]; then
|
||||||
|
CERC_BUILD_TOOL=yarn
|
||||||
|
else
|
||||||
|
CERC_BUILD_TOOL=npm
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
$CERC_BUILD_TOOL install || exit 1
|
||||||
|
$CERC_BUILD_TOOL build || exit 1
|
||||||
|
|
||||||
|
rm -rf "${DEST_DIR}"
|
||||||
|
mv "${WORK_DIR}/${OUTPUT_DIR}" "${DEST_DIR}"
|
||||||
|
else
|
||||||
|
echo "Copying static app ..."
|
||||||
|
mv "${WORK_DIR}" "${DEST_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
@ -6,4 +6,5 @@ fi
|
|||||||
CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}"
|
CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}"
|
||||||
|
|
||||||
/scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR}
|
/scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR}
|
||||||
http-server -p 80 ${CERC_WEBAPP_FILES_DIR}
|
/scripts/apply-runtime-env.sh ${CERC_WEBAPP_FILES_DIR}
|
||||||
|
http-server --cors -p 3000 ${CERC_WEBAPP_FILES_DIR}
|
@ -23,7 +23,7 @@ import tempfile
|
|||||||
import click
|
import click
|
||||||
|
|
||||||
from stack_orchestrator.deploy.webapp import deploy_webapp
|
from stack_orchestrator.deploy.webapp import deploy_webapp
|
||||||
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient,
|
from stack_orchestrator.deploy.webapp.util import (LaconicRegistryClient, determine_base_container,
|
||||||
build_container_image, push_container_image,
|
build_container_image, push_container_image,
|
||||||
file_hash, deploy_to_k8s, publish_deployment,
|
file_hash, deploy_to_k8s, publish_deployment,
|
||||||
hostname_for_deployment_request, generate_hostname_for_app,
|
hostname_for_deployment_request, generate_hostname_for_app,
|
||||||
|
@ -195,6 +195,23 @@ def file_hash(filename):
|
|||||||
return hashlib.sha1(open(filename).read().encode()).hexdigest()
|
return hashlib.sha1(open(filename).read().encode()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def determine_base_container(clone_dir, app_type="webapp"):
|
||||||
|
if not app_type.startswith("webapp"):
|
||||||
|
raise Exception(f"Unsupported app_type {app_type}")
|
||||||
|
|
||||||
|
base_container = "cerc/webapp-base"
|
||||||
|
if app_type == "webapp/next":
|
||||||
|
base_container = "cerc/nextjs-base"
|
||||||
|
elif app_type == "webapp":
|
||||||
|
pkg_json_path = os.path.join(clone_dir, "package.json")
|
||||||
|
if os.path.exists(pkg_json_path):
|
||||||
|
pkg_json = json.load(open(pkg_json_path))
|
||||||
|
if "next" in pkg_json.get("dependencies", {}):
|
||||||
|
base_container = "cerc/nextjs-base"
|
||||||
|
|
||||||
|
return base_container
|
||||||
|
|
||||||
|
|
||||||
def build_container_image(app_record, tag, extra_build_args=[]):
|
def build_container_image(app_record, tag, extra_build_args=[]):
|
||||||
tmpdir = tempfile.mkdtemp()
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
|
||||||
@ -216,8 +233,15 @@ def build_container_image(app_record, tag, extra_build_args=[]):
|
|||||||
result = subprocess.run(["git", "clone", "--depth", "1", repo, clone_dir])
|
result = subprocess.run(["git", "clone", "--depth", "1", repo, clone_dir])
|
||||||
result.check_returncode()
|
result.check_returncode()
|
||||||
|
|
||||||
|
base_container = determine_base_container(clone_dir, app_record.attributes.app_type)
|
||||||
|
|
||||||
print("Building webapp ...")
|
print("Building webapp ...")
|
||||||
build_command = [sys.argv[0], "build-webapp", "--source-repo", clone_dir, "--tag", tag]
|
build_command = [
|
||||||
|
sys.argv[0], "build-webapp",
|
||||||
|
"--source-repo", clone_dir,
|
||||||
|
"--tag", tag,
|
||||||
|
"--base-container", base_container
|
||||||
|
]
|
||||||
if extra_build_args:
|
if extra_build_args:
|
||||||
build_command.append("--extra-build-args")
|
build_command.append("--extra-build-args")
|
||||||
build_command.append(" ".join(extra_build_args))
|
build_command.append(" ".join(extra_build_args))
|
||||||
|
Loading…
Reference in New Issue
Block a user