[Setting | Windows] Spring 개발환경 설정

Windows 에서 Spring 개발환경을 설치하는 방법을 정리한다.


작성일 : 2022-06-14
OS : Windows 10 Pro
CPU : 11th Gen Intel(R) Core(TM) i7-1195G7 @ 2.90GHz 2.92 GHz

1> jar 파일을 다운로드

Spring Tools Intel CPU의 경우 WINDOWS X86_64 버전을 다운로드


2> 설치하려는 곳에 jar 파일을 옮기고 java 명령 실행

java -jar spring-tool-suite-4-4.14.1.RELEASE-e4.23.0-win32.win32.x86_64.self-extracting.jar

3> Workspace를 설정하고 Eclipse를 실행


4> 새로운 Spring Starter Project 생성

Name : 프로젝트명
Type : Gradle Project
Packaging : Jar
Java Version : 11
Language : Java
Group : com.[Company Name]
Artifact : 결과물명(프로젝트명)
Version : 결과물버전
Description : 프로젝트 설명
Package : 패키지명

Spring Boot Version : 2.7.0 (프로젝트 생성시점 안정적인 버전)

Finish 클릭하여 생성

[Setting | Ubuntu] 내부망용 인증서 생성 및 등록

내부망용 시스템에 인증서를 생성하고 nginx를 통해 SSL 접속하는 방법을 정리한다.


작성일 : 2022-06-13
OS : Ubuntu 22.04 LTS

1> 서버용 키 생성

openssl genrsa -des3 -out private.key 2048
# 비밀번호를 입력하여 생성
-------------------------------------------------
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-------------------------------------------------

2> Root CA 인증서 생성

openssl req -x509 -new -nodes -key private.key -sha256 -days 365 -out rootCA.pem
# 1>에서 입력한 비밀번호 입력
-------------------------------------------------
Enter pass phrase for private.key:
# 인증서 정보 입력
-------------------------------------------------
Country Name (2 letter code) [AU]:KO
State or Province Name (full name) [Some-State]:SEOUL
Locality Name (eg, city) []:KangNam
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Opendocs
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:opd.kr
-------------------------------------------------

3> crt 파일로 변환

openssl x509 -outform der -in rootCA.pem -out rootCA.crt

4> 접속할 시스템에 인증서 등록

4-1> 윈도우

> 서버로 부터 rootCA.crt파일 다운로드
> 파일 더블클릭
> 인증서 설치(I)
> 로컬 컴퓨터(L)
> 모든 인증서를 다음 저장소에 저장(P)
> 찾아보기(R) > 신뢰할 수 있는 루트 인증 기관 선택 > 확인
> 다음(N) > 마침(F)

4-2> 맥

> 서버로 부터 rootCA.pem파일 다운로드
sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" rootCA.pem

5> Nginx 설치

Nginx설치 메뉴얼

# Install the prerequisites
apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
# Fetch the key
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
# Verify Key 
gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
# Set Up Stable Repo
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginx
# Install nginx
sudo apt update
sudo apt install nginx=1.22.*
sudo systemctl start nginx

6> 사이트 인증서 생성

# 인증서 생성
openssl genrsa -out sample.opendocs.co.kr.key 2048
openssl req -new -key sample.opendocs.co.kr.key -out sample.opendocs.co.kr.csr
# ext 파일 생성
vi sample.opendocs.co.kr.ext
-------------------------------------------------
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = sample.opendocs.co.kr
-------------------------------------------------
#  crt 파일 생성
openssl x509 -req -in sample.opendocs.co.kr.csr -CA rootCA.pem -CAkey private.key -CAcreateserial \
-out sample.opendocs.co.kr.crt -days 365 -sha256 -extfile sample.opendocs.co.kr.ext
# pem 파일 생성
openssl x509 -in sample.opendocs.co.kr.crt -outform PEM -out sample.opendocs.co.kr.pem

7> Nginx 사이트 설정

vi /etc/nginx/conf.d/sample.opendocs.co.kr.conf
server {
        listen                      443 ssl;
        server_name                 sample.opendocs.co.kr;

        ssl_certificate             /etc/encrypt/sample.opendocs.co.kr.pem;
        ssl_certificate_key         /etc/encrypt/self/sample.opendocs.co.kr.key;

        ssl_session_cache           shared:SSL:1m;
        ssl_session_timeout         5m;

        ssl_ciphers                 HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;

        location / {
                proxy_pass          https://172.20.0.104:8443;
        }
}

8> Nginx 재시작

systemctl restart nginx

9> 사이트 접속시 자물쇠 확인


10> 사이트별 설정값

Docker 구성시 컨테이너 마다 프록시 설정값이 다름
( proxy_pass 부분이 상이함)

