Skip to content

production-live

production-live #10

---
name: "production-live"
on:
workflow_dispatch: {}
push:
branches:
- "main"
paths-ignore:
- ".github/workflows/fito-deploy-*.yml"
- "**/*.md"
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: false
env:
SSH_USER: "${{ secrets.FITO_ENV_CONNECTION_USER }}"
SSH_KEY: "${{ secrets.FITO_ENV_CONNECTION_PRIVATE_KEY }}"
SSH_HOST: "${{ secrets.FITO_ENV_CONNECTION_HOST }}"
ATTEMPTS: "${{ github.run_number }}"
jobs:
install-dependencies:
name: "install dependencies"
runs-on: "ubuntu-latest"
steps:
-
name: "Checkout under $GITHUB_WORKSPACE"
uses: "actions/checkout@v4"
with:
ref: "main"
-
name: "Set up NodeJS"
uses: "actions/setup-node@v3"
with:
node-version: "18.17"
-
name: "Install yarn"
run: "npm install -g yarn"
-
name: "Install dependencies"
run: "yarn install"
-
name: "Cache"
uses: "actions/cache@v3"
with:
path: "./*"
key: "${{ github.sha }}-cache"
build-application:
name: "build application"
runs-on: "ubuntu-latest"
needs: "install-dependencies"
steps:
-
name: "Cache"
uses: "actions/cache@v3"
with:
path: "./*"
key: "${{ github.sha }}-cache"
-
name: "Set up NodeJS"
uses: "actions/setup-node@v3"
with:
node-version: "18.17"
-
name: "Build application"
run: "yarn build"
-
name: "Cache"
uses: "actions/cache@v3"
with:
path: "./*\nbuild\nnode_modules\npackage.json\nstatic"
key: "${{ github.sha }}-cache"
create-and-push-docker-image:
name: "create and push docker image"
runs-on: "ubuntu-latest"
needs: "build-application"
steps:
-
name: "Cache"
uses: "actions/cache@v3"
with:
path: "./*\nbuild\nnode_modules\npackage.json\nstatic"
key: "${{ github.sha }}-cache"
-
name: "Build docker image"
run: "wget https://statics.dimaslz.dev/fito/docker/dockerfile-standard.docker.tmpl -O Dockerfile.tmpl\n export FROM=\"node:18.17-alpine\"\n export ARGS=\"\"\n export SOURCE=\"build\"\n export FILES=\"COPY node_modules /app/node_modules\nCOPY package.json /app/package.json\nCOPY static /app/static\"\n export PORT=\"3000\"\n export RUN_COMMAND=\"\\\"yarn\\\", \\\"start\\\"\"\n envsubst < Dockerfile.tmpl > Dockerfile\n docker build . -t ${{ env.ATTEMPTS }}_${{ github.sha }}_svelteuse.dimaslz.dev_production_image"
-
name: "prepare connection"
run: "mkdir -p ~/.ssh/\necho \"$SSH_KEY\" > ~/.ssh/prod.key\nchmod 600 ~/.ssh/prod.key\ncat >>~/.ssh/config <<END\nHost prod\n HostName $SSH_HOST\n User $SSH_USER\n IdentityFile ~/.ssh/prod.key\n StrictHostKeyChecking no\nEND"
-
name: "Cache"
uses: "actions/cache@v3"
with:
path: "./*\nbuild\nnode_modules\npackage.json\nstatic"
key: "${{ github.sha }}-cache"
-
name: "Push image"
run: "docker save ${{ env.ATTEMPTS }}_${{ github.sha }}_svelteuse.dimaslz.dev_production_image | bzip2 | ssh prod 'docker load'"
deployment:
name: "run image and clean"
runs-on: "ubuntu-latest"
needs: "create-and-push-docker-image"
environment:
name: "production"
url: "https://svelteuse.dimaslz.dev"
steps:
-
name: "Cache"
uses: "actions/cache@v3"
with:
path: "./*\nbuild\nnode_modules\npackage.json\nstatic"
key: "${{ github.sha }}-cache"
-
name: "prepare connection"
run: "mkdir -p ~/.ssh/\necho \"$SSH_KEY\" > ~/.ssh/prod.key\nchmod 600 ~/.ssh/prod.key\ncat >>~/.ssh/config <<END\nHost prod\n HostName $SSH_HOST\n User $SSH_USER\n IdentityFile ~/.ssh/prod.key\n StrictHostKeyChecking no\nEND"
-
name: "get current currentContainerId"
run: "currentContainerId=`ssh prod \"docker ps --format=\\\"{{.Names}} {{.ID}}\\\" | grep \\\"_svelteuse.dimaslz.dev\\\" || echo \\\"\\\"\"` && currentContainerId=`echo $currentContainerId | grep -Po \"\\s.*?$\" | tr -d \"\\n\" || echo \"\"` && echo \"currentContainerId=$currentContainerId\" >> $GITHUB_ENV"
-
name: "get current currentImageId"
run: "currentImageId=`ssh prod \"docker images --format=\\\"{{.Repository}} {{.ID}}\\\" | grep \\\"_svelteuse.dimaslz.dev\\\" || echo \\\"\\\"\"` && currentImageId=`echo $currentImageId | grep -Po \"\\s(.*?$)\" | tr -d \"\\n\" || echo \"\"` && echo \"currentImageId=$currentImageId\" >> $GITHUB_ENV"
-
name: "run"
run: "newContainerID=`ssh prod \"docker run --name ${{ env.ATTEMPTS }}_${{ github.sha }}_svelteuse.dimaslz.dev_production_container -d ${{ env.ATTEMPTS }}_${{ github.sha }}_svelteuse.dimaslz.dev_production_image\"` && echo \"newContainerID=$newContainerID\" >> $GITHUB_ENV"
-
name: "get container IP"
run: "newContainerIP=`ssh prod \"docker inspect -f \\\"{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}\\\" ${{ env.newContainerID }}\"` && echo \"newContainerIP=$newContainerIP\" >> $GITHUB_ENV"
-
name: "get container PORT"
run: "newContainerPort=`ssh prod \"docker container ls | grep \\\"${{ env.ATTEMPTS }}_${{ github.sha }}_svelteuse.dimaslz.dev_production\\\" | grep -Po \\\"\\d+/tcp \\\" | grep -Po \\\"\\d+\\\"\"` && echo \"newContainerPort=$newContainerPort\" >> $GITHUB_ENV"
-
name: "Container is not running"
if: "${{ failure() }}"
run: "echo \"container is not running\" && exit 1"
-
name: "setup nginx config"
run: "wget https://statics.dimaslz.dev/fito/nginx/static-config-auth.nginx-certbot-1-step.tmpl -O nginx.tmpl\n\texport SERVER_NAME=\"svelteuse.dimaslz.dev\"\n\texport SERVER_URL=\"http://${{ env.newContainerIP }}:${{ env.newContainerPort }}\"\n\tenvsubst < nginx.tmpl > svelteuse.dimaslz.dev\n\tscp svelteuse.dimaslz.dev prod:/etc/nginx/sites-enabled/svelteuse.dimaslz.dev\n\tssh prod \"nginx -t && systemctl restart nginx\""
-
name: "create certificates"
run: "ssh prod \"mkdir -p /usr/share/nginx/html/svelteuse.dimaslz.dev && echo \\\"1\\\" | certbot certonly --webroot -w /usr/share/nginx/html/svelteuse.dimaslz.dev -d svelteuse.dimaslz.dev --email ${{ secrets.FITO_ENV_USER_EMAIL }} --agree-tos --no-eff-email && nginx -t && systemctl restart nginx\""
-
name: "setup nginx config"
run: "wget https://statics.dimaslz.dev/fito/nginx/static-config-auth.nginx-certbot-2-step.tmpl -O nginx.tmpl\n\texport SERVER_NAME=\"svelteuse.dimaslz.dev\"\n\texport SERVER_URL=\"http://${{ env.newContainerIP }}:${{ env.newContainerPort }}\"\n\tenvsubst < nginx.tmpl > svelteuse.dimaslz.dev\n\tscp svelteuse.dimaslz.dev prod:/etc/nginx/sites-enabled/svelteuse.dimaslz.dev\n\tssh prod \"nginx -t && systemctl restart nginx\""
-
name: "setup .htpasswd authentication"
run: "ssh prod \"sh -c \\\"echo -n 'svelteuse:' > /etc/nginx/.svelteuse.dimaslz.dev-htpasswd\\\" & sh -c \\\"openssl passwd -apr1 ${{ secrets.FITO_ENV_SVELTEUSE_DIMASLZ_DEV }} >> /etc/nginx/.svelteuse.dimaslz.dev-htpasswd\\\"\""
-
name: "Container is not running"
if: "${{ failure() }}"
run: "echo \"container is not running\" && ssh prod \"docker rm -f ${{ env.newContainerID }}\" && exit 1"
-
name: "Delete previews containers"
if: "${{ success() }}"
run: "[ ! -z \"${{ env.currentContainerId }}\" ] && ssh prod \"docker rm -f ${{ env.currentContainerId }}\" || echo \"\""
-
name: "Delete previews images"
if: "${{ success() }}"
run: "[ ! -z \"${{ env.currentContainerId }}\" ] && ssh prod \"docker rmi -f ${{ env.currentImageId }}\" || echo \"\""