A NEW WAY TO DEPLOY BLOG
I migrated my code repository during some free time.
Previously, I used Coding to manage my private code for three reasons:
- I was familiar with it from my previous job.
- The code push and pull speed in China was impressively fast.
- I had access to private mirror repositories and several hundred free minutes for continuous deployment.
However, my interest waned when it became a paid service, and I found deploying on foreign servers to be slow. Although I tried using my own nodes for deployment, their performance was lacking, likely due to the inefficiencies of the foreign servers.
Now, I use k3s to manage these servers, which simplifies mirror image deployment. The deployment process is as follows:
Local -> Github -> Docker Hub -> Pod reset -> K3s pull
Building and Pushing Images
In the file .github/workflows/build-and-deploy.yml
:
name: Build and Deploy
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.110.0'
- name: Remove old public folder
run: rm -rf public
- name: Build website
run: hugo --minify
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} # create a on docker
- name: Build image and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
push: true
tags: avacooper/blog:latest # your img path
- name: Cleanup
run: |
docker system prune -af --volumes
rm -rf ./public
The Public folder generated by Hugo contains numerous static files that can be directly utilized by nginx.
In the Dockerfile
:
FROM nginx:alpine
COPY public/ /usr/share/nginx/html/
EXPOSE 80
K3S Configuration
As I had configured the certificate manager, I did not use LoadBalancer directly but instead employed nginx-ingress.
The configuration is as follows:
apiVersion: v1
kind: Service
metadata:
name: org-domain-blog
labels:
app: blog
spec:
ports:
- port: 80
name: blog
targetPort: 80
selector:
app: blog
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: blog
spec:
replicas: 1
selector:
matchLabels:
app: blog
template:
metadata:
labels:
app: blog
spec:
containers:
- name: blog
image: avacooper/blog:latest
ports:
- containerPort: 80
imagePullPolicy: Always
# nodeSelector:
# nn: sp
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: org-domain-blog-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
spec:
ingressClassName: nginx
tls:
- hosts:
- "*.domain.org"
- "blog.domain.org"
secretName: tls
rules:
- host: blog.domain.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: org-domain-blog
port:
number: 80
The drawback is that the image uploaded to Docker Hub is public. Therefore, I plan to purchase a larger server that supports private mirror deployment.