ci: build, push and deploy to personal cluster on push to master
- Gitea Actions workflow: build, push sha-tagged image, apply kustomize, wait for rollout with auto-rollback - Deploy to personal-site namespace, served at jesseinit.dev with TLS - Run container as non-root and bind to 0.0.0.0 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3bb0a5e4a9
commit
0927b9d665
@@ -6,3 +6,5 @@ README.md
|
|||||||
.env*
|
.env*
|
||||||
.next
|
.next
|
||||||
.git
|
.git
|
||||||
|
.github
|
||||||
|
k8s
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
name: CI and Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: tea.jesseinit.dev
|
||||||
|
IMAGE_NAME: ${{ github.repository_owner }}/personal-site
|
||||||
|
NAMESPACE: personal-site
|
||||||
|
DEPLOYMENT: jesseinit-portfolio
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: deploy-${{ github.ref }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
name: Build site
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
# The Gitea runner image only caches Node 24; match the Dockerfile's Node 22.
|
||||||
|
container: node:22-bookworm
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Validate Kubernetes manifests
|
||||||
|
run: |
|
||||||
|
curl -fsSL "https://dl.k8s.io/release/v1.34.3/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl
|
||||||
|
chmod +x /usr/local/bin/kubectl
|
||||||
|
kubectl kustomize k8s/ > /dev/null
|
||||||
|
|
||||||
|
build-image:
|
||||||
|
name: Build and push image
|
||||||
|
needs: ci
|
||||||
|
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v4
|
||||||
|
|
||||||
|
- name: Log in to Gitea Container Registry
|
||||||
|
uses: docker/login-action@v4
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract image metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v6
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=raw,value=latest
|
||||||
|
type=sha,format=long
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v7
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||||
|
cache-to: type=inline
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: Deploy to Kubernetes
|
||||||
|
needs: build-image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: production
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Set up kubectl
|
||||||
|
uses: azure/setup-kubectl@v5.1.0
|
||||||
|
with:
|
||||||
|
version: v1.34.3
|
||||||
|
|
||||||
|
- name: Configure kubectl
|
||||||
|
env:
|
||||||
|
KUBE_CONFIG_B64: ${{ secrets.KUBE_CONFIG }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "${KUBE_CONFIG_B64}" ]; then
|
||||||
|
echo "::error::KUBE_CONFIG is not configured in the production environment or repository."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
KUBECONFIG_PATH="${RUNNER_TEMP}/personal-site-kubeconfig"
|
||||||
|
umask 077
|
||||||
|
printf '%s' "${KUBE_CONFIG_B64}" | base64 --decode > "${KUBECONFIG_PATH}"
|
||||||
|
echo "KUBECONFIG=${KUBECONFIG_PATH}" >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
KUBECONFIG="${KUBECONFIG_PATH}" kubectl cluster-info --request-timeout=15s
|
||||||
|
|
||||||
|
- name: Pin image to this commit
|
||||||
|
run: sed -i "s/newTag: latest/newTag: sha-${GITHUB_SHA}/" k8s/kustomization.yaml
|
||||||
|
|
||||||
|
- name: Apply manifests
|
||||||
|
run: kubectl apply -k k8s/
|
||||||
|
|
||||||
|
- name: Wait for rollout
|
||||||
|
run: |
|
||||||
|
if ! kubectl rollout status "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" --timeout=5m; then
|
||||||
|
kubectl get pods -n "${NAMESPACE}" -o wide
|
||||||
|
kubectl describe pods -n "${NAMESPACE}" | tail -40
|
||||||
|
kubectl rollout undo "deployment/${DEPLOYMENT}" -n "${NAMESPACE}" || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Verify deployment
|
||||||
|
run: |
|
||||||
|
kubectl get deployments,pods,services,ingress -n "${NAMESPACE}"
|
||||||
|
echo "### Deployed sha-${GITHUB_SHA} to ${NAMESPACE}" >> "${GITHUB_STEP_SUMMARY}"
|
||||||
+8
-4
@@ -16,8 +16,12 @@ RUN npm run build
|
|||||||
# Run
|
# Run
|
||||||
FROM base AS run
|
FROM base AS run
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
RUN mkdir .next
|
ENV HOSTNAME=0.0.0.0
|
||||||
COPY --from=build /app/public ./public
|
ENV PORT=3000
|
||||||
COPY --from=build /app/.next/standalone ./
|
RUN mkdir .next && chown node:node .next
|
||||||
COPY --from=build /app/.next/static ./.next/static
|
COPY --from=build --chown=node:node /app/public ./public
|
||||||
|
COPY --from=build --chown=node:node /app/.next/standalone ./
|
||||||
|
COPY --from=build --chown=node:node /app/.next/static ./.next/static
|
||||||
|
USER node
|
||||||
|
EXPOSE 3000
|
||||||
CMD ["node", "server.js"]
|
CMD ["node", "server.js"]
|
||||||
+31
-214
@@ -1,225 +1,42 @@
|
|||||||
# Kubernetes Deployment Guide
|
# Kubernetes deployment
|
||||||
|
|
||||||
This directory contains all the necessary Kubernetes manifests to deploy the jesseinit portfolio application.
|
The site runs on the personal k3s cluster in the `personal-site` namespace and is served at
|
||||||
|
https://jesseinit.dev (`www.` redirects to the apex). TLS comes from cert-manager (`letsencrypt-prod`).
|
||||||
|
|
||||||
## Prerequisites
|
## How deploys work
|
||||||
|
|
||||||
- Kubernetes cluster (local or cloud)
|
`.github/workflows/deploy.yml` (run by Gitea Actions) on every push to `master`:
|
||||||
- kubectl CLI installed and configured
|
|
||||||
- Docker for building the image
|
|
||||||
- (Optional) kustomize for managing configurations
|
|
||||||
|
|
||||||
## Files Overview
|
1. **Build site**: `npm ci && npm run build`, and renders the kustomization to catch manifest errors.
|
||||||
|
2. **Build and push image**: `tea.jesseinit.dev/jesseinit/personal-site:sha-<commit>` and `:latest`.
|
||||||
|
3. **Deploy**: pins `newTag` in `kustomization.yaml` to `sha-<commit>`, runs `kubectl apply -k k8s/`,
|
||||||
|
waits for the rollout, and rolls back automatically if it fails.
|
||||||
|
|
||||||
- `deployment.yaml` - Kubernetes Deployment with 2 replicas, health checks, and resource limits
|
Pull requests run step 1 only. Old images are cleaned up by the nightly `gitea-package-prune` cronjob.
|
||||||
- `service.yaml` - ClusterIP Service exposing the application on port 80
|
|
||||||
- `ingress.yaml` - Ingress resource for external access (requires ingress controller)
|
|
||||||
- `configmap.yaml` - ConfigMap for environment variables
|
|
||||||
- `kustomization.yaml` - Kustomize configuration for easy deployment management
|
|
||||||
|
|
||||||
## Quick Start
|
### Required secrets (repo or `production` environment in Gitea)
|
||||||
|
|
||||||
### 1. Build the Docker Image
|
| Secret | Value |
|
||||||
|
| ---------------- | ----------------------------------------------------- |
|
||||||
|
| `REGISTRY_TOKEN` | Gitea token with `write:package` for `jesseinit` |
|
||||||
|
| `KUBE_CONFIG` | base64-encoded kubeconfig for the personal cluster |
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
- `namespace.yaml`: `personal-site` namespace
|
||||||
|
- `deployment.yaml`: 2 replicas, zero-downtime rolling updates, non-root, health checks
|
||||||
|
- `service.yaml`: ClusterIP on port 80 → container port 3000
|
||||||
|
- `ingress.yaml`: nginx ingress + TLS for `jesseinit.dev` / `www.jesseinit.dev`
|
||||||
|
- `configmap.yaml`: optional environment variables
|
||||||
|
- `kustomization.yaml`: ties it together and sets the image
|
||||||
|
|
||||||
|
## Manual operations
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build the image
|
kubectl --context personal-cluster -n personal-site get pods,ingress,certificate
|
||||||
docker build -t jesseinit-portfolio:latest .
|
kubectl --context personal-cluster -n personal-site logs -l app=jesseinit-portfolio -f
|
||||||
|
kubectl --context personal-cluster -n personal-site rollout undo deployment/jesseinit-portfolio
|
||||||
|
|
||||||
# If using a registry, tag and push
|
# Deploy by hand (uses :latest)
|
||||||
docker tag jesseinit-portfolio:latest <your-registry>/jesseinit-portfolio:latest
|
kubectl --context personal-cluster apply -k k8s/
|
||||||
docker push <your-registry>/jesseinit-portfolio:latest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Update Image Reference (if using a registry)
|
|
||||||
|
|
||||||
Edit `k8s/kustomization.yaml` and update the image reference:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
images:
|
|
||||||
- name: jesseinit-portfolio
|
|
||||||
newName: <your-registry>/jesseinit-portfolio
|
|
||||||
newTag: latest
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Deploy to Kubernetes
|
|
||||||
|
|
||||||
#### Option A: Using kubectl
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Apply all manifests
|
|
||||||
kubectl apply -f k8s/
|
|
||||||
|
|
||||||
# Verify deployment
|
|
||||||
kubectl get pods -l app=jesseinit-portfolio
|
|
||||||
kubectl get svc jesseinit-portfolio
|
|
||||||
kubectl get ingress jesseinit-portfolio
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Option B: Using Kustomize
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Deploy using kustomize
|
|
||||||
kubectl apply -k k8s/
|
|
||||||
|
|
||||||
# Or build and preview first
|
|
||||||
kubectl kustomize k8s/ | kubectl apply -f -
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Configure Ingress (Optional)
|
|
||||||
|
|
||||||
Edit `k8s/ingress.yaml` to match your setup:
|
|
||||||
|
|
||||||
1. Update the `host` field with your domain
|
|
||||||
2. Set the correct `ingressClassName` (nginx, traefik, etc.)
|
|
||||||
3. Uncomment TLS section if using HTTPS
|
|
||||||
4. Add appropriate annotations for your ingress controller
|
|
||||||
|
|
||||||
Example for NGINX with cert-manager:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
||||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Add Environment Variables (Optional)
|
|
||||||
|
|
||||||
Edit `k8s/configmap.yaml` to add any required environment variables:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
data:
|
|
||||||
API_URL: "https://api.example.com"
|
|
||||||
NEXT_PUBLIC_SITE_URL: "https://jesseinit.com"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Local Development with Minikube
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start minikube
|
|
||||||
minikube start
|
|
||||||
|
|
||||||
# Build image in minikube's Docker daemon
|
|
||||||
eval $(minikube docker-env)
|
|
||||||
docker build -t jesseinit-portfolio:latest .
|
|
||||||
|
|
||||||
# Deploy
|
|
||||||
kubectl apply -k k8s/
|
|
||||||
|
|
||||||
# Access the application
|
|
||||||
minikube service jesseinit-portfolio
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoring
|
|
||||||
|
|
||||||
### Check Pod Status
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl get pods -l app=jesseinit-portfolio
|
|
||||||
kubectl logs -l app=jesseinit-portfolio -f
|
|
||||||
kubectl describe pod <pod-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check Service
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl get svc jesseinit-portfolio
|
|
||||||
kubectl describe svc jesseinit-portfolio
|
|
||||||
```
|
|
||||||
|
|
||||||
### Port Forward for Local Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl port-forward svc/jesseinit-portfolio 8080:80
|
|
||||||
# Access at http://localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
## Scaling
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Scale to 3 replicas
|
|
||||||
kubectl scale deployment jesseinit-portfolio --replicas=3
|
|
||||||
|
|
||||||
# Or edit deployment.yaml and reapply
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating the Application
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build new image with new tag
|
|
||||||
docker build -t jesseinit-portfolio:v2 .
|
|
||||||
docker push <your-registry>/jesseinit-portfolio:v2
|
|
||||||
|
|
||||||
# Update the image
|
|
||||||
kubectl set image deployment/jesseinit-portfolio portfolio=<your-registry>/jesseinit-portfolio:v2
|
|
||||||
|
|
||||||
# Or update kustomization.yaml and reapply
|
|
||||||
kubectl apply -k k8s/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Pods not starting
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl describe pod <pod-name>
|
|
||||||
kubectl logs <pod-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Service not accessible
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl get endpoints jesseinit-portfolio
|
|
||||||
kubectl describe svc jesseinit-portfolio
|
|
||||||
```
|
|
||||||
|
|
||||||
### Image pull errors
|
|
||||||
|
|
||||||
If using a private registry, create an image pull secret:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl create secret docker-registry regcred \
|
|
||||||
--docker-server=<your-registry> \
|
|
||||||
--docker-username=<username> \
|
|
||||||
--docker-password=<password> \
|
|
||||||
--docker-email=<email>
|
|
||||||
```
|
|
||||||
|
|
||||||
Then add to `deployment.yaml`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
spec:
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: regcred
|
|
||||||
```
|
|
||||||
|
|
||||||
## Resource Management
|
|
||||||
|
|
||||||
The deployment includes default resource requests and limits:
|
|
||||||
|
|
||||||
- Requests: 128Mi memory, 100m CPU
|
|
||||||
- Limits: 512Mi memory, 500m CPU
|
|
||||||
|
|
||||||
Adjust these in `deployment.yaml` based on your application's needs.
|
|
||||||
|
|
||||||
## Cleanup
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Delete all resources
|
|
||||||
kubectl delete -k k8s/
|
|
||||||
|
|
||||||
# Or delete individually
|
|
||||||
kubectl delete -f k8s/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Production Considerations
|
|
||||||
|
|
||||||
1. **Use a specific image tag** instead of `latest` for better version control
|
|
||||||
2. **Set up HorizontalPodAutoscaler** for automatic scaling
|
|
||||||
3. **Configure persistent storage** if needed (for logs, cache, etc.)
|
|
||||||
4. **Add network policies** for security
|
|
||||||
5. **Set up monitoring** with Prometheus/Grafana
|
|
||||||
6. **Configure TLS/SSL** certificates for HTTPS
|
|
||||||
7. **Use secrets** for sensitive data instead of ConfigMaps
|
|
||||||
8. **Implement resource quotas** and limit ranges
|
|
||||||
9. **Set up backup and disaster recovery** procedures
|
|
||||||
10. **Use namespace isolation** for multi-environment deployments
|
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ metadata:
|
|||||||
app: jesseinit-portfolio
|
app: jesseinit-portfolio
|
||||||
spec:
|
spec:
|
||||||
replicas: 2
|
replicas: 2
|
||||||
|
revisionHistoryLimit: 5
|
||||||
|
strategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
rollingUpdate:
|
||||||
|
maxUnavailable: 0
|
||||||
|
maxSurge: 1
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: jesseinit-portfolio
|
app: jesseinit-portfolio
|
||||||
@@ -24,12 +30,20 @@ spec:
|
|||||||
env:
|
env:
|
||||||
- name: NODE_ENV
|
- name: NODE_ENV
|
||||||
value: "production"
|
value: "production"
|
||||||
|
- name: HOSTNAME
|
||||||
|
value: "0.0.0.0"
|
||||||
|
- name: PORT
|
||||||
|
value: "3000"
|
||||||
- name: NEXT_TELEMETRY_DISABLED
|
- name: NEXT_TELEMETRY_DISABLED
|
||||||
value: "1"
|
value: "1"
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: jesseinit-portfolio-config
|
name: jesseinit-portfolio-config
|
||||||
optional: true
|
optional: true
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
memory: "128Mi"
|
memory: "128Mi"
|
||||||
|
|||||||
+11
-10
@@ -5,13 +5,19 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app: jesseinit-portfolio
|
app: jesseinit-portfolio
|
||||||
annotations:
|
annotations:
|
||||||
# Uncomment and configure based on your ingress controller
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
# cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
# Redirect www.jesseinit.dev -> jesseinit.dev
|
||||||
|
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx # Change to your ingress class (nginx, traefik, etc.)
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- jesseinit.dev
|
||||||
|
- www.jesseinit.dev
|
||||||
|
secretName: personal-site-tls
|
||||||
rules:
|
rules:
|
||||||
- host: jesseinit.com # Replace with your domain
|
- host: jesseinit.dev
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
@@ -21,8 +27,3 @@ spec:
|
|||||||
name: jesseinit-portfolio
|
name: jesseinit-portfolio
|
||||||
port:
|
port:
|
||||||
number: 80
|
number: 80
|
||||||
# Uncomment for TLS/HTTPS support
|
|
||||||
# tls:
|
|
||||||
# - hosts:
|
|
||||||
# - jesseinit.com
|
|
||||||
# secretName: jesseinit-portfolio-tls
|
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
|
|
||||||
namespace: default
|
namespace: personal-site
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
|
- namespace.yaml
|
||||||
- configmap.yaml
|
- configmap.yaml
|
||||||
- deployment.yaml
|
- deployment.yaml
|
||||||
- service.yaml
|
- service.yaml
|
||||||
- ingress.yaml
|
- ingress.yaml
|
||||||
|
|
||||||
commonLabels:
|
labels:
|
||||||
app: jesseinit-portfolio
|
- pairs:
|
||||||
|
app.kubernetes.io/name: personal-site
|
||||||
|
app.kubernetes.io/managed-by: kustomize
|
||||||
|
|
||||||
|
# CI rewrites newTag to sha-<commit> before applying.
|
||||||
images:
|
images:
|
||||||
- name: jesseinit-portfolio
|
- name: jesseinit-portfolio
|
||||||
newName: jesseinit-portfolio
|
newName: tea.jesseinit.dev/jesseinit/personal-site
|
||||||
newTag: latest
|
newTag: latest
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: personal-site
|
||||||
Reference in New Issue
Block a user