10-1> GitLab

server {
   listen                     443 ssl;
   server_name                gitlab.opendocs.co.kr;

   ssl_certificate            /etc/letsencrypt/self/gitlab.opendocs.co.kr.pem;
   ssl_certificate_key        /etc/letsencrypt/self/gitlab.opendocs.co.kr.key;

   ssl_session_cache          shared:SSL:1m;
   ssl_session_timeout        5m;

   ssl_ciphers                HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers  on;

   location / {
      proxy_pass              http://127.0.0.1:9999;
   }
}

10-2> Jenkins

server {
   listen                     443 ssl;
   server_name                jenkins.opendocs.co.kr;

   ssl_certificate            /etc/letsencrypt/self/jenkins.opendocs.co.kr.pem;
   ssl_certificate_key        /etc/letsencrypt/self/jenkins.opendocs.co.kr.key;

   ssl_session_cache          shared:SSL:1m;
   ssl_session_timeout        5m;

   ssl_ciphers                HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers  on;

   location / {
      proxy_pass              http://127.0.0.1:8888;
   }
}

10-3> SonarQube

server {
   listen                     443 ssl;
   server_name                sonar.opendocs.co.kr;

   ssl_certificate            /etc/letsencrypt/self/sonar.opendocs.co.kr.pem;
   ssl_certificate_key        /etc/letsencrypt/self/sonar.opendocs.co.kr.key;

   ssl_session_cache          shared:SSL:1m;
   ssl_session_timeout        5m;

   ssl_ciphers                HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers  on;

   location / {
      proxy_pass              http://127.0.0.1:7777;
   }
}

10-4> Wiki

server {
   listen                     443 ssl;
   server_name                wiki.opendocs.co.kr;

   ssl_certificate            /etc/letsencrypt/self/wiki.opendocs.co.kr.pem;
   ssl_certificate_key        /etc/letsencrypt/self/wiki.opendocs.co.kr.key;

   ssl_session_cache          shared:SSL:1m;
   ssl_session_timeout        5m;

   ssl_ciphers                HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers  on;

   location / {
      proxy_pass              https://172.20.0.104:8443;
   }
}

10-5> Redmine

server {
   listen                     443 ssl;
   server_name                issue.opendocs.co.kr;

   ssl_certificate            /etc/letsencrypt/self/issue.opendocs.co.kr.pem;
   ssl_certificate_key        /etc/letsencrypt/self/issue.opendocs.co.kr.key;

   ssl_session_cache          shared:SSL:1m;
   ssl_session_timeout        5m;

   ssl_ciphers                HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers  on;

   location / {
      proxy_pass              http://127.0.0.1:5555;
   }
}

[Setting | Ubuntu] Docker 기본환경 구성 및 설치

도커를 활용하기 위한 기본 환경 구성 설정법과 docker compose를 활용한 서비스 실행법을 정리한다.


작성일 : 2022-06-08
OS : Ubuntu 22.04 LTS
Docker : Docker version 20.10.17

1> docker compose 설치

# 설치가능 버전을 확인
sudo apt-cache policy docker-compose
# --------------------------------------------

docker-compose:
  Installed: 1.29.2-1
  Candidate: 1.29.2-1
  Version table:
 *** 1.29.2-1 500
        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
        100 /var/lib/dpkg/status
# --------------------------------------------

# 특정버전의 docker-compose 설치
sudo apt install docker-compose=1.29.2-1 -y

2> data 폴더 생성

data 폴더를 만들고 docker-compose.yml 에서 컨테이너 볼륨을 생성

# root 권한으로 실행
sudo su
mkdir /data

3> .env

sudo vi /data/.env
## ----- FOR DEV_OPS
## gitlab
GITLAB_IP=172.20.0.101
GITLAB_PORT=9999
## jenkins
JENKINS_IP=172.20.0.102
JENKINS_PORT=8888
## sonarqube
SONARQUBE_IP=172.20.0.103
SONARQUBE_PORT=7777
## mediawiki
MEDIAWIKI_IP=172.20.0.104
MEDIAWIKI_PORT=6666
## redmine
REDMINE_IP=172.20.0.105
REDMINE_PORT=5555

## ----- FOR SERVICE
## postgresql
POSTGRESQL_VER=14.3
POSTGRESQL_ID=opendocs
POSTGRESQL_PW=qwer1234
POSTGRESQL_IP=172.20.0.201
POSTGRESQL_PORT=5432
## mariadb
MARIADB_VER=10.8.3
MARIADB_ROOT_PW=qwer1234
MARIADB_IP=172.20.0.202
MARIADB_PORT=3306

4> docker-compose.networks.yml

