본문 바로가기

프로젝트/멋사 개인 프로젝트 (mutsa-SNS)

[02] mutsa-SNS 1일차 - (1) CI/CD 설정

첫째 날은 CI/CD 설정과 회원가입 기능을 구현하였다.

1. Gitlab project 생성

https://gitlab.com/pigeon2gugu/finalproject_kimhaneul

 

하늘 / FinalProject_KimHaneul · GitLab

GitLab.com

gitlab.com

  • 처음에 root directory 안에 repository를 추가하여 진행하려 하였으나, 후에 docker build에서 root가 아닌 repository여서 문제가 생겨 root에 바로 생성하였다.
  • 위의 과정에서 repository 이름을 대문자로 하여 build과정에 문제가 생겼다. 주의가 필요 할 듯 하다.

 

2. java project 생성

  • Gradle - Groovy로 생성
  • Java 11로 생성
  • Lombok, Spring Configuration Processor, Spring Web, Mustache, Spring Security, MySQL Driver dependency 추가

 

3. helloController 생성

helloContoller

@RestController
@RequestMapping("/api/v1/")
public class HelloController {

    @GetMapping("/hello")
    public ResponseEntity<String> hello() {
        return ResponseEntity.ok().body("hello");
    }
}

hello를 출력하는 간단한 controller이다. 다만 초기에 SpringSecurity를 추가해주었기 때문에, 기본 Security 설정이 필요하여 SecurityConfig class를 만들어 설정을 해주었다.

 

SecurityConfig

@EnableWebSecurity
@Configuration
//WebSecurityConfigurerAdapter 는 이후 SpringBoot에서 잘 안쓰게 됨
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .httpBasic().disable()
                .csrf().disable()
                .cors().and()
                .authorizeRequests()
                .antMatchers("/api/v1/**").permitAll()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // jwt사용하는 경우 씀
                .and()
                .build();
    }

}

"/api/v1" 의 모든 주소에 대하여 허용해 주었다.  해당 문장이 없으면 error가 발생한다.

 

application.yml

server:
  port: 8080
  servlet:
    encoding:
      force-response: true

application.properties 에서 application.yml로 변경하였다.

포트는 8080으로, 한글 인코딩도 가능하게 일단 설정하였다.

4. Swagger 추가

swagger 3.0.0 ver을 추가하였다.

 

build.gradle

implementation "io.springfox:springfox-swagger-ui:3.0.0"

dependency를 추가하였다.

 

SwaggerConfig

@Configuration
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
}

 

<Reference>

https://velog.io/@wotj7687/Spring-Boot-Swagger-3.0.0-%EC%A0%81%EC%9A%A9

 

4. Pipeline 생성

gitlab에서 CI/CD - Editor 에서 .gitlab-ci.yml.file을 생성하였다.

생성 후 CI/CD - jobs 에서 실행 과정을 볼 수 있다.

 

.gitlab-ci.yml.file

stages:
  - dockerbuild-push

package:
  image: docker:latest
  stage: dockerbuild-push
  services:
    - docker:dind
  before_script:
    - docker login registry.gitlab.com -u $GITLAB_USER -p $GITLAB_PASSWORD
  script:
    - docker build -t registry.gitlab.com/$GITLAB_USER/$PROJECT_NAME .
    - docker push registry.gitlab.com/$GITLAB_USER/$PROJECT_NAME
  after_script:
    - docker logout

$GITLAB_USER , $GITLAB_PASSWORD, $PROJECT_NAME은 Setting - CI/CD - Variables에서 추가하였다.

 Packages and registries - Container registry 에서 생성된 docker image path를 확인 할 수 있다.

5. Crontab CD

xshell로 aws ec2에 접속하여 sudo su - 로 root로 접근 하였다.

vim 편집기를 이용하여 docker에 image를 pull하고, docker run을 하기위한 deploy를 생성하였다.

 

deploy-docker.sh

set -ex

docker pull registry.gitlab.com/<username>/<repository>:latest | grep "Image is up to date" && pull_status="already_pulled" || pull_status="newly_pulled"

echo $pull_status

if [ "$pull_status" = "newly_pulled" ]; then
        docker stop mutsa-sns
        docker rm -f mutsa-sns
        docker run -p 8080:8080 --name mutsa-sns -e SPRING_DATASOURCE_URL= <datasource_url> -e SPRING_DATASOURCE_PASSWORD= <password> -d registry.gitlab.com/<username>/<repository>
fi

pull할 image정보를 적고, 새로운 이미지가 pull ("newly_pulled")이면 띄워져 있던 docker container를 멈추고, 삭제하며 새로운 container를 띄운다.

 

그 후 Crontab을 이용하여 자동화 하였다.

 

crontab -e

* * * * * sh /root/deploy-docker.sh >> /root/deploy.log

 

초기 crontab -e를 입력하면 편집기 선택이 나오는데, 2번을 선택하여 익숙한 vim 편집기를 이용하였다.

*은 순서대로 분, 시간, 일, 월, 요일 을 뜻한다. 매 분 자동으로 deploy를 수행하기 위해 * * * * * 을 입력하였다.

deploy-docker.sh를 매분 실행하여, 값을 deploy.log에 남기는 명령어이다.