├── src ├── main │ ├── resources │ │ ├── application.properties │ │ ├── static │ │ │ ├── js │ │ │ │ └── main.js │ │ │ └── css │ │ │ │ └── main.css │ │ └── templates │ │ │ └── index.html │ └── java │ │ └── com │ │ └── example │ │ └── springboot │ │ └── Application.java └── test │ └── java │ └── com │ └── example │ └── springboot │ └── ApplicationTests.java ├── images └── cicd5.png ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── Dockerfile ├── .gitignore ├── pom.xml ├── Jenkinsfile ├── README.md ├── mvnw.cmd └── mvnw /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/cicd5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sushank3/CI_CD-portfolio/HEAD/images/cicd5.png -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sushank3/CI_CD-portfolio/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:22 2 | 3 | ARG artifact=target/spring-boot-0.0.1-SNAPSHOT.jar 4 | 5 | WORKDIR /opt/app 6 | 7 | COPY ${artifact} app.jar 8 | 9 | # This should not be changed 10 | ENTRYPOINT ["java","-jar","app.jar"] -------------------------------------------------------------------------------- /src/test/java/com/example/springboot/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.springboot; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | k8s_manifests 3 | 4 | HELP.md 5 | target/ 6 | !.mvn/wrapper/maven-wrapper.jar 7 | !**/src/main/**/target/ 8 | !**/src/test/**/target/ 9 | 10 | ### STS ### 11 | .apt_generated 12 | .classpath 13 | .factorypath 14 | .project 15 | .settings 16 | .springBeans 17 | .sts4-cache 18 | 19 | ### IntelliJ IDEA ### 20 | .idea 21 | *.iws 22 | *.iml 23 | *.ipr 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | build/ 32 | !**/src/main/**/build/ 33 | !**/src/test/**/build/ 34 | 35 | ### VS Code ### 36 | .vscode/ 37 | -------------------------------------------------------------------------------- /src/main/java/com/example/springboot/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.springboot; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | //import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | // import org.springframework.web.bind.annotation.RestController; 10 | 11 | @SpringBootApplication 12 | @Controller 13 | public class Application { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(Application.class, args); 17 | } 18 | 19 | @RequestMapping("/") 20 | public String index(final Model model) { 21 | model.addAttribute("title", "I have successfuly built a sprint boot application using Maven"); 22 | model.addAttribute("msg", "This application is deployed on to Kubernetes using Argo CD"); 23 | return "index"; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar 19 | -------------------------------------------------------------------------------- /src/main/resources/static/js/main.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $(window).scroll(function () { 3 | // checks if window is scrolled more than 500px, adds/removes solid class 4 | if ($(this).scrollTop() > 550) { 5 | $('.navbar').addClass('solid'); 6 | $('.back-to-top').addClass('visible'); 7 | } else { 8 | $('.navbar').removeClass('solid'); 9 | $('.back-to-top').removeClass('visible'); 10 | } 11 | 12 | }); 13 | }); 14 | 15 | 16 | $(document).ready(function () { 17 | // Add smooth scrolling to all links 18 | $("a").on('click', function (event) { 19 | 20 | // Make sure this.hash has a value before overriding default behavior 21 | if (this.hash !== "") { 22 | // Prevent default anchor click behavior 23 | event.preventDefault(); 24 | 25 | // Store hash 26 | var hash = this.hash; 27 | 28 | // Using jQuery's animate() method to add smooth page scroll 29 | // The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area 30 | $('html, body').animate({ 31 | scrollTop: $(hash).offset().top 32 | }, 800, function () { 33 | 34 | // Add hash (#) to URL when done scrolling (default click behavior) 35 | window.location.hash = hash; 36 | }); 37 | } // End if 38 | }); 39 | }); -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.13 9 | 10 | 11 | com.example 12 | spring-boot 13 | 0.0.1-SNAPSHOT 14 | spring-boot 15 | Demo project for Spring Boot 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-thymeleaf 28 | 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline{ 2 | 3 | agent any 4 | 5 | stages{ 6 | 7 | stage('Build and Test') { 8 | steps { 9 | sh 'ls -ltr' 10 | sh 'mvn clean package' 11 | 12 | 13 | } 14 | 15 | post { 16 | success { 17 | script { 18 | slackSend( 19 | color: '#36a64f', 20 | message: "Build ${env.BUILD_NUMBER} succeeded!", 21 | CredentialId: 'slack-jenkins' 22 | ) 23 | } 24 | } 25 | } 26 | 27 | } 28 | 29 | stage("Static Code Analysis"){ 30 | 31 | environment { 32 | SONAR_URL = "https://0b73-2405-201-a405-1893-d587-7c74-d639-3cdb.ngrok-free.app" 33 | } 34 | 35 | steps{ 36 | echo "========Start Testing========" 37 | 38 | withCredentials([string(credentialsId: 'sonarqube', variable: 'SONAR_AUTH_TOKEN')]) { 39 | sh 'mvn sonar:sonar -Dsonar.login=$SONAR_AUTH_TOKEN -Dsonar.host.url=${SONAR_URL}' 40 | 41 | } 42 | 43 | } 44 | 45 | post { 46 | success { 47 | script { 48 | slackSend( 49 | color: '#36a64f', 50 | message: "Test of ${env.BUILD_NUMBER} succeeded! using sonarqube", 51 | tokenCredentialId: 'slack-jenkins' 52 | ) 53 | } 54 | } 55 | 56 | failure { 57 | script { 58 | slackSend( 59 | color: '#ff0000', 60 | message: "Test failed", 61 | tokenCredentialId: 'slack-jenkins' 62 | ) 63 | 64 | } 65 | } 66 | } 67 | } 68 | 69 | stage("Build docker file and push"){ 70 | 71 | environment { 72 | DOCKER_IMAGE = "sushank3/ci_cd-portfolio:v${BUILD_NUMBER}" 73 | REGISTRY_CREDENTIALS = credentials('docker_hub') 74 | 75 | } 76 | 77 | steps{ 78 | 79 | script { 80 | sh "docker build -t ${DOCKER_IMAGE} ." 81 | def dockerImage = docker.image("${DOCKER_IMAGE}") 82 | docker.withRegistry("https://index.docker.io/v1/", "docker_hub") { 83 | dockerImage.push() 84 | } 85 | 86 | slackSend( 87 | color: '#36a64f', 88 | message: "Docker build ${env.BUILD_NUMBER} succeeded!", 89 | tokenCredentialId: 'slack-jenkins' 90 | ) 91 | } 92 | } 93 | } 94 | 95 | stage('Update Deployment File') { 96 | 97 | environment { 98 | GITLAB_PROJECT_NAME = "CI_CD-portfolio" 99 | GITLAB_USERNAME = "sushank3" 100 | } 101 | 102 | steps { 103 | sh 'echo passed' 104 | git branch: 'main', url: 'https://gitlab.com/sushank3/ci_cd-portfolio.git' 105 | withCredentials([string(credentialsId: 'gitlab-token', variable: 'GITLAB_TOKEN')]) { 106 | sh ''' 107 | git config user.email "sushankkr3@gmail.com" 108 | git config user.name "sushank3" 109 | 110 | BUILD_NUMBER="${BUILD_NUMBER}" 111 | 112 | CURRENT_IMAGE_VERSION=$(grep -oE 'sushank3/ci_cd-portfolio:v[0-9]+' deployment.yaml | cut -d':' -f2) 113 | sed -i "s/${CURRENT_IMAGE_VERSION}/v${BUILD_NUMBER}/g" deployment.yaml 114 | git add deployment.yaml 115 | 116 | git commit -m "Update deployment image to version ${BUILD_NUMBER}" 117 | 118 | git push "https://oauth2:${GITLAB_TOKEN}@gitlab.com/${GITLAB_USERNAME}/${GITLAB_PROJECT_NAME}" HEAD:main 119 | 120 | 121 | ''' 122 | 123 | } 124 | 125 | script { 126 | slackSend( 127 | color: '#36a64f', 128 | message: "Final Build ${env.BUILD_NUMBER} succeeded! and deployment file updated with new version", 129 | tokenCredentialId: 'slack-jenkins' 130 | ) 131 | } 132 | } 133 | } 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Complete CI/CD with Jenkins and ArgoCD 2 | 3 | ![](./images/cicd5.png) 4 | 5 | ## Introduction 6 | Welcome to my project that exemplifies the implementation of **Continuous Integration** and **Continuous Deployment** (CI/CD) practices. In this project, I have leveraged the power of **Jenkins** and **ArgoCD** to automate and streamline the entire software delivery/deployment pipeline. 7 | 8 | With CI/CD, it eliminates the manual steps and enabled the automatic build, test, and deployment of our applications. This ensures faster release cycles, higher quality code, and improved collaboration among team members. 9 | 10 | To ensure code quality, I have integrated SonarQube in pipeline. It performs static code analysis and provides valuable insights into potential issues, bugs, and vulnerabilities. By addressing these concerns early in the development process, we can deliver more robust and secure applications. 11 | 12 | Furthermore, this project embraces containerization using **Kubernetes** for deployment. Kubernetes allows us to efficiently manage and scale our application containers, ensuring high availability and seamless updates. 13 | 14 | By combining the power of Jenkins, ArgoCD, SonarQube, and Kubernetes, I have created an end-to-end CI/CD solution that significantly enhances the development process, accelerates delivery, and improves the overall quality of our software. 15 | 16 | ## Features 17 | 18 | * A configured CI/CD pipeline for automated **building**, **testing**, and **deployment** 19 | * Jenkins is used for automating the build and deployment process. 20 | * **Static Code Analysis** using [SonarQube](https://www.sonarsource.com/products/sonarqube/) 21 | * **GitOps enabled** - Utilizes **Argo CD** for **Kubernetes-based** deployment 22 | * **Dockerized application** for easy deployment and scalability 23 | 24 | ## Prerequisites 25 | 26 | Before getting started with this project, ensure you have the following dependencies installed: 27 | 28 | - [Docker](https://www.docker.com/) 29 | - [Kubernetes Cluster](https://kubernetes.io/docs/setup/) (either local or on Cloud) 30 | - SonarQube server up and running 31 | - Refer the [documentation](https://docs.sonarqube.org/latest/) to configure SonarQube 32 | - [Ngrok](https://ngrok.com/) (Running SonarQube in Docker on local machine) 33 | - [Argo CD](https://argo-cd.readthedocs.io/en/stable/) installed 34 | 35 | ## Getting Started 36 | 37 | ### Setup the Project 38 | 39 | To get started with this project, follow these steps: 40 | 41 | **Clone the repository:** 42 | 43 | - Application source code and CI part: 44 | ``` 45 | git clone https://github.com/sushank3/CI_CD-portfolio.git 46 | ``` 47 | 48 | - Kubernetes manifests file. 49 | 50 | ``` 51 | git clone https://gitlab.com/sushank3/ci_cd-portfolio.git 52 | ``` 53 | 54 | 55 | 1. **Move to project home directory:** 56 | ``` 57 | mvn clean package 58 | or 59 | mvn clean install 60 | ``` 61 | Java version >= 17 62 | 63 | 2. **Run the application:** 64 | 65 | - **Option 1: Run locally** 66 | ``` 67 | ./mvnw spring-boot:run 68 | ``` 69 | - **Option 2: Run with Docker** 70 | 71 | 1. Build the image locally: 72 | 73 | ``` 74 | docker build . -t 75 | ``` 76 | 2. Run the docker container: 77 | 78 | ``` 79 | docker run -d -p 8085:8080 80 | ``` 81 | 82 | - You can now access the app at: http://localhost:8085 83 | 84 | ![](./images/curl.png) 85 | 86 | ## Overview of CI/CD Workflow 87 | 88 | ### Jenkins CI - Continuous Integration 89 | 90 | Refer the [**`Jenkinsfile`**](https://github.com/sushank3/CI_CD-portfolio/blob/main/Jenkinsfile) for the full configuration. 91 | 92 | #### Prerequisites 93 | 94 | - Setup the following environment variables: 95 | - `gitlab-token` - Gitlab access token 96 | - `docker_hub` - DockerHub access token 97 | - `sonarqube` - SonarQube token 98 | - `slack-jenkins` - Slack token 99 | 100 | The CI pipeline consists of 5 stages: 101 | stage('Build and Test') 102 | stage("Static Code Analysis") 103 | stage("Build docker file and push") 104 | stage('Update Deployment File') 105 | 106 | 1. **Build** - Builds the springboot application. 107 | 2. **test** - Static code analysis using [SonarQube](https://) 108 | 3. **Build docker file and push** - Builds a new docker image and push to DockerHub 109 | 4. **Update_k8s_manifests** - Updates the latest image tag in Kubernetes manifests 110 | 111 | > **📍NOTE:** 112 | > 113 | > The CI pipeline is configured to be triggered "on push" to the project. There are two conditions defined: 114 | 115 | 116 | ##### Steps to run SonarQube Locally (Linux) 117 | 118 | ``` 119 | apt install unzip 120 | 121 | adduser sonarqube 122 | 123 | wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.4.0.54424.zip 124 | 125 | unzip * 126 | 127 | chmod -R 755 /home/sonarqube/sonarqube-9.4.0.54424 128 | 129 | chown -R sonarqube:sonarqube /home/sonarqube/sonarqube-9.4.0.54424 130 | 131 | cd sonarqube-9.4.0.54424/bin/linux-x86-64/ 132 | 133 | ./sonar.sh start 134 | ``` 135 | 136 | You can access the SonarQube Server on **`http://:9000`** 137 | 138 | #### If you are using SonarQube in Docker: 139 | > You need to expose the Sonar Server using a tool like [Ngrok](https://ngrok.com/), for GitLab to communicate with it. 140 | ##### Steps to run SonarQube on Docker: 141 | 142 | ``` 143 | docker run -d --name sonarqube -p 9000:9000 sonarqube 144 | ``` 145 | ##### Setup ngrok for port mapping of sonarqube docker container: 146 | ``` 147 | ngrok http 9000 148 | ``` 149 | 150 | Refer the [documentation](https://docs.sonarqube.org/9.6/try-out-sonarqube/) for more information. 151 | 152 | Refer the [guide](https://ngrok.com/docs/using-ngrok-with/docker/) to know more about using **Ngrok** and **Docker** together. 153 | 154 | 155 | ### Argo CD - Continuous Deployment 156 | 157 | Refer the [**`argCD.yaml`**](https://gitlab.com/sushank3/ci_cd-portfolio/-/blob/main/argoCD.yaml) for full application configuration for Argo CD. 158 | 159 | A few important points for configuring Argo CD: 160 | 161 | 1. Argo CD will automatically sync the application and deploy it based on the configuration defined: 162 | 163 | ``` 164 | syncPolicy: 165 | automated: {} 166 | 167 | ``` 168 | 2. Monitor the deployment status and access the application once it's successfully deployed. 169 | 170 | ![](./images/argo.png) 171 | 172 | 📍 To learn more about Argo CD and configure it in your cluster, refer the [documentation](https://argo-cd.readthedocs.io/en/stable/getting_started/). 173 | 174 | ## Contribute 175 | 176 | Contributions are welcome! If you encounter any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request. 177 | 178 | 179 | ## Acknowledgements 180 | 181 | Thanks to [Abhishek Veeramalla](https://youtu.be/jNPGo6A4VHc)! for CI/CD workflow project idea. 182 | 183 | Source link: 184 | 185 | IMPLEMENTING THE ULTIMATE CI/CD PIPELINE | LIVE DEMO| JENKINS END TO END PROJECT| BEST CICD PROJECT: 186 | https://youtu.be/JGQI5pkK82w -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Portfolio Code 10 | 11 | 12 | 13 |
14 | 26 |
27 |
28 |

