반응형

TextView

html 의 p태그와 비슷하며, 텍스트를 입력할 수 있다

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="소개팅 앱!!"
 />

 

match_parent : 부모요소의 길이

예제를 기준으로, textView 상위 부모의 width 를 따라간다

 

wrap_content : 해당요소의 길이

예제를 기준으로, text 요소의 height를 입력한다

LinearLayout

여러 요소를 줄세우는 div

세로, 가로 가능

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintBottom_toBottomOf="parent"
    tools:layout_editor_absoluteX="0dp">
    
    <Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/mainColor"
    android:layout_margin="10dp"
    android:textColor="@color/white"
    android:text="Login" />

</LinearLayout>

orientation = vertical : 세로정렬

 

 

728x90
반응형

components 폴더 생성

 

root 디렉토리에 components 폴더를 생성한다

하위에 layout 폴더를 생성하고 그 안쪽에 layout과 관련된 로직을 추가할것이다

 


프로젝트가 실행될 때 가장 먼저 실행되는것이 _app.tsx 이다.
만약 localhost:3000/home 으로 접속 시 _app.tsx 가  실행되면서 Comonent로 "home" Component가 들어오게된다
그렇기에 레이아웃을 씌우는 대상은 _app.tsx가된다

 

Header, Footer 생성

 

기본적인 헤더, 푸터를 생성해보자

 

▼Header.tsx

import React from 'react'

const Header = () => {
    return (
        <>
            <h1>Header</h1>
        </>
    )
}

export default Header

 

▼Footer.tsx

import React from 'react'

const Footer = () => {
    return (
        <>
            <div>
                <h1>Footer</h1>
            </div>
        </>
    )
}

export default Footer

 

Layout 생성

 

위에서 만들어진 Header, Footer 를 layout화 시켜보자

 

▼ Layout.tsx

import Header from "@/components/layout/Header";
import Footer from "@/components/layout/Footer";
import {Noto_Sans_KR} from "next/font/google";

type LayoutProps = {
  children: React.ReactNode
  className?: string
}

const notoSansKr = Noto_Sans_KR({
    subsets: ['latin'],
    weight: ['100', '400', '700', '900'],
    variable: '--font-notoSansKr',
})

export default function Layout({ children, className }: LayoutProps) {
  return (
    <div className={`${notoSansKr.className}`}>
      <Header />
      <div>
          {children}
      </div>
      <Footer />
    </div>
  )
}

 

layout function 에는 인자값으로 children, className 이 들어올건데, 이것의 타입은 위에 선언된 LayoutProps 이다.

그리고 Header, body, Footer 모두 폰트를 적용시키기 위하여 상위에 Classname을 설정해줬다

 

참고로 return 시 상위 태그를 선언하지않으면 오류가 난다

아래와 같이 빈 태그라도 넣어줘야한다

 

만든 Layout을 _app에 씌운다

import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import {NextPage} from "next";
import {ReactElement, ReactNode} from "react";
import Head from "next/head";

export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
  getLayout?: (_page: ReactElement) => ReactNode
}

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}
export default function App({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page) => page)

  return(
      <>
        {getLayout(<Component {...pageProps} />)}
      </>
  )
}

 

index 정리

 

필요없는 코드를 정리해준다

import { Inter } from 'next/font/google'
import {NextPageWithLayout} from "@/pages/_app";
import Layout from "@/components/layout/Layout";

const inter = Inter({ subsets: ['latin'] })

const Home : NextPageWithLayout = () => {
  return (
    <>
      <h1>본문 영역입니다</h1>
    </>
  )
}

Home.getLayout = function getLayout(page) {
  return<Layout>{page}</Layout>
}

export default Home

 

 

이렇게 레이아웃이 나뉘어졌다!

728x90
반응형

 

에뮬을 실행했더니 아래와 같은 오류가 확인되었다

 

Waiting For debugger

Application [프로젝트명] (process com.example.폴더명) is waiting for the debugger to attach.

 

Error running 'app'

Processes com.example.sogating are not found. Aborting session.

 

코틀린 안드로이드 개발은 처음인데.. java 처럼 오류메세지가 와락 뜨는게 아니라서 디버깅하는 방법을 공부하는중..

 

