production-live #11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
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: "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" |