Add CI/CD configuration

This commit is contained in:
tommansfield 2024-04-28 14:56:37 +02:00
parent 922807107f
commit a307f8bf7c
9 changed files with 151 additions and 97 deletions

View File

@ -1,25 +0,0 @@
name: merge-main-into-small-image.yml
on:
pull_request:
branches:
- main
types:
- closed
jobs:
merge-main-into-small-image:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
timeout-minutes: 3
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Merge with main
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git fetch
git checkout small-image
git merge main --no-ff --no-edit
git push origin small-image

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
# Logs # Logs
logs logs
build
*.log *.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*

103
deploy/.gitlab-ci.yml Executable file
View File

@ -0,0 +1,103 @@
stages:
- dependencies
- build
- dockerize
- deploy
variables:
NAMESPACE: sites
APP_NAME: tomcode
VERSION: latest
MOUNT_PATH: /data
STORAGE_SIZE: 128Mi
URL: tomcode.io
📚 Dependencies:
stage: dependencies
image: node:latest
cache:
- key:
files:
- package-lock.json
paths:
- .npm/
- node_modules/
policy: pull-push
script:
- echo "Downloading dependencies..."
- npm ci --cache .npm --prefer-offline
- echo "Dependencies downloaded successfully."
only:
- main
🔨 Build:
stage: build
image: node:12-alpine
cache:
- key:
files:
- package-lock.json
paths:
- .npm/
- node_modules/
policy: pull
- key: "$APP_NAME:$CI_COMMIT_REF_SLUG"
paths:
- build/
policy: pull-push
script:
- echo "Compiling the code..."
- npm run build --cache .npm --prefer-offline
- echo "Compile complete."
🐳 Dockerize:
stage: dockerize
image: docker:stable
services:
- docker:stable-dind
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
cache:
- key: "$APP_NAME:$CI_COMMIT_REF_SLUG"
paths:
- build/
policy: pull-push
before_script:
- echo "Logging into docker..."
- docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}
- echo "Login successful."
script:
- echo "Building docker image..."
- docker build -t $DOCKER_USERNAME/$APP_NAME:latest -f ./deploy/Dockerfile .
- echo "Docker image built, pushing to repository..."
- docker push $DOCKER_USERNAME/$APP_NAME:latest
- echo "Image successfully pushed."
🚀 Deploy:
stage: deploy
image: bitnami/kubectl
before_script:
- echo $KUBE_CONFIG | base64 -d > config
- mv config ~/.kube/
- echo "Preparing deployment.yaml..."
- cd deploy
- sed -i "s|{{NAMESPACE}}|$NAMESPACE|g" ./deployment.yaml
- sed -i "s|{{APP_NAME}}|$APP_NAME|g" ./deployment.yaml
- sed -i "s|{{VERSION}}|$VERSION|g" ./deployment.yaml
- sed -i "s|{{MOUNT_PATH}}|$MOUNT_PATH|g" ./deployment.yaml
- sed -i "s|{{STORAGE_SIZE}}|$STORAGE_SIZE|g" ./deployment.yaml
- sed -i "s|{{DOCKER_USERNAME}}|${DOCKER_USERNAME}|g" ./deployment.yaml
- sed -i "s|{{URL}}|$URL|g" ./deployment.yaml
- cat ./deployment.yaml
- echo "Deployment prepared."
script:
- echo "Deploying application..."
- kubectl config set-context --current --namespace=$NAMESPACE
- kubectl apply -f ./deployment.yaml
- kubectl rollout restart deploy $APP_NAME --namespace $NAMESPACE
- echo "Application successfully deployed."
only:
- main

3
deploy/Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM nginx:alpine
COPY /build /usr/share/nginx/html
COPY /deploy/default.conf /etc/nginx/conf.d/

10
deploy/default.conf Executable file
View File

@ -0,0 +1,10 @@
server {
server_name _;
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
}
}

View File