Hi, I'm Sushank Kumar

29 |

DevOps Enthusiast

30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |

About Me

42 |
43 | image 44 |

45 | I am a passionate DevOps enthusiast who is actively exploring and learning various DevOps tools. 46 |

47 |
48 |

49 | Check out my work 50 |

51 |
52 |
53 |
54 |
55 |
56 |

My Skills

57 |
58 |
59 |
60 |
61 | Git & Github 62 |
63 |
64 |
65 |
66 | Linux 67 |
68 |
69 |
70 |
71 | Docker 72 |
73 |
74 |
75 |
76 | Kubernetes 77 |
78 |
79 |
80 |
81 | Jenkins 82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |

92 | Check out my work 93 |

94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |

Portfolio

104 |
105 |
106 |
107 | 108 |
109 | 110 | 111 | 112 |

Restaurant Website UI

113 |

Build Using HTML,CSS,JS

114 | 117 | 120 |
121 |
122 |
123 | 124 |
125 | 126 | 127 |

Profile Card

128 |

Build Using HTML,CSS

129 | 132 | 135 |
136 |
137 |
138 |

139 | More 140 |

141 | CodePen 142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |

Contact Me

150 |

151 | Get in touch with me SushankKumar@gmail.com 152 |

153 | 154 | 155 | Linkedin 156 | Github 157 | 158 | Twitter 159 | 160 |
161 |
162 |
163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /src/main/resources/static/css/main.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | font-family: "Poppins", sans-serif; 11 | } 12 | 13 | header { 14 | background-color: hsla(202, 94%, 35%, 0.945); 15 | height: 100vh; 16 | } 17 | 18 | .container { 19 | max-width: 1200px; 20 | width: 90%; 21 | margin: auto; 22 | } 23 | 24 | /* ////........Navbar.......//// */ 25 | 26 | .navbar { 27 | position: fixed; 28 | width: 100%; 29 | z-index: 500; 30 | } 31 | 32 | .navbar-container { 33 | display: flex; 34 | justify-content: space-between; 35 | align-items: center; 36 | height: 64px; 37 | } 38 | 39 | .menu-items { 40 | display: flex; 41 | } 42 | 43 | .menu-items li { 44 | list-style: none; 45 | padding: 1rem; 46 | } 47 | 48 | .menu-items a { 49 | text-decoration: none; 50 | color: #f0f0e6; 51 | font-size: 1.2rem; 52 | padding: 0.3rem; 53 | } 54 | 55 | .menu-items a:hover { 56 | border-bottom: 2px solid #f0f0e6; 57 | } 58 | 59 | .navbar .logo { 60 | order: 1; 61 | color: #f0f0e6; 62 | font-size: 2rem; 63 | } 64 | 65 | /* ////........Home Content........//// */ 66 | 67 | .home-content .name { 68 | position: absolute; 69 | top: 47%; 70 | left: 50%; 71 | transform: translate(-50%, -50%); 72 | color: #07374a; 73 | width: 100%; 74 | text-align: center; 75 | } 76 | 77 | .home-content .name h1 { 78 | font-size: 2.2rem; 79 | text-align: center; 80 | } 81 | 82 | .home-content .name p { 83 | color: #f0f0e6; 84 | font-size: 1.5rem; 85 | } 86 | 87 | .angle-down-icon { 88 | position: absolute; 89 | bottom: 10%; 90 | left: 50%; 91 | transform: translate(-50%, -50%); 92 | font-size: 2rem; 93 | border: 3px solid #07374a; 94 | border-radius: 50%; 95 | } 96 | 97 | .angle-down-icon a { 98 | text-decoration: none; 99 | color: #07374a; 100 | padding: 1rem; 101 | } 102 | 103 | /* ////........About Me........//// */ 104 | 105 | .about-me { 106 | background-color: #07374a; 107 | padding: 6rem 0; 108 | } 109 | 110 | .about-me .about-heading { 111 | color: #25b79f; 112 | font-size: 2rem; 113 | font-weight: 600; 114 | text-align: center; 115 | } 116 | 117 | .about-content img { 118 | height: 200px; 119 | width: 150px; 120 | object-fit: cover; 121 | border-radius: 50%; 122 | } 123 | 124 | .about-content p { 125 | font-size: 1.2rem; 126 | color: #f0f0e6; 127 | padding: 0 2.3rem; 128 | text-align: center; 129 | } 130 | 131 | .skills .skills-heading { 132 | font-size: 2rem; 133 | font-weight: 600; 134 | color: #25b79f; 135 | text-align: center; 136 | } 137 | 138 | .about-me .about-content { 139 | display: flex; 140 | flex-wrap: wrap; 141 | } 142 | 143 | .about-content .left-content { 144 | flex-basis: 45%; 145 | text-align: center; 146 | } 147 | 148 | .about-content .right-content { 149 | flex-basis: 45%; 150 | } 151 | 152 | /* ///.....Skill Bar....../// */ 153 | 154 | .skills-bar { 155 | padding: 25px 30px; 156 | } 157 | 158 | .skills-bar .bar { 159 | margin: 25px 0; 160 | } 161 | 162 | .skills-bar .bar .info span { 163 | font-size: 1rem; 164 | font-weight: 500; 165 | } 166 | 167 | .skills-bar .bar .info { 168 | margin-bottom: 8px; 169 | color: #f0f0e6; 170 | } 171 | 172 | .skills-bar .bar .progress-line { 173 | position: relative; 174 | height: 10px; 175 | width: 550px; 176 | background: #f0f0f0; 177 | border-radius: 10px; 178 | transform: scaleX(0); 179 | transform-origin: left; 180 | animation: animate 1s cubic-bezier(1, 0, 0.5, 1) forwards; 181 | } 182 | 183 | .bar .progress-line span { 184 | position: absolute; 185 | background: #25b79f; 186 | height: 100%; 187 | border-radius: 10px; 188 | transform: scaleX(0); 189 | transform-origin: left; 190 | animation: animate 1s 1s cubic-bezier(1, 0, 0.5, 1) forwards; 191 | } 192 | 193 | @keyframes animate { 194 | 100% { 195 | transform: scaleX(1); 196 | } 197 | } 198 | 199 | .progress-line .html { 200 | width: 80%; 201 | } 202 | .progress-line .css { 203 | width: 70%; 204 | } 205 | .progress-line .bootstrap { 206 | width: 50%; 207 | } 208 | .progress-line .javascript { 209 | width: 50%; 210 | } 211 | .progress-line .c { 212 | width: 50%; 213 | } 214 | 215 | .bar .progress-line span::before { 216 | position: absolute; 217 | content: ""; 218 | height: 0; 219 | right: 0; 220 | top: -12px; 221 | width: 0; 222 | border: 7px solid transparent; 223 | border-bottom-width: 0px; 224 | border-right-width: 0px; 225 | border-top-style: #f0f0f0; 226 | border-top-color: #f0f0f0; 227 | } 228 | 229 | .bar .progress-line span::after { 230 | position: absolute; 231 | right: 0; 232 | top: -28px; 233 | color: #07374a; 234 | font-size: 12px; 235 | font-weight: 700; 236 | background: #f0f0f0; 237 | padding: 1px 8px; 238 | border-radius: 3px; 239 | } 240 | 241 | .progress-line .html::after { 242 | content: "80%"; 243 | } 244 | .progress-line .css::after { 245 | content: "70%"; 246 | } 247 | .progress-line .bootstrap::after { 248 | content: "50%"; 249 | } 250 | .progress-line .javascript::after { 251 | content: "50%"; 252 | } 253 | .progress-line .c::after { 254 | content: "50%"; 255 | } 256 | 257 | .navbar.solid { 258 | background-color: #07374a; 259 | transition: background-color 1s ease 0s; 260 | box-shadow: 0 0 4px rgb(7 55 74 / 20%); 261 | z-index: 500; 262 | } 263 | 264 | .navbar.solid .navbar-brand { 265 | display: inline-block; 266 | color: #f0f0e6; 267 | transition: color 1s ease 0s; 268 | } 269 | 270 | .navbar-brand { 271 | display: none; 272 | color: #f0f0e6; 273 | font-weight: 400; 274 | } 275 | 276 | .work-arrow { 277 | margin: 2rem 0; 278 | } 279 | 280 | .work-arrow a { 281 | font-size: 1rem; 282 | text-decoration: none; 283 | color: #25b79f; 284 | } 285 | 286 | .work-arrow-2 { 287 | margin: 2rem 0; 288 | } 289 | 290 | .work-arrow-2 a { 291 | font-size: 1rem; 292 | text-decoration: none; 293 | color: #25b79f; 294 | display: none; 295 | } 296 | 297 | /* ////.....Portfolio......///// */ 298 | 299 | .portfolio { 300 | background: #25b79f; 301 | padding: 6rem 0; 302 | } 303 | 304 | .proj-heading h1 { 305 | text-align: center; 306 | color: #07374a; 307 | font-size: 2.3rem; 308 | font-weight: 700; 309 | margin: 3rem 0; 310 | } 311 | 312 | .proj-1 { 313 | display: flex; 314 | justify-content: center; 315 | align-items: center; 316 | } 317 | 318 | .proj-1 img { 319 | height: 330px; 320 | width: 380px; 321 | object-fit: cover; 322 | border-radius: 50%; 323 | box-shadow: 0 20px 10px -10px rgb(37 41 52 / 31%); 324 | margin-right: 1.7rem; 325 | } 326 | 327 | .proj-1 .proj1-details { 328 | width: 32rem; 329 | } 330 | 331 | .proj-1 .proj1-details i { 332 | font-size: 1.5rem; 333 | color: #07374a; 334 | } 335 | 336 | .proj-1 .proj1-details h2 { 337 | font-size: 2rem; 338 | color: #07374a; 339 | } 340 | 341 | .proj-1 .proj1-details p { 342 | font-size: 1.3rem; 343 | color: #07374a; 344 | font-weight: 600; 345 | } 346 | 347 | .proj-1 .proj1-details button { 348 | background: #f0f0e6; 349 | padding: 0.5rem; 350 | margin-top: 0.5rem; 351 | width: 150px; 352 | border: none; 353 | border-bottom: 2px solid #07374a; 354 | } 355 | 356 | .proj-1 .proj1-details button a { 357 | text-decoration: none; 358 | color: #07374a; 359 | font-size: 1.1rem; 360 | transition: 0.2s ease-in-out; 361 | text-align: center; 362 | transition: 0.3s ease-in-out; 363 | } 364 | 365 | .proj-1 .proj1-details button .fas { 366 | font-size: 0.7rem; 367 | padding: 0.3rem; 368 | transition: 0.2s ease-in-out; 369 | } 370 | 371 | .proj-1 .proj1-details button:hover { 372 | background: #07374a; 373 | } 374 | 375 | .proj-1 .proj1-details button:hover a, 376 | .proj-1 .proj1-details button:hover .fas { 377 | color: #f0f0e6; 378 | } 379 | 380 | /* ////.....proj2.....//// */ 381 | 382 | .proj-2 { 383 | display: flex; 384 | justify-content: center; 385 | align-items: center; 386 | margin-top: 3rem; 387 | } 388 | 389 | .proj-2 img { 390 | height: 330px; 391 | width: 380px; 392 | object-fit: cover; 393 | border-radius: 50%; 394 | box-shadow: 0 20px 10px -10px rgb(37 41 52 / 31%); 395 | margin-right: 1.7rem; 396 | } 397 | 398 | .proj-2 .proj2-details { 399 | width: 32rem; 400 | } 401 | 402 | .proj-2 .proj2-details i { 403 | font-size: 1.5rem; 404 | color: #07374a; 405 | } 406 | 407 | .proj-2 .proj2-details h2 { 408 | font-size: 2rem; 409 | color: #07374a; 410 | } 411 | 412 | .proj-2 .proj2-details p { 413 | font-size: 1.3rem; 414 | color: #07374a; 415 | font-weight: 600; 416 | } 417 | 418 | .proj-2 .proj2-details button { 419 | background: #f0f0e6; 420 | padding: 0.5rem; 421 | margin-top: 0.5rem; 422 | width: 150px; 423 | border: none; 424 | border-bottom: 2px solid #07374a; 425 | } 426 | 427 | .proj-2 .proj2-details button a { 428 | text-decoration: none; 429 | color: #07374a; 430 | font-size: 1.1rem; 431 | transition: 0.2s ease-in-out; 432 | text-align: center; 433 | transition: 0.3s ease-in-out; 434 | } 435 | 436 | .proj-2 .proj2-details button .fas { 437 | font-size: 0.7rem; 438 | padding: 0.3rem; 439 | transition: 0.2s ease-in-out; 440 | } 441 | 442 | .proj-2 .proj2-details button:hover { 443 | background: #07374a; 444 | } 445 | 446 | .proj-2 .proj2-details button:hover a, 447 | .proj-2 .proj2-details button:hover .fas { 448 | color: #f0f0e6; 449 | } 450 | 451 | .more-work { 452 | text-align: center; 453 | margin: 3rem 0 1rem 0; 454 | } 455 | 456 | .more-work p { 457 | font-size: 1.6rem; 458 | color: #07374a; 459 | font-weight: 500; 460 | } 461 | 462 | .more-work a { 463 | text-decoration: none; 464 | color: #f0f0e6; 465 | font-size: 1.3rem; 466 | } 467 | 468 | .more-work a:hover { 469 | border-bottom: 2px solid #f0f0e6; 470 | } 471 | 472 | /* ////......Contact......///// */ 473 | 474 | .contact { 475 | background: #07374a; 476 | position: relative; 477 | height: 92vh; 478 | } 479 | 480 | .contact-content { 481 | position: absolute; 482 | top: 50%; 483 | left: 50%; 484 | transform: translate(-50%, -50%); 485 | text-align: center; 486 | } 487 | 488 | .contact-content h2 { 489 | font-size: 2.5rem; 490 | font-weight: 400; 491 | color: #25b79f; 492 | padding-bottom: 0.5rem; 493 | } 494 | 495 | .contact-content .mail { 496 | color: #f0f0e6; 497 | padding-bottom: 0.2rem; 498 | font-size: 1rem; 499 | } 500 | 501 | .contact-content .links { 502 | color: #25b79f; 503 | padding: 0.5rem; 504 | padding-bottom: 1.8rem; 505 | font-size: 1rem; 506 | } 507 | 508 | .contact-content a { 509 | text-decoration: none; 510 | color: #25b79f; 511 | padding: 0.5rem; 512 | transition: 0.3s ease-in-out; 513 | } 514 | 515 | .contact-content a:hover { 516 | color: #f0f0e6; 517 | } 518 | 519 | /* ////......Media query......//// */ 520 | 521 | @media (max-width: 500px) { 522 | html { 523 | font-size: 60%; 524 | } 525 | 526 | .about-content .left-content { 527 | flex-basis: 100%; 528 | text-align: center; 529 | } 530 | 531 | .about-content .right-content { 532 | flex-basis: 100%; 533 | } 534 | 535 | .skills { 536 | width: 100%; 537 | } 538 | 539 | .skills-bar .bar .progress-line { 540 | width: 100%; 541 | } 542 | 543 | .work-arrow { 544 | display: none; 545 | } 546 | 547 | .right-content h1 { 548 | margin-top: 3.2rem; 549 | } 550 | 551 | .proj-1 { 552 | display: flex; 553 | justify-content: center; 554 | flex-direction: column; 555 | } 556 | 557 | .proj-1 img { 558 | height: 230px; 559 | width: 290px; 560 | margin-bottom: 0.5rem; 561 | } 562 | 563 | .proj-2 { 564 | display: flex; 565 | justify-content: center; 566 | flex-direction: column; 567 | } 568 | 569 | .proj-2 img { 570 | height: 250px; 571 | width: 290px; 572 | margin-bottom: 0.5rem; 573 | } 574 | 575 | .work-arrow-2 a { 576 | font-size: 1.3rem; 577 | text-decoration: none; 578 | color: #25b79f; 579 | display: block; 580 | text-align: center; 581 | } 582 | 583 | .contact-content { 584 | width: 100%; 585 | } 586 | } 587 | 588 | @media (min-width: 501px) and (max-width: 768px) { 589 | html { 590 | font-size: 65%; 591 | } 592 | 593 | .about-content .left-content { 594 | flex-basis: 100%; 595 | text-align: center; 596 | } 597 | 598 | .about-content .right-content { 599 | flex-basis: 100%; 600 | } 601 | 602 | .skills { 603 | width: 100%; 604 | } 605 | 606 | .skills-bar .bar .progress-line { 607 | width: 100%; 608 | } 609 | 610 | .work-arrow { 611 | display: none; 612 | } 613 | 614 | .right-content h1 { 615 | margin-top: 3.2rem; 616 | } 617 | 618 | .proj-1 { 619 | display: flex; 620 | justify-content: center; 621 | flex-direction: column; 622 | } 623 | 624 | .proj-1 img { 625 | height: 240px; 626 | width: 290px; 627 | margin-bottom: 0.5rem; 628 | } 629 | 630 | .proj-2 { 631 | display: flex; 632 | justify-content: center; 633 | flex-direction: column; 634 | } 635 | 636 | .proj-2 img { 637 | height: 240px; 638 | width: 290px; 639 | margin-bottom: 0.5rem; 640 | } 641 | 642 | .work-arrow-2 a { 643 | font-size: 1.3rem; 644 | text-decoration: none; 645 | color: #25b79f; 646 | display: block; 647 | text-align: center; 648 | } 649 | 650 | .contact-content { 651 | width: 100%; 652 | } 653 | } 654 | 655 | @media (min-width: 769px) and (max-width: 1200px) { 656 | html { 657 | font-size: 70%; 658 | } 659 | 660 | .about-content .left-content { 661 | flex-basis: 100%; 662 | text-align: center; 663 | } 664 | 665 | .about-content .right-content { 666 | flex-basis: 100%; 667 | } 668 | 669 | .skills { 670 | width: 100%; 671 | display: flex; 672 | flex-direction: column; 673 | justify-content: center; 674 | align-items: center; 675 | } 676 | 677 | .work-arrow { 678 | display: none; 679 | } 680 | 681 | .left-content h1 { 682 | margin-top: 3.2rem; 683 | text-align: center; 684 | } 685 | 686 | .right-content h1 { 687 | margin-top: 3.2rem; 688 | text-align: center; 689 | } 690 | 691 | .work-arrow-2 a { 692 | font-size: 1.3rem; 693 | text-decoration: none; 694 | color: #25b79f; 695 | display: block; 696 | text-align: center; 697 | } 698 | 699 | .contact-content { 700 | width: 100%; 701 | } 702 | } 703 | 704 | @media (orientation: landscape) and (max-height: 500px) { 705 | .header { 706 | height: 90vmax; 707 | } 708 | } --------------------------------------------------------------------------------