Skip to content

Commit

Permalink
docker config
Browse files Browse the repository at this point in the history
  • Loading branch information
vggonzal authored and vggonzal committed Oct 18, 2023
1 parent 6167be7 commit 6a01fbd
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 389 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_SERVICES_{0}', env.TARGET_ENV_UPPERCASE)] }}
AWS_DEFAULT_REGION: us-west-2

TF_VAR_hydrocronapi_api_docker_image: "ghcr.io/podaac/hydrocron:${{ env.THE_VERSION }}"
TF_VAR_hydrocron_api_api_docker_image: "ghcr.io/podaac/hydrocron:${{ env.THE_VERSION }}"

run: |
#source bin/config.sh ${{ env.THE_ENV }}
Expand Down
16 changes: 16 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:10
LABEL org.opencontainers.image.source="https://github.com/podaac/hydrocron-api"
RUN npm install forever -g

ENV project_dir /project
ENV app_dir ${project_dir}/app
ENV config_dir ${project_dir}/config

RUN mkdir ${project_dir} ${app_dir} ${config_dir}
WORKDIR ${app_dir}

COPY package*.json ./
RUN npm install
COPY . .

CMD ${app_dir}/docker/docker-start-command
48 changes: 48 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Hydrocron API Docker Image

This directory contains the `Dockerfile` used to build the Docker image capable of running hydrocron API as a lambda.

It includes a number of helper scripts to be run by the CI/CD pipeline but can also be run locally to build the image.

## Building

Building the Hydrocron API docker image depends on a tar file version of the project. This can be built using `poetry build` or by downloading a previously built version of the project as a tar.

### Building from tar

`build-docker.sh` script can be used to build the docker image from the
local tar file. There are two required arguments that must be set:

1. service-name: The name of the service being built (from pyproject.toml)
2. service-version: The version of the service being built (also from pyproject.toml)

The docker tag of the built image will be returned from the script.

Example:

```shell script
./docker/build-docker.sh -n podaac-hydrocron -v 1.0.0-alpha.3
```

## Running

The Docker image can be run directly using the `docker run` command.

See [Testing Lambda container images locally](https://docs.aws.amazon.com/lambda/latest/dg/images-test.html) for details.

## Pushing to ECR

The `push-docker-ecr.sh` script can be used to push a docker image to AWS ECR. There are two required arguments:

1. tf-venue: The target venue for uploading (sit, uat, or ops).
2. docker-tag: The docker tage of the image being pushed

The easiest way to use the `push-docker-ecr.sh` script is to first call `build-docker.sh` and save the output to the
`docker_tag` environment variable. Then call `push-docker-ecr.sh`.

Example:

```shell script
export docker_tag=$(./docker/build-docker.sh -n podaac-hydrocron -v 1.0.0-alpha.3)
./docker/push-docker-ecr.sh -v sit -t $docker_tag
```
60 changes: 60 additions & 0 deletions docker/build-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env bash

# This script is intended to be run by the CI/CD pipeline to build a specific version of the Hydrocron API.

set -Eeo pipefail

POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"

case $key in
-n|--service-name)
service_name="$2"
shift # past argument
shift # past value
;;
-v|--service-version)
service_version="$2"
shift # past argument
shift # past value
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters

USAGE="USAGE: build-docker.sh -n|--service-name service_name -v|--service-version service_version"

# shellcheck disable=SC2154
if [[ -z "${service_name}" ]]; then
echo "service_name required. Name of the service as found in pyproject.toml (e.g. podaac-staging)" >&2
echo "$USAGE" >&2
exit 1
fi

# shellcheck disable=SC2154
if [[ -z "${service_version}" ]]; then
echo "service_version required. Version of software to install (e.g. 0.1.0-a1+12353)." >&2
echo "$USAGE" >&2
exit 1
fi

set -u

SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
PROJECT_DIR="$(dirname "${SCRIPTPATH}")"