일단 에뮬이 냅다 꺼진다면, 로직이 잘못된것이므로 코드를 하나씩 지워가면서 오류포인트를 찾았다.

뭐 설정이고 무슨 문제가 아니라, 로직문제가 없는지 확인할것..!

728x90
반응형

 

React 프로젝트를 시작해보자

그런데 이제 next.js 와 typescript 를 곁들인... !!

 

Node js 설치

프로젝트 생성 전에 무조건 node js 가 설치되어있어야 하므로 아래 커맨드로 node js 가 설치되어있는지 확인해보자

$ node -v

 

 

설치되어있지않다면, node js 홈페이지로 이동하여 Recommended For Most users 버전을 다운받자

https://nodejs.org/en

 

프로젝트 생성

내가 프로젝트 만들 위치로 이동하여 아래 커맨드를 실행시킨다

$ npx create-next-app react_next

 

아래와 같은 옵션을 선택해야하는데, 필요에 따라 선택하면 된다

 

 

√ Would you like to use TypeScript? ... No / Yes
 -> 나는 ts 쓸꺼라서 yes
√ Would you like to use ESLint? ... No / Yes
-> ESLint 쓸꺼라서 yes
참고로 ESLint는 간단히 말해서 야 이거 틀렷어!! 하고 난리쳐주는 고마운 검수자이다
√ Would you like to use Tailwind CSS? ... No / Yes
-> tailwind css안쓸래
√ Would you like to use `src/` directory? ... No / Yes
->소스 디렉터리 시작점을 app으로 할건지 
√ Would you like to use App Router? (recommended) ... No / Yes
-> 라우터 안쓸거라서 No
√ Would you like to customize the default import alias (@/*)? ... No / Yes
-> 안쓸거라서 No
src 안쓸때 src 쓸때 src 안쓰고
app router 안쓸때

 

프로젝트 실행

다운로드가 종료되면 아래 커맨드로 프로젝트를 실행시킨다

$ npm run dev

 

참고로  start 는 운영이고, dev는 개발이라고 보면 된다

run start 로 프로젝트를 실행시키면 로컬에서 소스코드 변경해도 바로 브라우저에 반영이 안된다
.next 로 만들어진 폴더의 내용물을 보여주기 때문이다

하지만 run dev로 실행시키면 소스코드 변경 시 바로 브라우저에 반영되므로 개발할땐 dev로 실행시키자

 

 

하지만 프로젝트 실행 시 다양한 이유로 실행이 안될수도있다.

나의 경우엔 node js 버전이 너무 낮아서 버전업이 필요한 상황이었다

$ npm run dev

> react_next@0.1.0 dev
> next dev

You are using Node.js 18.16.0. For Next.js, Node.js version >= v18.17.0 is required.

 

보면, 내가 설치한 node js 는 18.16.0 버전이지만, 요구되는 버전은 18.17 이다

nodejs 홈페이지 가보니까 20이 나와있는 상황이라 겸사겸사 다시 다운받았다.

 

node js 버전업 하는 방법이야.. 여러 방법이 있지만 나는 다 귀찮으므로 ㅋㅋㅋ

node js 홈페이지에서 다운로드파일 받고 실행시키면 알아서 버전업 된다

 

혹시 next: command not found 뜨면 npm install 해주고 실행하면 된다

호옥시!!! 그래도 안된다면 npm run dev 커맨드 실행하는 위치가 프로젝트 루트위치에서 실행하는게 맞는지 꼭 확인할것

프로젝트 확인

npm run dev를 실행하면 아래와 같이 표시될것이다

 

localhost:3000 부분을 클릭하면 브라우저가 열리고 react-next project가 보인다

여기까지 보인다면 프로젝트 설치  성공!

 

728x90
반응형

 

Android Studio Card Stack View

Android Studio 개발 시 아래 저장소의 yuyakaido CardStackView 를 import 하는데, dependencies 추가해도 안됐다

https://github.com/yuyakaido/CardStackView.git

 

GitHub - yuyakaido/CardStackView: 📱Tinder like swipeable card view for Android

📱Tinder like swipeable card view for Android. Contribute to yuyakaido/CardStackView development by creating an account on GitHub.

github.com

 

해결방법

settings.gradle 에 아래 문구 추가

//기존
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

//수정
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        jcenter() //추가
        maven{url 'https://jitpack.io'} //추가
        mavenCentral()
    }
}

 

728x90
반응형

 

평화로운 2023년의 어느날

 

중소기업에 취직하여 평화롭게 3년차 개발자를 향해 달리고 있던 2023년의 어느날, 

설날 명절선물로 빤스를 받고나서 이직생각이 들었다


이커머스 SM 회사였고 다양한 시도와 코드리뷰 문화를 만들어서 재미있게 회사생활하고 있었지만 

회사 재고로 남아있던 빤스를 받은순간... 정이 싹털렸다

갑자기 회사를 객관적으로 보게되면서

이렇게 발전 가능성없고.. 주어진일만 계속해서 하는 3년차 개발자..괜찮을까? 하는 생각이 들었다 

 

 

이직 준비

새로운 일을 도전해보고싶어서 이직을 준비했고 코딩테스트, CS를 열심히 공부했다

오랜만에 각잡고 취직현장에 들어서려고 하니 쉽지않았고 시장이 겨울이니 뭐니 했는데 다행히 중견기업으로 이직에 성공


대기업으로 분류되는 중견기업으로, 복지도 좋고 연봉도 괜찮았지만

실제로 6개월 넘게 다녀보니 직무자체는 중소기업이 더 재밌었던것같다

현 직장에서 프로젝트 PL을 맡으면서 개발보다는 현업담당자와 외주개발자와의 의견조율을 하며

DB, 인프라세팅을 하며 WBS관리를 하면서 매니징 역량은 늘은거같은데...


실제 개발 역량은 늘것같지 않아서 퇴근 후 공부를 하거나 토이프로젝트를 진행했다

 

퇴근 후 공부

퇴근 후 운동 및 공부를 하는건 진짜 헬이었는데, 하다보니 어느순간 익숙해졌다

 

특히 토이프로젝트를 진짜... 성심성의껏 공부하고 진행했다

AWS 서버에 무료 인스턴스를 올리고 github private 프로젝트를 jenkins 로 자동배포 하였고 사용스택은 아래와 같다


Back-End
- JDK 17
- Srping boot
- Spring Security
- JPA
- MariaDB

Front-end
- React
- Next.js

infra
- AWS linux
- Nginx

 

회사에서 이미 다 설정이 되어있었지만, 내가 처음부터 해나가는 과정은 생각보다 오래걸리고 내가얼마나 주먹구구식으로 회사를 다녔는지 깨닫게 해줬다

 

토이프로젝트이다보니, 참여율도 좋지않아서 프론트 react, next js 를 프론트작업자와 함께 공부했는데 너무 재밌었다

백단 질릴때는 프론트했다가.. 프론트 재미없을때는 백단 했다가 ㅎㅎ

 

원래는 실제 운영을 위한 사이트개발이었는데 시간 / 개발 / 수익 세가지를 모두 만족시킬수 없어서 프로젝트 종료중이다..

실제로  상업성을 띄는 사이트를 개발해보니, 회사에서 개발하던것과는 사뭇 달랐다

개발에 투자하니 시간이 많이 걸렸고, 그렇게 개발을 했더니 수익을 만족시킬 수 없었다..

 

만약 진짜로 사업을 한다면 프레임워크고 나발이고 최대한 가벼운 프로젝트로 빠른 수익성을 내는 개발을 해야겠다는 교훈을 얻었다. 실제로 어떻게 될지는 모르겠지만..

 

2023년을 마무리하며..


토이프로젝트와 회사일을 병행하면서 느낀점이 정말 많았던 해였고, 주택자금대출도 20%정도 상환했다

내년의 목표는 회사를 잘 다니면서 개인역량을 늘리는 것이다

2024년 목표


1. 1일1커밋
2. 알고리즘/코테 스터디
3. 개발서적 스터디
4. 다이어트
5. 주택대출상환 40%

건강을 챙기고!

돈도 잘 모으고!

공부도 열심히!

여러가지로 역량을 늘리는 한 해를 만들고 하반기쯤엔 다양한 기업에 지원해보고싶다 :)

728x90
반응형

@Component

개발자가 직접 작성한 class 전체를 Spring Bean 으로 등록

하위로 @Controller, @Service, @Repository 어노테이션이 있다

@Component
public class MyComponent {
// 클래스 내용
}

 

@Configuration

스프링에게 해당 클래스가 Bean 구성 Class 임을 알리는 어노테이션이다

즉, Bean 등록용 class로 사용할 수 있고 일반 메소드 또한 만들수있지만 주로 Bean 을 보조하는 역할을 한다

 

@Bean

외부 라이브러리 등 반환되는 객체를 Bean 으로 등록한다

쉽게말하면 @Bean 어노테이션을 사용하면 new ~ 로  생성해서 import 하지않아도 된다

 

스프링 간 객체가 의존관계를 관리하도록 하는 것에 가장 큰 목적이다

new 로 생성하면 생성자를 그득그득 붙여서 변경가능성이 있는데, Bean 을 사용하면 변경이 안되겠지

@Configuration //여기는 @Bean 등록 전용 class!
public class TestConfig {

    @Bean
    public MyBean myBean() {
      return new MyBean();
    }
    
    @Bean(name="myMethod")
    public MyBean myBean() {
      return new MyBean();
    }
    
    // @Bean 어노테이션이 없는 메소드
    public SomeConfiguration someConfiguration() {
      // 구성 정보 반환
      return new SomeConfiguration();
    }
}
728x90
반응형

@RequestParam

Client 요청 URI 에서 전달되는 파라미터를 메소드 인자와 매칭
휴먼에러 방지를 위해 name 속성을 같이 쓰는게 좋음!

@GetMapping(value = "/main")
public String index(@RequestParam String nickname, 
                    @RequestParam(name="age") String age) {
        return "";
}

 

@RequestBody

Client 에서 서버로 요청 시 복수의 parameter 를 전달할 때 사용
json 기반의 Http Body 를 컨트롤러에서 자바객체로 변환 (Client 에서 보낸 json body를 객체형태로 매핑)

Client 에서 보내고싶은 데이터가 여러개 있을 경우 주로 사용된다.

아래와 같이 param 안에 데이터를 넣고

var param = {
      title : "1111",
      content : "hello",
      userName : "admin"
  }

 

 

해당 어노테이션을 넣으면 컨트롤러에서 해당 데이터를 객체로 자동 매핑한다

이때 유의할 점은 PostDto 에서 선언된 변수명과 param 에 들어있는 변수명이 완벽하게 같아야 한다

public class PostDto {
    private String title;
    private String content;
    private String userName;
}

/////
@PostMapping(value = "/index-request")
public String indexRequest(@RequestBody PostDto postDto) {
        return "/user/index";
}

 

만약 변수명이 같지 않은 경우 별도로 에러는 발생하지 않으며, 해당 변수만 해당 객체에 매핑되지 않는다

 

 

@ResponseBody

Client 로 data 반환 시 사용하며 객체 data 를 json 으로 바꿔 반환한다

해당 어노테이션의 위치는 return type 객체 앞에 써도 되지만, 나는 개인적으로 방법 2를 선호한다

// 방법 1
@GetMapping(value = "/index-rest")
public @ResponseBody ResponseEntity indexRest() {
    //json type으로 반환하기 위하여 @ResponseBody 어노테이션이 필요함
    return ApiResponseEntity
            .builder()
            .ok();
}

// 방법 2
@ResponseBody
@GetMapping(value = "/index-rest2")
public ResponseEntity indexRest2() {
    //@ResponseBody 어노테이션은 return type 앞에 위치한것보다 현재의 형태가 제일 깔끔해 보인다
    return ApiResponseEntity
            .builder()
            .ok();
}

 

위와 같은 코드로 컨트롤러에서 데이터를 보내면 Client 에서는 아래와 같은 형태로 받게된다

var response = {
        "data": {
            "loginId": "admin"
        },
        "status": 200
  }

 

자세한 코드는 아래 깃헙 주소에서 basic폴더의 README 참고

https://github.com/Daseul727/BackEnd-Skill-Up.git

 

728x90
반응형

@Controller

- 일반적인 Spring MVC 컨트롤러

- 주로 view 를 반환하기 위하여 사용됨

 

View 반환

Return Type 은 String 으로 설정한다

return 에 들어오는 경로의 화면을 View Resolver 를 통해 반환한다

@Controller
@RequestMapping("/main")
public class MainController {

    @GetMapping(value = "/index")
    public String index(){
        return "/user/index";
    }
}

 

요청 처리 과정

1. Client 에서 URI 형식으로 요청

2. DispatcherServlet 에서 요청을 처리할 대상 조회

3. HandlerAdapter 를 통해 요청을 Controller 로 위임

4. Controller 에서 서비스로직 실행 후 view 반환

5. DispatcherServletViewResolver 를 통해 View 를 찾아 반환

 

View + Data 반환

Return Type 은 String 으로 설정한다

model 에 들어있는 data를 view와 함께 반환한다

@Controller
@RequestMapping("/main")
public class MainController {

    @GetMapping(value = "/index-model")
    public String indexModel(Model model){
        model.addAttribute("user", "");
        return "/user/index";
    }

    @GetMapping(value = "/index-param")
    public String indexParam(Model model, @RequestParam("userName") String userName){
        model.addAttribute("user", userName);
        return "/user/index";
    }

}

 

요청 처리 과정

1. Client 에서 URI 형식으로 요청

2. DispatcherServlet 에서 요청을 처리할 대상 조회

3. HandlerAdapter 를 통해 요청을 Controller 로 위임

4. Controller 에서 서비스로직 실행 후 viewData 를 함께 반환

 

Data 반환

페이지 이동없이 데이터만 Json 객체로 반환한다

@Controller
@RequestMapping("/main")
public class MainController {

    @GetMapping(value = "/index-rest")
    public @ResponseBody ResponseEntity indexRest() {
        //json type으로 반환하기 위하여 @ResponseBody 어노테이션이 필요함
        return ApiResponseEntity
                .builder()
                .ok();
    }
}

 

하지만 이런 경우 @Controller 를 쓰기보단 아래의 @RestController 어노테이션을 사용한다

 

@RestController

- RestFul 웹서비스의 컨트롤러

- @Controller + @RequestBody 의 기능을 한다

- ResponseEntity 형식으로 return

   ㄴ HttpStatus, data 를 Json 객체로 반환

 

 

Data 반환

페이지이동 없이 Data 만 Json 객체로 반환한다

아래 코드의 경

@RestController
@RequestMapping("/api/main")
public class MainRestController {

    @ResponseBody
    @GetMapping("")
    public ResponseEntity index() {
        return ResponseEntity
                .ok();
    }
}

 

요청 처리 과정

1. Client 에서 URI 형식으로 요청

2. DispatcherServlet 이 요청을 처리

3. HandlerAdapter 를 통해 요청을 Controller로 위임

4. Controller 에서 서비스로직 실행 후 객체 반환

5. 반환 Json 으로 Serialize 되어 Client 반환

 

 

viewResolver 필요한 프로젝트는 @Controller

api기능만 사용할 프로젝트는 @RestController 사용하면 된다!

728x90
반응형

 

1. 서버 메모리 swap

AWS 프리티어 무과금러는 .. Jenkins 배포에 앞서 꼭!!! 해야하는 작업이 있다

 

바로 메모리 swap

 

프리티어로 받은 서버로는.. 배포하다가 인스턴스가 죽어버린다

그러면 ip도 다시 발급받게되고ㅠㅠ 설정을 다 바꿔야하는게 너무귀찮으므로 꼭 메모리 swap 을 해야한다고 강조한다

 

자세한 과정은 아래 블로그에 너무 잘 정리해두셔서 꼭!! 방문을 해서 메모리 swap 처리를 하기 바란다

https://kth990303.tistory.com/361

 

[AWS] Swap File을 이용해 EC2 메모리 부족 현상을 해결해보자

작업을 하던 중 aws ec2 메모리 부족현상이 발생했다. 우리가 사용하고 있는 t4g.micro 인스턴스 유형은 램이 1GB였고, 이는 메모리 부족현상을 충분히(?) 볼 수 있을 정도로 작은 양의 메모리였다. 이

kth990303.tistory.com

 

2. AWS 서버에 Jenkins 권한 부여

Jenkins가 실제로 배포하려면 서버에 대한 읽기/쓰기/수정/삭제 권한이 있어야 한다

 

AWS 서버에 접속하여 root 계정으로 전환한다

$ sudo su

 

sudoers.d 폴더로 이동해서 jenkins 파일을 생성한다

$ cd /etc/sudoers.d
$ touch jenkins

 

 

jenkins에게 sudo 명령 실행권한을 부여하고 실행할때 password 를 물어보지않는 설정을 추가하고 해당파일 보안설정을 해준다

$ jenkins ALL=(ALL) NOPASSWD: ALL
$ chmod 0440 jenkins

 

근데 나는 이 방법으로는 jenkins 배포할때 권한이 자꾸 튕겨져나가서, 아래 커맨드도 실행했다

$ echo "jenkins ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d jenkins
$ sudo chmod 0440 /etc/sudoers.d/jenkins

2. Jenkins - Github 계정 연결

이제 Jenkisn 웹페이지에 접속해보자

 

Jenkins 에서 github 를 사용하려면 우선 github계정을 jenkins에 등록시켜야 한다

이때 사용할 github계정은 엄밀히 말하면 내가 배포하려고 하는 repository에 접근 가능한 github 계정이기만 하면 된다

 

대시보드 > Jenkins 관리 > System 으로 이동해보자

Github 이라는 영역이 보일텐데 여기서 git hub 계정추가가 가능하다

 

gitHub server 콤보박스를 선택하면 아래와 같은 영역이 노출될것이다

고대~~~로 냅두고 Credentials 하단의 Add 를 눌러준다

 

Credentials 는 Jenkins 에 등록된 github 계정목록이 노출되는 부분이지만

지금은 등록된 github 계정이 없으므로 none으로 보이는것일뿐이다

 

각 항목의 의미는 아래와 같다

username : gihub 계정 username
password : github 계정 password
ID : 해당 정보를 대표할 name이며, 해당 계정을 구분하기위한 용도로만 사용되는 대표이름. title
Description : 안적어도 됨

username은 github의 username 이고 ID는 jenkins 에서 사용할 id이다 즉, Credentials 목록에 노출될 text이다

 

이렇게 입력하면 비로소 Credentials 에 내 계정이 보인다

 

3. Jenkins - SSH 설정

 

앞으로 Jenkins 에서 AWS 서버에 접속하여 배포를 진행하겠지만, 우리는 해당서버에 pem/ppk 파일로 접속하고있기때문에 Jenkins에도 해당정보를 전달해주어야한다

 

1) SSH 플러그인 설치

기본적으로 Jenkins 에는 SSH 플러그인이 없기때문에 따로 설치해줘야 한다

 

아래 경로로 이동한다

Jenkins 관리 > 플러그인관리 > 설치가능 > Publish Over SSH 설치

 

설치완료되고 재시작 여부를 물으면 재시작해준다

 

재시작이 완료되면 System 관리 > Publish Over SSH 영역이 생겨있는것을 볼 수 있다

 

key 영역을 입력해줘야하는데, 다운받아놓은 pem 파일을 크롬에 던지면 텍스트가 주루룩 나온다

그것을 입력해주자

 

하지만 이것은 pem 파일만 등록된거고, 그래서 어느 서버에 적용할건지 설정해줘야한다.

하단의 추가 버튼을 클릭하여 SSH Server 를 등록하자

 

 

name : 해당 서버를 지칭할 이름. 중요하지않다 title 개념
hostname : AWS IP주소
username : 유저명 (우리의 경우는 ubuntu라고 적는다)
remote directory : 젠킨스로 생성된 배포파일의 root 경로

 

 

여기서 어려운 부분은 remote directory 인데, 우선 AWS 서버 내 배포파일이 저장될 위치를 알아서 정해보자.

 

나는 home 디렉토리에 ubuntu 폴더를 만들었다.

그래서 위와같이 Remote Directory 는 /home/ubuntu 가 되었다

 

이렇게 하면 Jenkins가 실제로 배포할때 서버에 접속할 수 있게 되었다

 

3. 배포 item 생성 - Free Style

자 드디어 배포를 해보자!!

 

Dashboard 에서 새로운 Item 을 추가해준다

 

 

다양한 선택지가 있지만, 우선 Freestyle project 를 만들어보겠다

해당 프로젝트명 혹은 구분가능한 이름을 input에 입력해주자

 

두가지 옵션의 간단한 차이는 아래와 같다

Freestyle project ?
-> jenkins 설정으로만 배포한다
Pipeline ? 
-> 프로젝트 소스코드에 내가 직접 커맨드를 입력한 정보를 기반으로 배포한다

 

 

 

item 을 생성하면 또!! 설정창이 나온다 ㅎㅎ

기존에 설정했던것이 서버에 대한 설정이라면, 지금은 repository 에 대한 설정이라고 보면된다

 

1) Github 설정

설명 부분에 해당 프로젝트의 설명을 간단히 입력해주고 하단의 Github project 체크박스를 선택한다

그리고 나의 repository 주소를 넣어준다. git clone 할때 입력되는 http 주소이다

 

밑에 내리면 소스코드관리 -> Git 을 선택한다

Repository URL 은 위에서 입력한 github 주소와 똑같이 입력해주고, Credentials도 기존에 설정된 계정을 선택한다

 

하지만!!!

 

만약 private github repository 를 사용한다면 해당 계정으로는 오류가 발생한다

 

원인은, 정책변경으로 인하여 user/password 방식으로 등록한 github계정으로는 해당 repository에 접근이 불가하다

토큰방식으로 등록된 github 계정이 필요하다

 

또한!! 해당 private repository를 생성한 계정이 필요하다.

 

repository 가 public 이라면 아래 과정은 넘어가주길 바란다.

만약 private 라면 Credentials 하단의 Add를 눌러서 토큰방식의 계정을 추가해보자

 

secret 에 github에서 발급받은 토큰을 입력해야한다

Kind → Secret Text 선택 (토큰 인증방식)
Domain : Global credentials
Secret : 깃헙에서 발급 받은 토큰 입력
ID : 해당 정보를 대표할 name이며, 해당 계정을 구분하기위한 용도로만 사용되는 대표이름. title
Description : 안적어도 됨

 

 

2) Build Step 설정

 

github 설정하고 내리다보면 빌드유발..빌드환경..등등 많이 있지만 

안타깝게도 AWS 프리티어는 빌드를 할때마다 data transfer fee가 청구된다 ㅠㅠ 그래서 한달에 정해진 용량이있는데..

내가봣을땐 한달에 30번정도 하면 용량에 딱 맞았던거같다. 그래서 github hook을 연결해서 빌드하는 작업은 건너뛰었다

 

이제 각 프로젝트에 맞는 빌드과정을 진행하면 되는데, 나는 Spring boot - java 프로젝트를 배포하였다

 

 

gradle clean build를 해준다는 의미이다

echo ">> grant permission"
chmod +x gradlew

echo ">> project clean Build Start"
./gradlew clean build

 

3) 빌드 후 조치

빌드가 되면 어떤 작업이 필요한지 설정한다

spring 프로젝트의 경우 실행중인 포트가 있다면 종료하고 jar 파일을 실행시키도록 하였다

나는 이미 선택해서 회색으로 되어있지만 Send build artifacts over SSH 선택한다

 

이제 또 버라이티하게 입력할 영역이 노출되지만 침착하게 입력해보자

나는 spring boot 멀티모듈 프로젝트였기에 경로가 좀 보잡하다

 

각 항목에 대한 부가설명은 아래와 같다

 

name :: 프로젝트 명

Transfer :: 어느경로의 배포파일을 어디로 복사할건지 정하는 영역

 

Source files : build/libs/*.jar 로 입력

 - 만약 멀티모듈이라면 해당 모듈명/build/libs/*.jar 로 입력

 

Remove prefix : 배포 시 Source files 의 경로에서 제거되어야하는 경로를 입력

 - 배포파일 즉 jar 파일은 System 설정에 등록된 Remote Directory 경로 + Source files 경로로 다운로드될건데

    공란으로 둔다면 /home/ubuntu/build/libs/*.jar 경로로 다운로드될것이다. 그것이 싫다면 build/libs 를 입력하자.

    만약 멀티모듈이라면 해당모듈명/build/libs/*.jar 로 입력

 

Remote directory : 배포파일 위치할 폴더명

 - Remove prefix 까지 설정하면 /home/ubuntu/*.jar 경로로 다운로드 될텐데, 이러면 어떤프로젝트인지 구분이 되지 않으니

    구분하고싶은 폴더명을 입력하면 된다. 즉 /home/ubuntu/폴더명/*.jar 의 경로로 받아지게 하기 위한 폴더명이다

 

Source files : build/libs/hello.jar
Remove prefix : build/libs
Remote directory : helloJava

이렇게 설정된 경우, 최종적으로 배포파일은 /home/ubuntu/helloJava/hello.jar 경로로 배포될것이다

 

Exec command : 옮기고나서 실행할 커맨드

 

나는 8080포트번호를 죽이고 jar 를 실행하는 커맨드를 입력했다

pid="$(lsof -t -i :8080 -s TCP:LISTEN)";

if [ "$pid" != "" ]; then
  kill -9 $pid;
  echo "$pid process kill complete"
else
  echo "pid is empty"
fi

cd /home/ubuntu/폴더명

java -jar 배포파일.jar &

 

만약 멀티모듈을 사용한다면 Add server 로 다른 모듈도 추가해주면 된다

 

진짜끝!!

 

3. 배포 item 생성 - Pipeline

백단은 freestyle 로 배포구성을 마쳤다

이제 프론트를 해야하는데, 나의 경우는 react-next.js 로 구성된 프로젝트였다

때문에 해당 프로젝트를 jenkins에서 배포하기 위하여 node js 플러그인 설치가 필요하였다

 

1) node js 플러그인 설치

Dashboard > Jenkins 관리 > Plugins > Avaliable plugins > node js 검색하여 설치하자

 

2) Node Js 이름설정

설치가 완료되었으면 아래 경로로 이동하여 다운받은 nodejs 의 이름을 설정해준다

나는 nodejs 라고 설정하였다

 

Dashboard > Jenkins 관리 > Tools → NodeJs → name 설정

 

3) Jenkinsfile 추가

 

Pipeline으로 Jenkins 가 배포하기위해서, 프론트 프로젝트 소스코드를 수정해야한다

 

프로젝트 root에 Jenkinsfile 파일을 추가하고 아래의 코드를 입력한다

확장자 없고 파일명은 "Jenkinsfile" 딸랑 하나만 놓으면 된다

pipeline {
     agent any
     tools {nodejs "nodejs"}

     stages {
        stage("Build") {
            steps {
                sh "npm install"
                sh "npm run build"
            }
        }
        stage("Deploy") {
            steps {
                script {
                    sh 'chmod +x ./script/deploy.sh'
                    sh './script/deploy.sh'
                }
            }
        }
    }
}

 

상단의 코드에서 tools {nodejs "nodejs"} 라고 되어잇는 부분이 있는데,

"" 쌍따옴표 안에 들어가는 이름은 위에 Jenkins 에서 설정한 Node Js 의 이름을 정확히 넣어야한다

 

그리고 프로젝트 root에 script 폴더를 만들고 deploy.sh 파일을 추가하자

왜냐하면 상단의 코드에서 Deploy 부분에 script/deploy.sh 의 작동을 하기 때문이다

pid=$(sudo lsof -ti:3000)


echo "========= front deploy start ========="

if [ -n "$pid" ]; then
  sudo kill -9 $pid
  echo "kill ${pid} process..."
  nohup npm start &
  exit
else
  nohup npm start &
  exit
fi

echo "nginx restart..."

systemctl restart nginx

echo "========= front deploy end ========="

 

3000번 포트를 죽이고 nginx restart 해주는 설정이다

 

4) item 추가

 

자 이제 프론트 배포를 해보자ㅠㅠ

 

Pipeline 으로 아이템을추가하고 설명, github repository 주소를 입력한다

 

하단에 내리다보면 Pipeline 설정을 할수있다

위에 입력한 repository 와 동일한 url 을 입력해주고 만약 private repository 라면 위에서 설정한 토큰방식의 github 계정과 연결해준다

 

그리고 배포되어야하는 브랜치명을 입력해준다

 

 

이렇게.. 프론트/백 배포 설명을 마쳐본다

 

Freestyle 은 Jenkins 의 설정에 따라 배포되고 

pipelene은 프로젝트 내 세팅해놓은 설정에 따라 배포된다

 

이 과정을 따르면 AWS 프리티어 인스턴스에 spring boot 로 개발된 백단 프로젝트를 AWS 에 배포하고

react + next.js 로 개발된 프론트 프로젝트를 AWS 에 배포할수있다!

 

728x90

+ Recent posts