336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

새로 들어간 회사의 프로젝트를 관리하기 위해 Redmine 을 사용하기로 결정하였고, 

Agile Plugin 을 설치/사용하여 사용가능한 수준임을 파악하기 위한 로컬에 환경을 구성하기로 하였다. 

 

간략하게 정리하면 한번의 시행착오가 있었다. 

레드마인과 PostgreSQL 을 각각의 도커로 설치하였고, 연동하고자 부단히 노력했으나 안되었다. 

이유) 컨테이너는 Linux Namespace 기술을 이용해 각자 격리된 네트워크 공간을 할당받게 된다. 

 

이를 간과했다. Bridge 가 필요함을 알고 있었으나, 그 사실을 잊었던 것이었다. 

테스트라 쉽게 가기로 하였다. 

 

Docker-Compose

#docker-compose.yml

# docker-compose -f :: 다른 이름이나 경로의 파일을 Docker Compose 설정 파일로 사용할 경우
# docker-compose up : 가장 자주 사용되는 커맨드, Docker Compose 에 정의되어있는 모든 서비스 컨테이너를 한 번에 생성하고 실행하기 위해 사용
# 보통 -d 옵션을 사용하여 백그라운드에서 컨테이너를 띄우는 경우가 많음
# docker-compose down : Docker Compose 에 정의되어있는 모든 서비스 컨테이너를 한 번에 정지시키고 삭제하기 위해 사용
# docker-compose start : 정지된 특정 서비스 컨테이너를 올리기 위해 사용
# docker-compose stop : 실행 중인 특정 서비스 컨테이너를 정지시키기 위해서 사용
# docker-compose ps : Docker Compose 에 정의되어 있는 모든 서비스 컨테이너 목록을 조회할 때 사용 
# docker-compose log : 서비스 컨테이너의 로그를 확인하고 싶을 때 사용. 보통 -f 옵션을 붙여서 실시간 로그 확인 ex) docker-compose logs -f web
# docker-compose exec : 실행 중인 서비스 컨테이너를 대상으로 어떤 명령어를 날릴 때 사용 ex) docker-compose exec db psql postgres postgres
# docker-compose run : 서비스 컨테이너의 특정 명령어를 일회성으로 실행할 때 사용 ex) docker-compose run web env
# docker-compose config : 설정을 확인할 때 사용. -f 옵션으로 여러 개의 설정파일을 사용할 때, 최종적으로 어떻게 설정이 적용되었는지 확인해 볼때 유용

#version: '3.8'

services:
  redmine:
    image: 'bitnami/redmine:4.1.2'
    ports:
      - '8283:3000'
    restart: always
    environment:
      REDMINE_DB_POSTGRES: postgres
      REDMINE_DB_DATABASE: bitnami_redmine
      REDMINE_DB_USERNAME: redmine
      REDMINE_DB_PASSWORD: redmine

    volumes:
      - '/Users/path/work/dataDB/redmine:/usr/src/redmine/files'
      - '/Users/path/work/dataDB/redmine:/usr/src/redmine/public/themes'
      - '/Users/path/work/dataDB/redmine:/usr/src/redmine/plugins'   

    container_name: 'redmine-container'

  postgres:
    image: postgres:13
    container_name: redmine-postgesql-container
    restart: always
    
    volumes:
      - /Users/path/work/dataDB/postgres-redmine/data:/var/lib/postgres/data
    ports:
      - 25432:5432

    environment:
      POSTGRES_DB: bitnami_redmine
      POSTGRES_USER: redmine
      POSTGRES_PASSWORD: redmine

위처럼 docker compse 를 설정하고, docker-compse /yml 위치경로/docker-compose.yml up 을 실행.

정상적으로 올라온 것을 확인 할 수 있었다. 

 

그럼 연동하기로 한 PostgreSQL 은 어떻게 되었을까? 

docker logs redmine-container | grep post 

 

postgre INFO 에서 잘 듣고 일하고 있다 알려주고 있다. 

 

그럼 레드마인에 접속해보자. 경로를 치고 들어가보면 아래와 같이 잘 뜬다. 근데.... 계정이.... 뭐지??? 

admin/admin, admin/system.... 등등 별의 별 것을 다 해보았으나, 안된다.!!!!

 

접속이 안되면, 가볍게 회원가입을 하자!!! 회원가입을 하면 승인단계가 필요한데, 이것은 DB 에 접속하여 값을 UPDATE 했다. 

( DB 로 회원정보를 넣으려 했더니, 비밀번호, salt 에서 MD5 니 digest 라니... 뭐 이런걸 시키길래... 아 귀찮아~~~~ )

 

쉽게, users 테이블에서 admin과 status 값만 true, 1 로만 바꿔주면 관리자 권한 쉽게 획득할 수 있다. 

그리고 로그인을 해보면, 아래와 같은 초기화면을 볼 수 있다. 

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

스프링에서 제공하는 Schedule 기능을 사용했었는데, 정리하는 차원으로 남깁니다. 

 

1. @EnableScheduling 을 이용한 Schedule 설정

  -. 설정파일에 스케쥴을 사용하겠다는 의미로 @EnableScheduling을 추가하여 스케쥴링 기능을 사용하겠다는 것을 표기하여 줄 수 있다.

  -. @Scheduled 어노테이션을 메서드 상단에 붙여 메서드가 주기적으로 동작하도록 설정할 수 있다.

 