repositoryName=podaac/podaac-cloud/${service_name}

# Docker tags can't include '+' https://github.com/docker/distribution/issues/1201
dockerTagVersion=$(echo "${service_version}" | tr "+" _)

tar_filename="${service_name}-${service_version}.tar.gz"
docker build -t "${repositoryName}":"${dockerTagVersion}" --build-arg SOURCE="dist/${tar_filename}" -f "$SCRIPTPATH"/Dockerfile "$PROJECT_DIR" 1>&2

echo "${repositoryName}":"${dockerTagVersion}"
16 changes: 16 additions & 0 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
set -e

if test -f "logging.ini"; then
echo "Applying user-provided logging.ini"
else
echo "Using default logging.ini included with hydrocron. This can be overridden by mounting a python logging configuration file at $(pwd)/logging.ini"
python - <<'END'
import pkgutil
logging_conf = pkgutil.get_data('hydrocron', 'conf/logging.ini').decode("utf-8")
with open('logging.ini', 'w') as logging_ini:
logging_ini.write(logging_conf)
END
fi

uvicorn hydrocron.api:app --proxy-headers --host 0.0.0.0 --port 80 --log-config logging.ini
82 changes: 82 additions & 0 deletions docker/push-docker-ecr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env bash

# This script is intended to be run by the CI/CD pipeline to push a docker tag previously built by build-docker.sh

set -Eeo pipefail

POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"

case $key in
-t|--docker-tag)
docker_tag="$2"
echo "--- docker_tag"
echo $docker_tag
shift # past argument
shift # past value
;;
-v|--tf-venue)
tf_venue="$2"
echo "--- tf_venue"
echo $tf_venue
case $tf_venue in
sit|uat|ops) ;;
*)
echo "tf_venue must be sit, uat, or ops"
exit 1;;
esac
shift # past argument
shift # past value
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters

USAGE="push-docker-ecr.sh -t|--docker-tag docker_tag -v|--tf-venue tf_venue"

# shellcheck disable=SC2154
if [[ -z "${tf_venue}" ]]; then
echo "tf_venue required. One of sit, uat, ops" >&2
echo "$USAGE" >&2
exit 1
fi

# shellcheck disable=SC2154
if [[ -z "${docker_tag}" ]]; then
echo "docker_tag required." >&2
echo "$USAGE" >&2
exit 1
fi

set -u

repositoryName=$(echo "${docker_tag}" | awk -F':' '{print $1}')
tf_profile="ngap-service-${tf_venue}"

# Get the AWS Account ID for this venue/profile
# shellcheck disable=SC2154
aws_acct=$(aws sts get-caller-identity --profile "$tf_profile" | python -c "import sys, json; print(json.load(sys.stdin)['Account'])")
echo "aws_acct"
echo $aws_acct

# Create repository if needed
aws ecr create-repository --repository-name "${repositoryName}" --profile "$tf_profile" || echo "No need to create, repository ${repositoryName} already exists"

# Login to ECR
echo "aws ecr get-login-password --region us-west-2 --profile \"$tf_profile\" | docker login --username AWS --password-stdin \"$aws_acct\".dkr.ecr.us-west-2.amazonaws.com"
set +x
$(aws ecr get-login --no-include-email --region us-west-2 --profile "$tf_profile" 2> /dev/null) || \
docker login --username AWS --password "$(aws ecr get-login-password --region us-west-2 --profile "$tf_profile")" "$aws_acct".dkr.ecr.us-west-2.amazonaws.com
set -x

# Tag the image for this venue's ECR
docker tag "${docker_tag}" "$aws_acct".dkr.ecr.us-west-2.amazonaws.com/"${docker_tag}"

# Push the tag
docker push "$aws_acct".dkr.ecr.us-west-2.amazonaws.com/"${docker_tag}"
Loading

0 comments on commit 6a01fbd

Please sign in to comment.