diff --git a/.circleci/Dockerfile b/.circleci/Dockerfile new file mode 100644 index 000000000..217f54f6a --- /dev/null +++ b/.circleci/Dockerfile @@ -0,0 +1,52 @@ +FROM node:14.16.0-buster-slim as node + +FROM node as build +# Having multiple steps in builder doesn't increase the final image size +# So having verbose steps for readability and caching should be the target + +WORKDIR /opt/viewer +COPY packages/viewer/package*.json ./ +RUN npm install +COPY packages/viewer . +RUN npm run build + +WORKDIR /opt/frontend +# Copy package defs first they are the least likely to change +# Keeping this order will least likely trigger full rebuild +COPY packages/frontend/package*.json ./ +RUN npm install ../viewer +RUN npm ci + +WORKDIR /opt +COPY packages/server/package*.json server/ +ENV NODE_ENV production +RUN npm --prefix server ci server + +# Copy remaining files across for frontend. Changes to these files +# will be more common than changes to the dependencies. This should +# speed up rebuilds. +COPY packages/frontend frontend + +WORKDIR /opt/frontend +RUN npm run build + +# --- +FROM node as runtime + +RUN apt-get update && apt-get install -y \ + tini \ + && rm -rf /var/lib/apt/lists/* + +# Copy dependencies and static files from build layer +COPY --from=build --chown=node /opt/frontend/dist /home/node/frontend/dist +COPY --from=build --chown=node /opt/server /home/node/server + +# Run the application from the non root users home directory +WORKDIR /home/node/server + +COPY packages/server /home/node/server + +ENV NODE_ENV production + +ENTRYPOINT [ "tini", "--" ] +CMD ["node", "bin/www"] diff --git a/.circleci/ci-build-and-deploy.sh b/.circleci/ci-build-and-deploy.sh new file mode 100755 index 000000000..f705ff9e1 --- /dev/null +++ b/.circleci/ci-build-and-deploy.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -e + +# TAG_VER=2.0.$CIRCLE_BUILD_NUM + +docker build -t $DOCKER_IMAGE_TAG:latest . -f .circleci/Dockerfile +docker tag $DOCKER_IMAGE_TAG:latest $DOCKER_IMAGE_TAG:$CIRCLE_SHA1 + +echo "$DOCKER_REG_PASS" | docker login -u "$DOCKER_REG_USER" --password-stdin $DOCKER_REG_URL +docker push $DOCKER_IMAGE_TAG:latest +docker push $DOCKER_IMAGE_TAG:$CIRCLE_SHA1 + +echo "$K8S_CLUSTER_CERTIFICATE" | base64 --decode > k8s_cert.crt + +./kubectl \ + --kubeconfig=/dev/null \ + --server=$K8S_SERVER \ + --certificate-authority=k8s_cert.crt \ + --token=$K8S_TOKEN \ + set image deployment/$SPECKLE_K8S_DEPLOYMENT main=$DOCKER_IMAGE_TAG:$CIRCLE_SHA1 + +./kubectl \ + --kubeconfig=/dev/null \ + --server=$K8S_SERVER \ + --certificate-authority=k8s_cert.crt \ + --token=$K8S_TOKEN \ + rollout status -w deployment/$SPECKLE_K8S_DEPLOYMENT --timeout=1m diff --git a/.circleci/config.yml b/.circleci/config.yml index 52013f8d1..a69a270b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,9 +8,17 @@ version: 2.1 workflows: version: 2.1 - build: + test: jobs: - test_server + deploy: + jobs: + - docker_build_and_deploy: + context: main-builds + filters: + branches: + only: main + jobs: test_server: @@ -43,3 +51,19 @@ jobs: - run: command: 'bash <(curl -s https://codecov.io/bash)' working_directory: 'packages/server' + + docker_build_and_deploy: + docker: + - image: circleci/golang:1.15 + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Install kubectl + command: | + curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl + chmod u+x ./kubectl + - run: + name: Create and Deploy Docker image + command: ./.circleci/ci-build-and-deploy.sh