단점 : Scheduler 자체의 동작여부를 직접정의할 필요가 있을 경우 스케쥴러의 동작을 제어할 수 없다. 

@Component
@EnableScheduling
@PropertySource(name = "classpath:/constants.yml", value = "")
public abstract class ScheduledConfig {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("prefix.schedule.thread-pool")
    private String THREAD_PREFIX_NAME;

    @Bean
    public TaskScheduler scheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setThreadNamePrefix(THREAD_PREFIX_NAME);
        scheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);
        return scheduler;
        }
}
--------------------------------------------------------------------------------------------

@Component
@EnableScheduling
public class LotteryCrawling {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final String scheduleTerm = "0/5 * * * * *";

    /*  아래 표현식으로 다양하게 주기를 설정할 수 있다. 
        cron : cron 표현식을 사용하여 특정 시간마다 동작 ("초 분 시 일 월 요일" 6필드)
        fixedDelay : 작업이 끝난 시점 기준, milliseconds 마다 동작
        fixedDelayString : fixedDelay와 동일, 속성값만 String으로 입력
        fixedRate : 작업이 시작한 시점 기준, milliseconds 마다 동작
        fixedRateString : fixedRate와 동일, 속성값만 String으로 입력
        initialDelay : 최초 수행 지연 시간, milliseconds 이후에 실행
        initialDelayString : initialDelay와 동일, 속성값만 String으로 입력
        zone : 시간대, Oracle Real-Time Collabaration에서 지원하는 시간대 목록
        설정하지 않으면 default는 설치된 서버의 시간대로 설정됨
        시간대를 직접 설정해야 할 경우에는 아래 오라클 문서를 참고하시면 되요. (예시: "Asia/Seoul")
        https://docs.oracle.com/cd/B13866_04/webconf.904/b10877/timezone.htm

        * : 모든 값
        ? : 설정 없음 (일과 요일만 사용 가능)
        , : 배열 ex) 1,5,8 : 1,5,8에만
        - : 앞부터 뒤까지 ex) 1-3 : 1부터 3까지
        / : 앞부터 뒤마다 ex) 1/3 : 1부터 매3마다 1,4,7,11...
    */

    @Scheduled(cron = scheduleTerm)
    // 필요에 따라서는 아래와 같이 SpEL을 사용하여 프로퍼티의 값에 따른 주기적인 작업설정도 가능하다.
    //@Scheduled(cron="${properties value}")

    public void getCrawlingData() {
        // to do somthing

        }
}

2. Dynamic Scheduling

  -. ThreadPoolTaskScheduler라는 클래스를 활용하여 추상클래스로 동작시점을 직접정의

 

다양하게 정의하여 사용하기 위해서 실행영역과 주기설정을 추상클래스로 정의하도록 구현하였다.

그리고 부트 실행과 동시에 스케줄이 등록될 수 있도록 ApplicationRunner를 이용하여 초기 실행하였다. 

public abstract class DynamicScheduledConfig {

    private Logger logger = LoggerFactory.getLogger(getClass());
    private ThreadPoolTaskScheduler scheduler;

    public void stopScheduler() {
        if(scheduler != null) {
            scheduler.shutdown();
        }
    }

    public void startScheduler() {
        scheduler = new ThreadPoolTaskScheduler();
        scheduler.initialize();
        scheduler.setPoolSize(4);
        scheduler.schedule(getRunnable(), getTrigger());
    }

    private Runnable getRunnable() {
        return new Runnable() {
            @Override
            public void run() {               
                runner();
             }
        };
    }

    public abstract void runner();
    public abstract Trigger getTrigger();
}
--------------------------------------------------------------------------------------------
@Component
public class ScheduleApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        DynamicScheduledConfig scheduledConfig = new DynamicScheduledConfig() {
            @Override
            public void runner() {
                //to do something
            }

            @Override
            public Trigger getTrigger() {
                return new CronTrigger("0/10 * * * * *");
            }
        };

        scheduledConfig.startScheduler();
    }
}

참고) www.daleseo.com/spring-boot-runners/
스프링 부트 애플리케이션 구동 시점에 특정 코드 실행 시키기기 위해서 2가지 인터페이스를 제공

1. CommandLineRunner

  -. 인터페이스는 구동 시점에 실행되는 코드가 자바 문자열 아규먼트 배열에 접근해야할 필요가 있는 경우에 사용

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class DemoCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner Args: " + Arrays.toString(args));
    }
}

2. ApplicationRunner

  -. CommandLineRunner 인터페이스와 마찬가지로 구동 시점에 run() 메소드를 실행시키지만 다른 타입의 인자를 받음.

    단순 인자의 스트링 배열을 포함한 추상화한 ApplicationArguments 타입의 객체가 대신 run() 메소드의 인자로 넘어옴

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class DemoApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner Args: " + Arrays.toString(args.getSourceArgs()));
    }
}

 

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

맥유저가 손쉽게 패키지를 설치할 수 있는 Homebrew 설치를 알아보자.

 

https://brew.sh/index_ko

 

 

Homebrew

The Missing Package Manager for macOS (or Linux).

brew.sh

설치방법 은 Homebrew 에서도 잘 나와있습니다.

 

기본 터미널에서 아래의 명령어를 삽입 후 엔터 

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

 

 

+ Recent posts