Compare commits

..
Author SHA1 Message Date
telackey 2173e7ce6a If the next version is unsupported, print a big warning and try higher version. (#674) 2023-11-30 12:33:06 -06:00
dboreham c19559967d Add doc for deploy-webapp (#672) 2023-11-29 20:55:14 -07:00
dboreham d7093277b4 Use constants (#671) 2023-11-29 20:50:53 -07:00
telackey 03a3645b3c Add --port option to run-webapp. (#667)
* Add --port option to run-webapp

* Fixed merge

* lint
2023-11-29 11:32:28 -06:00
8 changed files with 59 additions and 16 deletions
+11 -1
View File
@@ -34,7 +34,7 @@ To test locally run:
## Running
With `run-webapp` a new container will be launched with runtime configuration provided by `--env-file` (if specified) and published on an available port. Multiple instances can be launched with different configuration.
With `run-webapp` a new container will be launched on the local machine, with runtime configuration provided by `--env-file` (if specified) and published on an available port. Multiple instances can be launched with different configuration.
**Example**:
```
@@ -52,3 +52,13 @@ Image: cerc/test-progressive-web-app:local
ID: 9ab96494f563aafb6c057d88df58f9eca81b90f8721a4e068493a289a976051c
URL: http://localhost:32769
```
## Deploying
Use the subcommand `deploy-webapp create` to make a deployment directory that can be subsequently deployed to a Kubernetes cluster.
Example commands are shown below, assuming that the webapp container image `cerc/test-progressive-web-app:local` has already been built:
```
$ laconic-so deploy-webapp create --kube-config ~/kubectl/k8s-kubeconfig.yaml --image-registry registry.digitalocean.com/laconic-registry --deployment-dir webapp-k8s-deployment --image cerc/test-progressive-web-app:local --url https://test-pwa-app.hosting.laconic.com/ --env-file test-webapp.env
$ laconic-so deployment --dir webapp-k8s-deployment push-images
$ laconic-so deployment --dir webapp-k8s-deployment start
```
@@ -24,6 +24,8 @@ RUN \
&& 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" \
&& npm cache clean --force > /dev/null 2>&1
# [Optional] Uncomment this section to install additional OS packages.
@@ -4,10 +4,12 @@ if [ -n "$CERC_SCRIPT_DEBUG" ]; then
set -x
fi
CERC_MIN_NEXTVER=13.4.2
CERC_NEXT_VERSION="${CERC_NEXT_VERSION:-keep}"
CERC_BUILD_TOOL="${CERC_BUILD_TOOL}"
if [ -z "$CERC_BUILD_TOOL" ]; then
if [ -f "yarn.lock" ] && [ ! -f "package-lock.json" ]; then
if [ -f "yarn.lock" ]; then
CERC_BUILD_TOOL=yarn
else
CERC_BUILD_TOOL=npm
@@ -101,13 +103,35 @@ cat package.dist | jq '.scripts.cerc_compile = "next experimental-compile"' | jq
CUR_NEXT_VERSION="`jq -r '.dependencies.next' package.json`"
if [ "$CERC_NEXT_VERSION" != "keep" ] && [ "$CUR_NEXT_VERSION" != "$CERC_NEXT_VERSION" ]; then
echo "Changing 'next' version specifier from '$CUR_NEXT_VERSION' to '$CERC_NEXT_VERSION' (set with --build-arg CERC_NEXT_VERSION)"
echo "Changing 'next' version specifier from '$CUR_NEXT_VERSION' to '$CERC_NEXT_VERSION' (set with '--extra-build-args \"--build-arg CERC_NEXT_VERSION=$CERC_NEXT_VERSION\"')"
cat package.json | jq ".dependencies.next = \"$CERC_NEXT_VERSION\"" | sponge package.json
else
echo "'next' version specifier '$CUR_NEXT_VERSION' (override with --build-arg CERC_NEXT_VERSION)"
fi
$CERC_BUILD_TOOL install || exit 1
CUR_NEXT_VERSION=`jq -r '.version' node_modules/next/package.json`
semver -p -r ">=$CERC_MIN_NEXTVER" $CUR_NEXT_VERSION
if [ $? -ne 0 ]; then
cat <<EOF
###############################################################################
WARNING: 'next' $CUR_NEXT_VERSION < minimum version $CERC_MIN_NEXTVER.
Attempting to build with '^$CERC_MIN_NEXTVER'. If this fails, you should upgrade
the dependency in your webapp, or specify an explicit 'next' version
to use for the build with:
--extra-build-args "--build-arg CERC_NEXT_VERSION=<version>"
###############################################################################
EOF
cat package.json | jq ".dependencies.next = \"^$CERC_MIN_NEXTVER\"" | sponge package.json
$CERC_BUILD_TOOL install || exit 1
fi
$CERC_BUILD_TOOL run cerc_compile || exit 1
exit 0
@@ -64,10 +64,10 @@ class DockerDeployer(Deployer):
except DockerException as e:
raise DeployerException(e)
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, detach=False):
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, ports=[], detach=False):
try:
return self.docker.run(image=image, command=command, user=user, volumes=volumes,
entrypoint=entrypoint, envs=env, detach=detach, publish_all=True)
entrypoint=entrypoint, envs=env, detach=detach, publish=ports, publish_all=len(ports) == 0)
except DockerException as e:
raise DeployerException(e)
+1 -1
View File
@@ -44,7 +44,7 @@ class Deployer(ABC):
pass
@abstractmethod
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, detach=False):
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, ports=[], detach=False):
pass
@@ -16,6 +16,7 @@
from pathlib import Path
from stack_orchestrator import constants
from stack_orchestrator.deploy.stack import Stack
from stack_orchestrator.deploy.spec import Spec
@@ -26,13 +27,13 @@ class DeploymentContext:
stack: Stack
def get_stack_file(self):
return self.deployment_dir.joinpath("stack.yml")
return self.deployment_dir.joinpath(constants.stack_file_name)
def get_spec_file(self):
return self.deployment_dir.joinpath("spec.yml")
return self.deployment_dir.joinpath(constants.spec_file_name)
def get_env_file(self):
return self.deployment_dir.joinpath("config.env")
return self.deployment_dir.joinpath(constants.config_file_name)
# TODO: implement me
def get_cluster_name(self):
+1 -1
View File
@@ -230,7 +230,7 @@ class K8sDeployer(Deployer):
log_data = self.core_api.read_namespaced_pod_log(k8s_pod_name, namespace="default", container="test")
return log_stream_from_string(log_data)
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, detach=False):
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, ports=[], detach=False):
# We need to figure out how to do this -- check why we're being called first
pass
+10 -4
View File
@@ -27,13 +27,16 @@ from dotenv import dotenv_values
from stack_orchestrator import constants
from stack_orchestrator.deploy.deployer_factory import getDeployer
WEBAPP_PORT = 3000
@click.command()
@click.option("--image", help="image to deploy", required=True)
@click.option("--env-file", help="environment file for webapp")
@click.option("--port", help="port to use (default random)")
@click.pass_context
def command(ctx, image, env_file):
'''build the specified webapp container'''
def command(ctx, image, env_file, port):
'''run the specified webapp container'''
env = {}
if env_file:
@@ -49,10 +52,13 @@ def command(ctx, image, env_file):
compose_project_name=cluster,
compose_env_file=None)
container = deployer.run(image, command=[], user=None, volumes=[], entrypoint=None, env=env, detach=True)
ports = []
if port:
ports = [(port, WEBAPP_PORT)]
container = deployer.run(image, command=[], user=None, volumes=[], entrypoint=None, env=env, ports=ports, detach=True)
# Make configurable?
webappPort = "3000/tcp"
webappPort = f"{WEBAPP_PORT}/tcp"
# TODO: This assumes a Docker container object...
if webappPort in container.network_settings.ports:
mapping = container.network_settings.ports[webappPort][0]