feat: new post 21-09-2024
This commit is contained in:
parent
f5c891910e
commit
20a993d258
20
.eleventy.js
20
.eleventy.js
@ -1,28 +1,35 @@
|
|||||||
const blogTools = require("eleventy-plugin-blog-tools");
|
const blogTools = require("eleventy-plugin-blog-tools");
|
||||||
const markdownIt = require("markdown-it");
|
const markdownIt = require("markdown-it");
|
||||||
const markdownItAttrs = require("markdown-it-attrs");
|
const markdownItAttrs = require("markdown-it-attrs");
|
||||||
|
const markdownItAnchor = require("markdown-it-anchor");
|
||||||
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
|
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
|
||||||
|
|
||||||
|
|
||||||
// Import prior to `module.exports` within `.eleventy.js`
|
|
||||||
const { DateTime } = require("luxon");
|
const { DateTime } = require("luxon");
|
||||||
|
|
||||||
|
|
||||||
module.exports = function(eleventyConfig) {
|
module.exports = function(eleventyConfig) {
|
||||||
const mdOptions = {
|
const mdOptions = {
|
||||||
html: true,
|
html: true,
|
||||||
breaks: true,
|
breaks: true,
|
||||||
linkify: true,
|
linkify: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const markdownLib = markdownIt(mdOptions)
|
const markdownLib = markdownIt(mdOptions)
|
||||||
.use(markdownItAttrs)
|
.use(markdownItAttrs)
|
||||||
|
.use(markdownItAnchor, {
|
||||||
|
permalink: markdownItAnchor.permalink.linkInsideHeader({
|
||||||
|
// Change the symbol to a link icon, e.g., "🔗"
|
||||||
|
symbol: '🔗', // Change this to whatever symbol you want
|
||||||
|
class: 'anchor-link', // You can style this class with CSS
|
||||||
|
ariaHidden: false,
|
||||||
|
tabIndex: -1,
|
||||||
|
before: '', // Leave empty to not add anything before the icon
|
||||||
|
})
|
||||||
|
})
|
||||||
.disable("code");
|
.disable("code");
|
||||||
|
|
||||||
eleventyConfig.addFilter("postDate", (dateObj) => {
|
eleventyConfig.addFilter("postDate", (dateObj) => {
|
||||||
return DateTime.fromJSDate(dateObj).toLocaleString(DateTime.DATE_MED);
|
return DateTime.fromJSDate(dateObj).toLocaleString(DateTime.DATE_MED);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
eleventyConfig.setLibrary("md", markdownLib);
|
eleventyConfig.setLibrary("md", markdownLib);
|
||||||
|
|
||||||
eleventyConfig.setUseGitIgnore(false);
|
eleventyConfig.setUseGitIgnore(false);
|
||||||
@ -38,7 +45,7 @@ module.exports = function(eleventyConfig) {
|
|||||||
eleventyConfig.setTemplateFormats("html,njk,md");
|
eleventyConfig.setTemplateFormats("html,njk,md");
|
||||||
|
|
||||||
eleventyConfig.addCollection('posts', function(collectionApi) {
|
eleventyConfig.addCollection('posts', function(collectionApi) {
|
||||||
return collectionApi.getFilteredByGlob('src/blog/posts/**/*.md')
|
return collectionApi.getFilteredByGlob('src/blog/posts/**/*.md');
|
||||||
});
|
});
|
||||||
|
|
||||||
eleventyConfig.addPlugin(blogTools);
|
eleventyConfig.addPlugin(blogTools);
|
||||||
@ -46,7 +53,6 @@ module.exports = function(eleventyConfig) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
passthroughFileCopy: true,
|
passthroughFileCopy: true,
|
||||||
|
|
||||||
dir: {
|
dir: {
|
||||||
input: 'src',
|
input: 'src',
|
||||||
includes: '_includes',
|
includes: '_includes',
|
||||||
|
36
package-lock.json
generated
36
package-lock.json
generated
@ -128,6 +128,7 @@
|
|||||||
"lodash.deburr": "^4.1.0",
|
"lodash.deburr": "^4.1.0",
|
||||||
"lru-cache": "^10.4.3",
|
"lru-cache": "^10.4.3",
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
|
"markdown-it-anchor": "^9.2.0",
|
||||||
"maximatch": "^0.1.0",
|
"maximatch": "^0.1.0",
|
||||||
"mdurl": "^1.0.1",
|
"mdurl": "^1.0.1",
|
||||||
"merge2": "^1.4.1",
|
"merge2": "^1.4.1",
|
||||||
@ -652,6 +653,28 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/linkify-it": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/markdown-it": {
|
||||||
|
"version": "14.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||||
|
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/linkify-it": "^5",
|
||||||
|
"@types/mdurl": "^2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/mdurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/@types/minimatch": {
|
"node_modules/@types/minimatch": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
||||||
@ -2901,7 +2924,6 @@
|
|||||||
"version": "13.0.2",
|
"version": "13.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
|
||||||
"integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
|
"integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argparse": "^2.0.1",
|
"argparse": "^2.0.1",
|
||||||
"entities": "~3.0.1",
|
"entities": "~3.0.1",
|
||||||
@ -2913,6 +2935,15 @@
|
|||||||
"markdown-it": "bin/markdown-it.js"
|
"markdown-it": "bin/markdown-it.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/markdown-it-anchor": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/markdown-it": "*",
|
||||||
|
"markdown-it": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/markdown-it-attrs": {
|
"node_modules/markdown-it-attrs": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.2.0.tgz",
|
||||||
@ -2928,8 +2959,7 @@
|
|||||||
"node_modules/markdown-it/node_modules/argparse": {
|
"node_modules/markdown-it/node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/maximatch": {
|
"node_modules/maximatch": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
@ -146,6 +146,7 @@
|
|||||||
"lodash.deburr": "^4.1.0",
|
"lodash.deburr": "^4.1.0",
|
||||||
"lru-cache": "^10.4.3",
|
"lru-cache": "^10.4.3",
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
|
"markdown-it-anchor": "^9.2.0",
|
||||||
"maximatch": "^0.1.0",
|
"maximatch": "^0.1.0",
|
||||||
"mdurl": "^1.0.1",
|
"mdurl": "^1.0.1",
|
||||||
"merge2": "^1.4.1",
|
"merge2": "^1.4.1",
|
||||||
|
BIN
src/assets/img/gitea-action-successful.png
Normal file
BIN
src/assets/img/gitea-action-successful.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
src/assets/img/gitea-secrets.png
Normal file
BIN
src/assets/img/gitea-secrets.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
124
src/blog/posts/2024/09/21-WebsiteDeployment.md
Normal file
124
src/blog/posts/2024/09/21-WebsiteDeployment.md
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
---
|
||||||
|
layout: layouts/post.njk
|
||||||
|
title: Continuous Integration & Continuous Deployment
|
||||||
|
description: Website Deployment using CI/CD Piplines
|
||||||
|
date: 2024-09-21
|
||||||
|
author: Matthew McKinnon
|
||||||
|
---
|
||||||
|
<!-- excerpt start -->
|
||||||
|
|
||||||
|
### {{ description }}
|
||||||
|
|
||||||
|
<center>
|
||||||
|
|
||||||
|
![](https://cd.foundation/wp-content/uploads/sites/78/2020/09/devops.png){width=800}
|
||||||
|
|
||||||
|
</center>
|
||||||
|
|
||||||
|
Since the reset of the website, I have been working on getting it to auto build and deploy using [Gitea Actions](https://docs.gitea.com/usage/actions/overview). Which is similar and compatible to [GitHub Actions](https://github.com/features/actions)
|
||||||
|
|
||||||
|
Before implementing the action it was a manual process which required using docker commands to login, build and push the image to the container registry.
|
||||||
|
|
||||||
|
<!-- excerpt end -->
|
||||||
|
|
||||||
|
### Why use CI/CD?
|
||||||
|
|
||||||
|
It takes the manual process steps away and does them for you, helping you to avoid missing any steps and avoiding errors. This also makes the interaction seamless and automated.
|
||||||
|
|
||||||
|
### Setting up the Aciton
|
||||||
|
|
||||||
|
To setup the action we first needed to create some "secrets" in the repo. Secrets are secure variables that are requied to interact with systems. Such as passwords, usernames, SSH Keys etc.
|
||||||
|
|
||||||
|
![gitea secrets](/assets/img/gitea-secrets.png)
|
||||||
|
|
||||||
|
After populating our secrets file we can then create our ```.gitea/workflows/build.yml``` file. This file contains all the steps to build, test and deploy the container.
|
||||||
|
|
||||||
|
{% raw %}
|
||||||
|
```yml
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build-node:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: catthehacker/ubuntu:act-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
|
||||||
|
- name: Install Node Dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build 11ty Site
|
||||||
|
run: npm run build --if-present
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: git.comprofix.com
|
||||||
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: ./
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: git.comprofix.com/mmckinnon/comprofix.com:latest
|
||||||
|
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Publish Website
|
||||||
|
run: |
|
||||||
|
mkdir ~/.ssh
|
||||||
|
echo "${{ secrets.SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
|
||||||
|
chmod 644 ~/.ssh/known_hosts
|
||||||
|
eval $(ssh-agent -s)
|
||||||
|
ssh-add <(echo "${{ secrets.SSH_PRIVATE_KEY }}")
|
||||||
|
ssh administrator@comprofix.com "cd /opt/comprofix; docker compose down" || true
|
||||||
|
scp docker-compose.yml administrator@comprofix.com:/opt/comprofix
|
||||||
|
ssh administrator@comprofix.com "cd /opt/comprofix; docker compose pull; docker compose up -d"
|
||||||
|
```
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
### build.yml explained
|
||||||
|
|
||||||
|
* ```yml
|
||||||
|
on: push
|
||||||
|
```
|
||||||
|
This tells the action to run when code is pushed to the repo.
|
||||||
|
* ```yml
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: catthehacker/ubuntu:act-latest
|
||||||
|
```
|
||||||
|
This specified the "container" to use to run all the steps on. This was crucial as running without a "conatiner" would fail as not all required dependencies where available
|
||||||
|
* ```yml
|
||||||
|
jobs:
|
||||||
|
build-node:
|
||||||
|
...
|
||||||
|
publish:
|
||||||
|
```
|
||||||
|
These are the names of the separate jobs for the build action. The build node will build the site and create the new docker container and push to the registry. The publish will connect the host running the container and restart using the new container.
|
||||||
|
* ```yml
|
||||||
|
steps:
|
||||||
|
```
|
||||||
|
Each job has a list of steps it performs on the code. Most of these a pretty self explaining on what they do. Everything from check out the code. Setup Node environment and build. Run the docker commands to login to the registry, build the container and push. Then the last job steps connect the host and pull the new container and start.
|
||||||
|
|
||||||
|
|
||||||
|
### Gitea Action Completes
|
||||||
|
|
||||||
|
Once the new code was commited to the repo the Action was able to complete successfully.
|
||||||
|
|
||||||
|
![alt text](/assets/img/gitea-action-successful.png){width=1200}
|
||||||
|
|
@ -1,3 +1,11 @@
|
|||||||
|
.anchor-link {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
font-size: 0.8em; /* Adjust size as needed */
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* styles.css */
|
/* styles.css */
|
||||||
:root {
|
:root {
|
||||||
--bg-color: lightgrey;
|
--bg-color: lightgrey;
|
||||||
|
Loading…
Reference in New Issue
Block a user