diff --git a/.github/workflows/testnet_deploy_contracts.yml b/.github/workflows/testnet_deploy_contracts.yml new file mode 100644 index 00000000..90e82894 --- /dev/null +++ b/.github/workflows/testnet_deploy_contracts.yml @@ -0,0 +1,24 @@ +name: Deploy Testnet contracts + +on: workflow_dispatch + +jobs: + contracts: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + context: app + + - name: Install Doppler CLI + uses: dopplerhq/cli-action@v1 + + - name: Deploy contracts + id: deploy-contracts + env: + DOPPLER_TOKEN: ${{ secrets.TESTNET_DOPPLER_TOKEN_CONTRACTS_DEPLOY }} + run: | + cd hardhat + npm ci + doppler run -- npx hardhat deploy --network arbitrumSepolia diff --git a/.github/workflows/testnet_deploy_services.yml b/.github/workflows/testnet_deploy_services.yml new file mode 100644 index 00000000..01c78eab --- /dev/null +++ b/.github/workflows/testnet_deploy_services.yml @@ -0,0 +1,124 @@ +name: Deploy Testnet services + +on: workflow_dispatch + +jobs: + solver-build-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + context: app + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + with: + mask-password: 'true' + + - name: Solver build, tag, and push image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY_SOLVER: ${{ secrets.ECR_REPOSITORY_SOLVER }} + run: | + docker build \ + -t $ECR_REPOSITORY_SOLVER \ + -f ./docker/solver/Dockerfile \ + --build-arg="expose_via=cloudflare" \ + . + docker tag $ECR_REPOSITORY_SOLVER:latest $ECR_REGISTRY/$ECR_REPOSITORY_SOLVER:latest + docker push $ECR_REGISTRY/$ECR_REPOSITORY_SOLVER:latest + + - name: Solver deploy to EC2 instance + uses: appleboy/ssh-action@master + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY_SOLVER: ${{ secrets.ECR_REPOSITORY_SOLVER }} + TESTNET_DOPPLER_TOKEN_SOLVER: ${{ secrets.TESTNET_DOPPLER_TOKEN_SOLVER }} + with: + host: ${{ secrets.TESTNET_EC2_HOST_SOLVER }} + username: ${{ secrets.TESTNET_EC2_USERNAME_SOLVER }} + key: ${{ secrets.TESTNET_EC2_PRIVATE_KEY_SOLVER }} + envs: ECR_REGISTRY, ECR_REPOSITORY_SOLVER, TESTNET_DOPPLER_TOKEN_SOLVER + script_stop: true + script: | + docker stop solver || true + docker rm solver || true + aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $ECR_REGISTRY + docker system prune -af + docker pull $ECR_REGISTRY/$ECR_REPOSITORY_SOLVER:latest + docker run \ + -d \ + --restart always \ + --name solver \ + -e DOPPLER_TOKEN=$TESTNET_DOPPLER_TOKEN_SOLVER \ + $ECR_REGISTRY/$ECR_REPOSITORY_SOLVER:latest + + job-creator-build-deploy: + needs: [solver-build-deploy] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + context: app + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + with: + mask-password: 'true' + + - name: Job creator build, tag, and push image to Amazon ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY_JOB_CREATOR: ${{ secrets.ECR_REPOSITORY_JOB_CREATOR }} + run: | + docker build \ + -t $ECR_REPOSITORY_JOB_CREATOR \ + -f ./docker/job-creator/Dockerfile \ + . + docker tag $ECR_REPOSITORY_JOB_CREATOR:latest $ECR_REGISTRY/$ECR_REPOSITORY_JOB_CREATOR:latest + docker push $ECR_REGISTRY/$ECR_REPOSITORY_JOB_CREATOR:latest + + - name: Job creator deploy to EC2 instance + uses: appleboy/ssh-action@master + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY_JOB_CREATOR: ${{ secrets.ECR_REPOSITORY_JOB_CREATOR }} + TESTNET_DOPPLER_TOKEN_JOB_CREATOR: ${{ secrets.TESTNET_DOPPLER_TOKEN_JOB_CREATOR }} + with: + host: ${{ secrets.TESTNET_EC2_HOST_JOB_CREATOR }} + username: ${{ secrets.TESTNET_EC2_USERNAME_JOB_CREATOR }} + key: ${{ secrets.TESTNET_EC2_PRIVATE_KEY_JOB_CREATOR }} + envs: ECR_REGISTRY, ECR_REPOSITORY_JOB_CREATOR, TESTNET_DOPPLER_TOKEN_JOB_CREATOR + script_stop: true + script: | + docker stop job-creator || true + docker rm job-creator || true + aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $ECR_REGISTRY + docker system prune -af + docker pull $ECR_REGISTRY/$ECR_REPOSITORY_JOB_CREATOR:latest + docker run \ + -d \ + --restart always \ + --name job-creator \ + -e DOPPLER_TOKEN=$TESTNET_DOPPLER_TOKEN_JOB_CREATOR \ + $ECR_REGISTRY/$ECR_REPOSITORY_JOB_CREATOR:latest diff --git a/.github/workflows/testnet_restart_job_creator.yml b/.github/workflows/testnet_restart_job_creator.yml new file mode 100644 index 00000000..c6151ac5 --- /dev/null +++ b/.github/workflows/testnet_restart_job_creator.yml @@ -0,0 +1,17 @@ +name: Restart Testnet job creator + +on: workflow_dispatch + +jobs: + job-creator-restart: + runs-on: ubuntu-latest + steps: + - name: Restart job-creator container + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.TESTNET_EC2_HOST_JOB_CREATOR }} + username: ${{ secrets.TESTNET_EC2_USERNAME_JOB_CREATOR }} + key: ${{ secrets.TESTNET_EC2_PRIVATE_KEY_JOB_CREATOR }} + script_stop: true + script: | + docker restart job-creator || true diff --git a/.github/workflows/testnet_restart_solver.yml b/.github/workflows/testnet_restart_solver.yml new file mode 100644 index 00000000..019426d3 --- /dev/null +++ b/.github/workflows/testnet_restart_solver.yml @@ -0,0 +1,17 @@ +name: Restart Testnet solver + +on: workflow_dispatch + +jobs: + solver-restart: + runs-on: ubuntu-latest + steps: + - name: Restart solver container + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.TESTNET_EC2_HOST_SOLVER }} + username: ${{ secrets.TESTNET_EC2_USERNAME_SOLVER }} + key: ${{ secrets.TESTNET_EC2_PRIVATE_KEY_SOLVER }} + script_stop: true + script: | + docker restart solver || true diff --git a/DEVNET.md b/DEVNET.md index 800f9190..664e010d 100644 --- a/DEVNET.md +++ b/DEVNET.md @@ -49,21 +49,42 @@ These steps have been used for [AWS](https://aws.amazon.com/) so maybe some chan ### VM instance -Create a virtual machine to execute the component. The VM should have a running Docker daemon and should be able to pull an image from the chosen container registry. +The VM should have a running Docker daemon and should be able to pull an image from the chosen container registry. These instructions asssume an Ubuntu image. -[`How to install docker`](https://serverfault.com/questions/836198/how-to-install-docker-on-aws-ec2-instance-with-ami-ce-ee-update) +Create a virtual machine to execute the component. When creating the VM, attach an instance profile that gives it access to pull from an ECR registry. In our ops setup, we have a role named `LilypadService` that has the necessary permissions. -#### tldr; +#### Install AWS CLI + +Update the VM and install the AWS CLI: + +```sh +sudo apt update && sudo apt upgrade +sudo snap install aws-cli --classic +``` + +#### Install Docker + +Install Docker: + +```sh +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +``` + +Add your user to the `docker` group if you want to run without `sudo`: ```sh -sudo yum update -y -sudo yum install docker -y -sudo service docker start -sudo usermod -a -G docker -sudo systemctl enable docker (restart docker when VM instance restarts) +sudo usermod -aG docker ubuntu +newgrp docker ``` -To grant access to the [ECR](https://aws.amazon.com/ecr/) registry from the VM execute `aws configure` with credentials that have `pull` permissions. +The `ubuntu` user assumes the default user on Ubuntu images. The `newgrrp` command adds your user to the group without logging out and back in. + +Check that Docker is running: + +```sh +docker run hello-world +``` ### ECR repo @@ -72,5 +93,3 @@ Make sure the repo has been created. ### Cloudflare tunnel Make sure the Cloudflare tunnel has been created and linked to the desired subdomain, and pass the token to the container in the build step. - - diff --git a/docker/job-creator/Dockerfile b/docker/job-creator/Dockerfile index af3af1a5..f8c356e2 100644 --- a/docker/job-creator/Dockerfile +++ b/docker/job-creator/Dockerfile @@ -1,8 +1,6 @@ FROM golang:latest as base WORKDIR /usr/src/app -ARG doppler_config=dev - COPY . . RUN go mod download && go mod verify RUN go build -v . @@ -12,7 +10,7 @@ RUN (curl -Ls --tlsv1.2 --proto "=https" --retry 3 https://cli.doppler.com/insta RUN touch run RUN echo "#!/bin/bash" >> run -RUN echo "doppler run -p job-creator -c $doppler_config -- lilypad jobcreator" >> run +RUN echo "doppler run -- lilypad jobcreator" >> run RUN chmod +x run CMD ["/bin/bash", "./run"] diff --git a/docker/solver/Dockerfile b/docker/solver/Dockerfile index b1a76d88..fcd3ec78 100644 --- a/docker/solver/Dockerfile +++ b/docker/solver/Dockerfile @@ -4,8 +4,6 @@ FROM golang:latest as base WORKDIR /usr/src/app ARG arch=amd64 -ARG doppler_config=dev -ARG cloudflare_token="not-a-token" COPY . . RUN go mod download && go mod verify @@ -20,13 +18,13 @@ RUN echo "#!/bin/bash" >> run FROM base AS expose-cloudflare RUN curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${arch}.deb RUN dpkg -i cloudflared.deb -RUN echo "cloudflared tunnel --metrics 0.0.0.0:11113 run --token $cloudflare_token --url http://localhost:8080 &" >> run +RUN echo "doppler run --command \"cloudflared tunnel run & lilypad solver\"" >> run FROM base AS expose-local EXPOSE 8080 +RUN echo "doppler run -- lilypad solver" >> run FROM expose-$expose_via AS FINAL -RUN echo "doppler run -p solver -c $doppler_config -- lilypad solver" >> run RUN chmod +x run CMD ["/bin/bash", "./run"]