sudo vi /data/docker-compose.networks.yml
version: '3.8'

networks:
  opdnet:
    driver: bridge
    ipam:
      driver: default
      config:
      - subnet: 172.20.0.0/21
        gateway: 172.20.0.1

5> docker-compose.volumes.yml

sudo vi /data/docker-compose.volumes.yml
version: '3.8'

volumes:
## ----- FOR DEV_OPS
  gitlab_config:
    name: gitlab_config
  gitlab_data:
    name: gitlab_data
  gitlab_logs:
    name: gitlab_logs
  jenkins_home:
    name: jenkins_home
  sonarqube_data:
    name: sonarqube_data
  sonarqube_logs:
    name: sonarqube_logs
  sonarqube_extensions:
    name: sonarqube_extensions
  mediawiki_data:
    name: mediawiki_data
  redmine_data:
    name: redmine_data

## ----- FOR SERVICE
  postgresql_data:
    name: postgresql_data
  mariadb_data:
    name: mariadb_data

6> docker-compose.services.yml

sudo vi /data/docker-compose.services.yml
version: '3.8'

services:
## ----- FOR DEV_OPS
    gitlab:
        image: gitlab-opendocs
        build:
            context: .
            dockerfile: ./gitlab/Dockerfile
        hostname: gitlab
        container_name: gitlab
        networks:
            opdnet:
                ipv4_address: ${GITLAB_IP}
        ports:
        - ${GITLAB_PORT}:80
        - '10022:22'
        restart: always
        volumes:
        - gitlab_config:/etc/gitlab:rw
        - gitlab_logs:/var/log/gitlab:rw
        - gitlab_data:/var/opt/gitlab:rw

    jenkins:
        image: jenkins-opendocs
        build:
            context: .
            dockerfile: ./jenkins/Dockerfile
        user: root
        hostname: jenkins
        container_name: jenkins
        networks:
            opdnet:
                ipv4_address: ${JENKINS_IP}
        ports:
        - ${JENKINS_PORT}:8080
        - '50000:50000'
        environment:
        - JAVA_OPTS='-Dhudson.model.DownloadService.noSignatureCheck=true'
        volumes:
        - jenkins_home:/var/jenkins_home:rw

    sonarqube:
        image: sonarqube-opendocs
        build:
            context: .
            dockerfile: ./sonarqube/Dockerfile
        hostname: sonarqube
        container_name: sonarqube
        networks:
            opdnet:
                ipv4_address: ${SONARQUBE_IP}
        ports:
        - ${SONARQUBE_PORT}:9000
        volumes:
        - sonarqube_data:/opt/sonarqube/data:rw
        - sonarqube_logs:/opt/sonarqube/logs:rw
        - sonarqube_extensions:/opt/sonarqube/extensions:rw

    mediawiki:
        image: mediawiki-opendocs
        build:
            context: .
            dockerfile: ./mediawiki/Dockerfile
        hostname: mediawiki
        container_name: mediawiki
        networks:
            opdnet:
                ipv4_address: ${MEDIAWIKI_IP}
        ports:
        - ${MEDIAWIKI_PORT}:80
        - '8443:8443'
        environment:
        - MEDIAWIKI_HOST=wiki.opendocs.co.kr
        - ALLOW_EMPTY_PASSWORD=yes
        - MEDIAWIKI_DATABASE_HOST=${MARIADB_IP}
        - MEDIAWIKI_DATABASE_PORT_NUMBER=${MARIADB_PORT}
        - MEDIAWIKI_DATABASE_USER=mediawiki
        - MEDIAWIKI_DATABASE_PASSWORD=qwer1234
        - MEDIAWIKI_DATABASE_NAME=mediawiki
        volumes:
        - mediawiki_data:/bitnami/mediawiki:rw
        depends_on:
        - mariadb
        links:
        - mariadb

    redmine:
        image: redmine-opendocs
        build:
            context: .
            dockerfile: ./redmine/Dockerfile
        hostname: redmine
        container_name: redmine
        networks:
            opdnet:
                ipv4_address: ${REDMINE_IP}
        ports:
        - ${REDMINE_PORT}:3000
        - '8444:8443'
        environment:
        - ALLOW_EMPTY_PASSWORD=yes
        - REDMINE_DATABASE_HOST=${MARIADB_IP}
        - REDMINE_DATABASE_PORT_NUMBER=${MARIADB_PORT}
        - REDMINE_DATABASE_USER=redmine
        - REDMINE_DATABASE_PASSWORD=qwer1234
        - REDMINE_DATABASE_NAME=redmine
        volumes:
        - redmine_data:/bitnami/redmine:rw
        depends_on:
        - mariadb
        links:
        - mariadb


