Skip to content

Commit

Permalink
clinic: add deploy job to the github workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ashutoshgngwr committed Oct 25, 2023
1 parent a8c692e commit ac17819
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 4 deletions.
135 changes: 131 additions & 4 deletions .github/workflows/clinic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ on:
- main
tags:
- "**"
paths-ignore:
- "**.md"
paths:
- clinic/**
- .github/workflows/clinic.yaml
pull_request:
branches:
- main

env:
JDK_DISTRIBUTION: temurin
JAVA_VERSION: 21
NODE_VERSION: 21
NODE_VERSION: 20

jobs:
tests:
Expand Down Expand Up @@ -92,12 +93,17 @@ jobs:
npx shadow-cljs release app
- name: Build Uberjar
run: lein uberjar
# buildx uses QEMU. Docker Buildx is needed for multiplatform build.
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
password: ${{ github.token }}
- name: Generate Docker Image Tags
id: docker-image-tags
run: |
Expand All @@ -112,4 +118,125 @@ jobs:
with:
context: clinic
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.docker-image-tags.outputs.tags }}
- name: Delete Untagged Images from GHCR
uses: vlaurin/[email protected]
with:
container: ashutosh-onboarding/clinic
token: ${{ github.token }}
user: ${{ github.actor }}
keep-last: 3
prune-untagged: true

deploy:
name: Deploy
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event_name == 'push' # skip for pull requests.
needs:
- build
# GitHub won't allow using an env var to specify environment.
environment: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || 'staging' }}
env:
DEPLOYMENT_ID: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || 'staging' }}
SCP_DEST_PATH: /tmp/${{ github.sha }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.DEPLOY_BOT_ACCESS_KEY }}
defaults:
run:
working-directory: ./clinic
steps:
- name: Checkout Source
uses: actions/checkout@v4
- name: Install prerequisites
run: |
sudo apt-get -qq update -y
sudo apt-get -qq install -y awscli
- name: Get Workflow Runner's Public IP
id: workflow-runner-ip
run: echo "ipv4=$(curl -s 'https://api.ipify.org')" >> "$GITHUB_OUTPUT"
- name: Authorize runner's SSH access to EC2 host
run: |
aws ec2 authorize-security-group-ingress \
--group-id "$AWS_EC2_SG_ID" \
--protocol tcp \
--port 22 \
--cidr ${{ steps.workflow-runner-ip.outputs.ipv4 }}/32
env:
AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOY_BOT_SECRET_KEY }}
AWS_EC2_SG_ID: ${{ secrets.AWS_EC2_SG_ID }}

- name: Upload Systemd Service and Logrotate Config
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
port: ${{ secrets.SSH_PORT }}
key: ${{ secrets.SSH_KEY }}
source: clinic/deploy/systemd,clinic/deploy/logrotate
target: ${{ env.SCP_DEST_PATH }}
strip_components: 2 # remove `clinic/deploy/` path component at target.
rm: true # remove target directory before uploading data

- name: Configure Deployment
uses: appleboy/[email protected]
env:
APP_ENV: ${{ secrets.APP_ENV }}
GHCR_USER: ${{ github.actor }}
GHCR_TOKEN: ${{ github.token }}
GHCR_IMAGE: ghcr.io/nilenso/ashutosh-onboarding/clinic:${{ env.DEPLOYMENT_ID == 'staging' && 'latest' || github.ref_name }}
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
port: ${{ secrets.SSH_PORT }}
key: ${{ secrets.SSH_KEY }}
# only pass sensitive env vars from here. for others, use GitHub's env
# context, which is a little less error-prone.
envs: APP_ENV,GHCR_TOKEN
script_stop: true # stop script after first failure.
script: |
# stop existing deployment
service_name="clinic@${{ env.DEPLOYMENT_ID }}.service"
sudo systemctl stop "$service_name" || true
# pull and tag the new docker image
echo "$GHCR_TOKEN" | sudo docker login ghcr.io -u ${{ env.GHCR_USER }} --password-stdin
sudo docker pull ${{ env.GHCR_IMAGE }}
sudo docker tag ${{ env.GHCR_IMAGE }} clinic:${{ env.DEPLOYMENT_ID }}
sudo docker logout ghcr.io
# write environment configuration
sudo mkdir -p /etc/clinic
echo "$APP_ENV" | sudo tee "/etc/clinic/${{ env.DEPLOYMENT_ID }}.env" > /dev/null
# update systemd unit
sudo chown root:root ${{ env.SCP_DEST_PATH }}/systemd/*
sudo chmod 644 ${{ env.SCP_DEST_PATH }}/systemd/*
sudo mv ${{ env.SCP_DEST_PATH }}/systemd/* /etc/systemd/system/
# reload systemd daemon and restart the service
sudo systemctl daemon-reload
sudo systemctl reenable "$service_name"
sudo systemctl restart "$service_name"
# deploy logrotate config
sudo chown root:root ${{ env.SCP_DEST_PATH }}/logrotate/*
sudo chmod 644 ${{ env.SCP_DEST_PATH }}/logrotate/*
sudo mv ${{ env.SCP_DEST_PATH }}/logrotate/* /etc/logrotate.d/
# clean-up
sudo docker image prune -f
sudo rm -rf ${{ env.SCP_DEST_PATH }}
- name: Revoke runner's SSH access from EC2 host
if: ${{ always() }}
run: |
aws ec2 revoke-security-group-ingress \
--group-id "$AWS_EC2_SG_ID" \
--protocol tcp \
--port 22 \
--cidr ${{ steps.workflow-runner-ip.outputs.ipv4 }}/32
env:
AWS_SECRET_ACCESS_KEY: ${{ secrets.DEPLOY_BOT_SECRET_KEY }}
AWS_EC2_SG_ID: ${{ secrets.AWS_EC2_SG_ID }}
9 changes: 9 additions & 0 deletions clinic/deploy/logrotate/clinic
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/var/log/clinic/*.log {
daily
rotate 30
copytruncate
nocompress
nodelaycompress
notifempty
missingok
}
23 changes: 23 additions & 0 deletions clinic/deploy/systemd/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[Unit]
Description=Clinic %i
After=docker.service hapi-%i.service
Requires=docker.service hapi-%i.service

[Service]
Type=simple
ExecStartPre=-docker stop %p-%i
ExecStartPre=-docker rm %p-%i
ExecStart=docker run --rm --name %p-%i \
--pull never \
--env-file /etc/clinic/%i.env \
--network host \
--memory 500M \
--cpus 0.25 \
clinic:%i
StandardOutput=append:/var/log/clinic/%i.log
StandardError=append:/var/log/clinic/%i.log
SuccessExitStatus=130
Restart=on-failure

[Install]
WantedBy=default.target

0 comments on commit ac17819

Please sign in to comment.