@ -1,107 +1,105 @@
apiVersion: v1 apiVersion: v1
kind: Namespace kind: Namespace
metadata: metadata:
name: sites name: {{NAMESPACE}}
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolume kind: PersistentVolume
metadata: metadata:
name: tomcode-pv name: {{APP_NAME}}-pv
labels: labels:
type: local type: local
spec: spec:
storageClassName: manual storageClassName: manual
capacity: capacity:
storage: 128Mi storage: {{STORAGE_SIZE}}
accessModes: accessModes:
- ReadWriteMany - ReadWriteMany
hostPath: hostPath:
path: "/var/lib/rancher/k3s/storage/tomcode" path: "/var/lib/rancher/k3s/storage/{{APP_NAME}}"
--- ---
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: tomcode-pvc name: {{APP_NAME}}-pvc
namespace: sites namespace: {{NAMESPACE}}
spec: spec:
volumeName: tomcode-pv volumeName: {{APP_NAME}}-pv
storageClassName: manual storageClassName: manual
accessModes: accessModes:
- ReadWriteMany - ReadWriteMany
resources: resources:
requests: requests:
storage: 128Mi storage: {{STORAGE_SIZE}}
--- ---
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: tomcode name: {{APP_NAME}}
namespace: sites namespace: {{NAMESPACE}}
labels: labels:
app: tomcode app: {{APP_NAME}}
spec: spec:
replicas: 1 replicas: 1
selector: selector:
matchLabels: matchLabels:
app: tomcode app: {{APP_NAME}}
template: template:
metadata: metadata:
labels: labels:
app: tomcode app: {{APP_NAME}}
spec: spec:
containers: containers:
- name: tomcode - name: {{APP_NAME}}
image: tommansfield/tomcode:latest image: {{DOCKER_USERNAME}}/{{APP_NAME}}:{{VERSION}}
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- containerPort: 3000 - containerPort: 80
resources: resources:
limits: limits:
memory: "128Mi" memory: "128Mi"
cpu: "1" cpu: "1"
volumeMounts: volumeMounts:
- name: tomcode-volume - name: {{APP_NAME}}-volume
mountPath: /data mountPath: /data
subPath: ./web subPath: ./web
volumes: volumes:
- name: tomcode-volume - name: {{APP_NAME}}-volume
persistentVolumeClaim: persistentVolumeClaim:
claimName: tomcode-pvc claimName: {{APP_NAME}}-pvc
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: tomcode name: {{APP_NAME}}
namespace: sites namespace: {{NAMESPACE}}
labels: labels:
app: tomcode app: {{APP_NAME}}
spec: spec:
type: LoadBalancer
ports: ports:
- name: tomcode - name: {{APP_NAME}}
port: 80 port: 80
targetPort: 3000 targetPort: 80
nodePort: 30800
selector: selector:
app: tomcode app: {{APP_NAME}}
--- ---
apiVersion: traefik.io/v1alpha1 apiVersion: traefik.io/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: tomcode name: {{APP_NAME}}
namespace: sites namespace: {{NAMESPACE}}
spec: spec:
entryPoints: entryPoints:
- websecure - websecure
routes: routes:
- kind: Rule - kind: Rule
match: Host(`tomcode.io`, `www.tomcode.io`) match: Host(`{{URL}}`, `www.{{URL}}`)
services: services:
- name: tomcode - name: {{APP_NAME}}
port: 80 port: 80
tls: tls:
certResolver: letsencrypt certResolver: letsencrypt
domains: domains:
- main: "tomcode.io" - main: "{{URL}}"
sans: sans:
- "*.tomcode.io" - "*.{{URL}}"

View File

@ -1,23 +0,0 @@
# Start your image with a node base image
FROM node:18-alpine
# The /app directory should act as the main application directory
WORKDIR /app
# Copy the app package and package-lock.json file
COPY package*.json ./
# Copy local directories to the current local directory of our docker image (/app)
COPY ./src ./src
COPY ./public ./public
# Install node packages, install serve, build the app, and remove dependencies at the end
RUN npm install \
&& npm install -g serve \
&& npm run build \
&& rm -fr node_modules
EXPOSE 3000
# Start the app using serve command
CMD [ "serve", "-s", "build" ]

17
package-lock.json generated Normal file → Executable file
View File

@ -1,11 +1,11 @@
{ {
"name": "welcome-to-docker", "name": "tomcode",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "welcome-to-docker", "name": "tomcode",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"react": "^18.2.0", "react": "^18.2.0",
@ -7738,19 +7738,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
}, },
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",

View File

@ -1,5 +1,5 @@
{ {
"name": "welcome-to-docker", "name": "tomcode",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {