Support other webapp types (react, static). (#721)
* Support other webapp types (react, static).
This commit is contained in:
		
							parent
							
								
									1c30441000
								
							
						
					
					
						commit
						6629017d6a
					
				| @ -25,10 +25,11 @@ from decouple import config | ||||
| import click | ||||
| from pathlib import Path | ||||
| from stack_orchestrator.build import build_containers | ||||
| from stack_orchestrator.deploy.webapp.util import determine_base_container | ||||
| 
 | ||||
| 
 | ||||
| @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("--force-rebuild", is_flag=True, default=False, help="Override dependency checking -- always rebuild") | ||||
| @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: | ||||
|         print(f'Dev Root is: {dev_root_path}') | ||||
| 
 | ||||
|     if not base_container: | ||||
|         base_container = determine_base_container(source_repo) | ||||
| 
 | ||||
|     # First build the base container. | ||||
|     container_build_env = build_containers.make_container_build_env(dev_root_path, container_build_dir, debug, | ||||
|                                                                     force_rebuild, extra_build_args) | ||||
| @ -64,13 +68,12 @@ 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, | ||||
|                                        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. | ||||
|     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_DOCKERFILE"] = os.path.join(container_build_dir, | ||||
|                                                                     base_container.replace("/", "-"), | ||||
|                                                                     "Dockerfile.webapp") | ||||
|                                                                           base_container.replace("/", "-"), | ||||
|                                                                           "Dockerfile.webapp") | ||||
|     if not tag: | ||||
|         webapp_name = os.path.abspath(source_repo).split(os.path.sep)[-1] | ||||
|         container_build_env["CERC_CONTAINER_BUILD_TAG"] = f"cerc/{webapp_name}:local" | ||||
|  | ||||
| @ -36,7 +36,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ | ||||
| # RUN su node -c "npm install -g <your-package-list-here>" | ||||
| 
 | ||||
| # Expose port for http | ||||
| EXPOSE 3000 | ||||
| EXPOSE 80 | ||||
| 
 | ||||
| COPY /scripts /scripts | ||||
| 
 | ||||
|  | ||||
| @ -58,4 +58,4 @@ if [ "$CERC_NEXTJS_SKIP_GENERATE" != "true" ]; then | ||||
|   fi | ||||
| fi | ||||
| 
 | ||||
| $CERC_BUILD_TOOL start . -p ${CERC_LISTEN_PORT:-3000} | ||||
| $CERC_BUILD_TOOL start . -- -p ${CERC_LISTEN_PORT:-80} | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| # 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=18-bullseye | ||||
| ARG VARIANT=20-bullseye | ||||
| FROM node:${VARIANT} | ||||
| 
 | ||||
| ARG USERNAME=node | ||||
| @ -28,7 +28,7 @@ RUN \ | ||||
| 
 | ||||
| # [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 | ||||
|     && 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 | ||||
| @ -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 | ||||
| COPY --from=docker.io/mikefarah/yq:latest /usr/bin/yq /usr/local/bin/yq | ||||
| 
 | ||||
| RUN mkdir -p /scripts | ||||
| COPY ./apply-webapp-config.sh /scripts | ||||
| COPY ./start-serving-app.sh /scripts | ||||
| 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>" | ||||
|  | ||||
| @ -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 | ||||
| # Build cerc/laconic-registry-cli | ||||
| # 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 ) | ||||
| 
 | ||||
| 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 | ||||
| @ -0,0 +1,15 @@ | ||||
| #!/usr/bin/env bash | ||||
| if [ -n "$CERC_SCRIPT_DEBUG" ]; then | ||||
|     set -x | ||||
| fi | ||||
| 
 | ||||
| CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}" | ||||
| CERC_ENABLE_CORS="${CERC_ENABLE_CORS:-false}" | ||||
| 
 | ||||
| if [ "true" == "$CERC_ENABLE_CORS" ]; then | ||||
|   CERC_HTTP_EXTRA_ARGS="$CERC_HTTP_EXTRA_ARGS --cors" | ||||
| fi | ||||
| 
 | ||||
| /scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR} | ||||
| /scripts/apply-runtime-env.sh ${CERC_WEBAPP_FILES_DIR} | ||||
| http-server $CERC_HTTP_EXTRA_ARGS -p ${CERC_LISTEN_PORT:-80} ${CERC_WEBAPP_FILES_DIR} | ||||
| @ -1,9 +0,0 @@ | ||||
| #!/usr/bin/env bash | ||||
| if [ -n "$CERC_SCRIPT_DEBUG" ]; then | ||||
|     set -x | ||||
| fi | ||||
| 
 | ||||
| CERC_WEBAPP_FILES_DIR="${CERC_WEBAPP_FILES_DIR:-/data}" | ||||
| 
 | ||||
| /scripts/apply-webapp-config.sh /config/config.yml ${CERC_WEBAPP_FILES_DIR} | ||||
| http-server -p 80 ${CERC_WEBAPP_FILES_DIR} | ||||
| @ -27,7 +27,7 @@ from dotenv import dotenv_values | ||||
| from stack_orchestrator import constants | ||||
| from stack_orchestrator.deploy.deployer_factory import getDeployer | ||||
| 
 | ||||
| WEBAPP_PORT = 3000 | ||||
| WEBAPP_PORT = 80 | ||||
| 
 | ||||
| 
 | ||||
| @click.command() | ||||
|  | ||||
| @ -195,6 +195,23 @@ def file_hash(filename): | ||||
|     return hashlib.sha1(open(filename).read().encode()).hexdigest() | ||||
| 
 | ||||
| 
 | ||||
| def determine_base_container(clone_dir, app_type="webapp"): | ||||
|     if not app_type or 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=[]): | ||||
|     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.check_returncode() | ||||
| 
 | ||||
|         base_container = determine_base_container(clone_dir, app_record.attributes.app_type) | ||||
| 
 | ||||
|         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: | ||||
|             build_command.append("--extra-build-args") | ||||
|             build_command.append(" ".join(extra_build_args)) | ||||
|  | ||||
| @ -30,14 +30,14 @@ CHECK="SPECIAL_01234567890_TEST_STRING" | ||||
| 
 | ||||
| set +e | ||||
| 
 | ||||
| CONTAINER_ID=$(docker run -p 3000:3000 -d -e CERC_SCRIPT_DEBUG=$CERC_SCRIPT_DEBUG cerc/test-progressive-web-app:local) | ||||
| CONTAINER_ID=$(docker run -p 3000:80 -d -e CERC_SCRIPT_DEBUG=$CERC_SCRIPT_DEBUG cerc/test-progressive-web-app:local) | ||||
| sleep 3 | ||||
| wget -t 7 -O test.before -m http://localhost:3000 | ||||
| 
 | ||||
| docker logs $CONTAINER_ID | ||||
| docker remove -f $CONTAINER_ID | ||||
| 
 | ||||
| CONTAINER_ID=$(docker run -p 3000:3000 -e CERC_WEBAPP_DEBUG=$CHECK -e CERC_SCRIPT_DEBUG=$CERC_SCRIPT_DEBUG -d cerc/test-progressive-web-app:local) | ||||
| CONTAINER_ID=$(docker run -p 3000:80 -e CERC_WEBAPP_DEBUG=$CHECK -e CERC_SCRIPT_DEBUG=$CERC_SCRIPT_DEBUG -d cerc/test-progressive-web-app:local) | ||||
| sleep 3 | ||||
| wget -t 7 -O test.after -m http://localhost:3000 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user