diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..0af4a1d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,96 @@ +image: node:20 + +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - if: $CI_COMMIT_BRANCH == "production" + - if: $CI_COMMIT_BRANCH == "dev" + - if: $CI_COMMIT_TAG =~ /^v[\d]{1,4}\.[\d]{1,2}\.[\d]{1,2}$/ + +stages: + - build + - docker + - deploy + +cache: + key: ${CI_COMMIT_REF_SLUG} + paths: + - node_modules/ + +variables: + NEXT_PUBLIC_ENV: "production" + OUTPUT_DIR: ".next" + PROJECT_NAME: $CI_PROJECT_NAME + DOCKER_IMAGE: "registry.boomlab.party/rheinsw/$CI_PROJECT_NAME" + +# Reusable SSH key setup block +.install_deploy_key: &install_deploy_key + - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' + - mkdir -p ~/.ssh + - echo "$DEPLOY_KEY_BASE64" | base64 -d > ~/.ssh/deploy_key + - eval "$(ssh-agent -s)" + - chmod 600 ~/.ssh/deploy_key + - ssh-add ~/.ssh/deploy_key + - ssh-keyscan -p 22 -H '192.168.41.101' >> ~/.ssh/known_hosts || true + +build: + stage: build + script: + - npm install + - npx next build + - npm run lint + +dockerize: + stage: docker + image: docker:latest + services: + - docker:dind + before_script: + - echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin + script: + - | + if [[ "$CI_COMMIT_REF_NAME" == "production" ]]; then + TAG="latest" + elif [[ "$CI_COMMIT_REF_NAME" == "dev" ]]; then + TAG="dev" + else + echo "Skipping Docker build for branch $CI_COMMIT_REF_NAME" + exit 0 + fi + echo "Using tag: $TAG" + docker build -t $DOCKER_IMAGE:$TAG -f Dockerfile . + docker push $DOCKER_IMAGE:$TAG + only: + - dev + - production + +deploy: + stage: deploy + image: node:20 + before_script: *install_deploy_key + script: + - | + if [[ "$CI_COMMIT_REF_NAME" == "production" ]]; then + TAG="latest" + PORT="4100" + elif [[ "$CI_COMMIT_REF_NAME" == "dev" ]]; then + TAG="dev" + PORT="5100" + else + echo "Skipping deployment for branch $CI_COMMIT_REF_NAME" + exit 0 + fi + + CONTAINER_NAME="$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME" + echo "Deploying $DOCKER_IMAGE:$TAG to $CONTAINER_NAME on port $PORT..." + + ssh gitlab@192.168.41.101 -p 22 " + echo \"$CI_REGISTRY_PASSWORD\" | docker login $CI_REGISTRY -u \"$CI_REGISTRY_USER\" --password-stdin && + docker pull $DOCKER_IMAGE:$TAG && + docker stop $CONTAINER_NAME || true && + docker rm $CONTAINER_NAME || true && + docker run -d --name $CONTAINER_NAME -p $PORT:3000 $DOCKER_IMAGE:$TAG + " + only: + - dev + - production diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9c017d9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +# Use lightweight Node.js 20 base image +FROM node:20-alpine as builder + +# Set working directory +WORKDIR /app + +# Copy package files separately for better Docker caching +COPY package.json package-lock.json ./ + +# Install dependencies +RUN npm install + +# Copy entire project +COPY . . + +# Build the Next.js app +RUN npm run build + +# Use a minimal base image for running the app +FROM node:20-alpine + +WORKDIR /app + +# Copy built files from the builder stage +COPY --from=builder /app ./ + +# Expose port +EXPOSE 3000 + +# Start Next.js in production mode +CMD ["npm", "run", "start"]