## ----- FOR SERVICE
    postgresql:
        image: postgres:${POSTGRESQL_VER}
        hostname: postgresql
        container_name: postgresql
        networks:
            opdnet:
                ipv4_address: ${POSTGRESQL_IP}
        ports:
        - ${POSTGRESQL_PORT}:5432
        environment:
            POSTGRES_USER: ${POSTGRESQL_ID}
            POSTGRES_PASSWORD: ${POSTGRESQL_PW}
        volumes:
        - postgresql_data:/var/lib/postgresql/data:rw
    mariadb:
        image: mariadb:${MARIADB_VER}
        hostname: mariadb
        container_name: mariadb
        networks:
            opdnet:
                ipv4_address: ${MARIADB_IP}
        ports:
        - ${MARIADB_PORT}:3306
        environment:
            MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PW}
        volumes:
        - mariadb_data:/var/lib/mysql:rw
        - ./mariadb/query/:/docker-entrypoint-initdb.d/:rw

7> Dockerfile

7-1> gitlab

sudo mkdir /data/gitlab
sudo vi /data/gitlab/Dockerfile
FROM gitlab/gitlab-ce:14.9.5-ce.0

# RUN
# COPY

7-2> jenkins

sudo mkdir /data/jenkins
sudo vi /data/jenkins/Dockerfile
FROM jenkins/jenkins:2.354

# RUN
# COPY

7-3> sonarqube

sudo mkdir /data/sonarqube
sudo vi /data/sonarqube/Dockerfile
FROM sonarqube:9.4-community

# RUN
# COPY

7-4> mediawiki

sudo mkdir /data/mediawiki
sudo vi /data/mediawiki/Dockerfile
FROM bitnami/mediawiki:1.37.2

# RUN
# COPY

7-5> redmine

sudo mkdir /data/redmine
sudo vi /data/redmine/Dockerfile
FROM bitnami/redmine:5.0.1

# RUN
# COPY

7-6> mariadb

sudo mkdir /data/mariadb
sudo mkdir /data/mariadb/query
sudo vi /data/mariadb/query/init.sql
CREATE USER IF NOT EXISTS root@localhost IDENTIFIED BY 'qwer1234';
SET PASSWORD FOR root@localhost = PASSWORD('qwer1234');
GRANT ALL ON *.* TO root@localhost WITH GRANT OPTION;

CREATE USER IF NOT EXISTS root@'%' IDENTIFIED BY 'qwer1234';
SET PASSWORD FOR root@'%' = PASSWORD('qwer1234');
GRANT ALL ON *.* TO root@'%' WITH GRANT OPTION;

CREATE USER IF NOT EXISTS mediawiki@'%' IDENTIFIED BY 'qwer1234';
SET PASSWORD FOR mediawiki@'%' = PASSWORD('qwer1234');

CREATE USER IF NOT EXISTS redmine@'%' IDENTIFIED BY 'qwer1234';
SET PASSWORD FOR redmine@'%' = PASSWORD('qwer1234');

CREATE DATABASE IF NOT EXISTS mediawiki;
GRANT ALL ON mediawiki.* TO mediawiki@'%';

CREATE DATABASE IF NOT EXISTS redmine;
GRANT ALL ON redmine.* TO redmine@'%';

8> docker-compose up & down

# root 권한으로 실행
sudo su
# yml파일이 있는 폴더에서 실행
cd /data
# docker compose up
docker-compose -f docker-compose.networks.yml -f docker-compose.volumes.yml -f docker-compose.services.yml up -d
# docker compose down
docker-compose -f docker-compose.networks.yml -f docker-compose.volumes.yml -f docker-compose.services.yml down
# docker compose down & delete volume
docker-compose -f docker-compose.networks.yml -f docker-compose.volumes.yml -f docker-compose.services.yml down --volumes
# log
docker-compose -f docker-compose.networks.yml -f docker-compose.volumes.yml -f docker-compose.services.yml logs
# build
docker-compose -f docker-compose.networks.yml -f docker-compose.volumes.yml -f docker-compose.services.yml up -d --build

9> 추가설정

9-1> mediawiki

sudo vi /var/lib/docker/volumes/mediawiki_data/_data/LocalSettings.php
----------------------------------------------------
# 변경전
$wgServer = '//localhost';
# 변경후
$wgServer = '//wiki.opendocs.co.kr';
----------------------------------------------------
# 컨테이너 확인
sudo docker ps -a
# 컨테이터 재시작
sudo docker container restart [CONTAINER_ID]

10> docker-compose.*.yml 이 수정되었을 경우

docker-compose up -d [서비스_이름]

11> Dockerfile 이 수정되었을 경우

docker-compose up -d --build [서비스_이름]