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
build
*.log
npm-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
kind: Namespace
metadata:
name: sites
name: {{NAMESPACE}}
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: tomcode-pv
name: {{APP_NAME}}-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 128Mi
storage: {{STORAGE_SIZE}}
accessModes:
- ReadWriteMany
hostPath:
path: "/var/lib/rancher/k3s/storage/tomcode"
path: "/var/lib/rancher/k3s/storage/{{APP_NAME}}"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tomcode-pvc
namespace: sites
name: {{APP_NAME}}-pvc
namespace: {{NAMESPACE}}
spec:
volumeName: tomcode-pv
volumeName: {{APP_NAME}}-pv
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 128Mi
storage: {{STORAGE_SIZE}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcode
namespace: sites
name: {{APP_NAME}}
namespace: {{NAMESPACE}}
labels:
app: tomcode
app: {{APP_NAME}}
spec:
replicas: 1
selector:
matchLabels:
app: tomcode
app: {{APP_NAME}}
template:
metadata:
labels:
app: tomcode
app: {{APP_NAME}}
spec:
containers:
- name: tomcode
image: tommansfield/tomcode:latest
- name: {{APP_NAME}}
image: {{DOCKER_USERNAME}}/{{APP_NAME}}:{{VERSION}}
imagePullPolicy: Always
ports:
- containerPort: 3000
- containerPort: 80
resources:
limits:
memory: "128Mi"
cpu: "1"
volumeMounts:
- name: tomcode-volume
- name: {{APP_NAME}}-volume
mountPath: /data
subPath: ./web
volumes:
- name: tomcode-volume
- name: {{APP_NAME}}-volume
persistentVolumeClaim:
claimName: tomcode-pvc
claimName: {{APP_NAME}}-pvc
---
apiVersion: v1
kind: Service
metadata:
name: tomcode
namespace: sites
name: {{APP_NAME}}
namespace: {{NAMESPACE}}
labels:
app: tomcode
app: {{APP_NAME}}
spec:
type: LoadBalancer
ports:
- name: tomcode
- name: {{APP_NAME}}
port: 80
targetPort: 3000
nodePort: 30800
targetPort: 80
selector:
app: tomcode
app: {{APP_NAME}}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: tomcode
namespace: sites
name: {{APP_NAME}}
namespace: {{NAMESPACE}}
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`tomcode.io`, `www.tomcode.io`)
match: Host(`{{URL}}`, `www.{{URL}}`)
services:
- name: tomcode
- name: {{APP_NAME}}
port: 80
tls:
certResolver: letsencrypt
domains:
- main: "tomcode.io"
- main: "{{URL}}"
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",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "welcome-to-docker",
"name": "tomcode",
"version": "0.1.0",
"dependencies": {
"react": "^18.2.0",
@ -7738,19 +7738,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"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": {
"version": "1.1.1",
"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",
"private": true,
"dependencies": {