2. linux에 Docker 설치하기

|

1. Window에 Docker 설치하기

|

[1] 가상화 기능 활성화 확인

도커는 윈도우용/macOS용에서 안정(stable)버전과 개발(edge)버전으로 나위어 제공된다.

윈도우용 도커를 실행하려면 가상화 기능이 필요하다.

가상화 기능 활성화 확인

작업관리자 > CPU탭 > 가상화 항복 ‘사용’ 확인

views


사용하지 않음으로 되어있다면 컴퓨터 바이어스(UEFI0) 설정에서 가상화 기능을 활성화 해야한다.


[2] Docker 다운로드 및 설치

도커 다운로드 url에서 윈도우용 도커 안정버전을 받을 수 있다. 회원가입 후 아래의 버튼을 클릭하면 된다.

views
views

도커 인스톨러 파일을 다운로드 했다면 Hyper-V 기능을 활성화 하고 확인버튼을 눌러 설치 완료 후 윈도우를 재시작한다.

views
views

도커가 실행되고 작업 표시줄에 Docker is running이라는 메세지가 나타나면 정상적으로 설치된 것이다.

도커가 실행된 상태에서 PowerShell(혹은 gitbash)을 통해 docker version 명령어 실행시 현재 도커버전 확인이 가능하다.

views
간혹 윈도우에서 메모리 확보 실패 등 이유로 실행 실패하는 경우가 있는데, 서비스 재시작 혹은 설정에서 CPU 혹은 메모리 할당을 줄여야한다.


[3] Docker 기본 설정

도커 아이콘 > 오른쪽마우스 클릭 > settings 클릭

views

- 도커 자동 실행 설정

Gerneral 탭에서 ‘Start Docker Desktop when you log in’ 체크를 하면 운영체제 로그인 시 도커가 자동으로 실행된다.

- 자동 업데이트 확인

Gerneral 탭에서 ‘Automatically check for updates’를 체크하면 최신 버전 출시만 알려줄 뿐 강제 업데이트가 일어나진 않는다.

views

- 프록시

‘Proxies’ 탭에서 원격 도커 저장소에서 도커 이미지를 받아올 떄 사용할 HTTP/HTTPS 프록시를 설정할 수 있다. 제한된 대상에만 접근을 허용하는 프라이빗 저장소로부터 이미지를 받아와야하는 경우에는 ‘Manual proxy configuration’을 선택해서 설정하면 된다.

views

- 비보안 레지스트리

‘Daemon-Basic’에서 ‘Insecure registries’에서 비보안 도커 레지스트리를 등록할 수 있다. 도커 레지스트리는 기본적으로 HTTPS통신을 권장하며 HTTP통신을 사용하려면 별도로 설정해줘야한다.

views

‘Daemon-Advanced’에서는 JSON포맥으로 도커를 설정할 수 있다. 도커 설정화면에 나오지 않는 사항을 변경하려면 JSON문자열을 수정하면 된다.

views



15 리눅스 네트워크 설정 - ip 고정하기

|

1) 리눅스 네트워크 설정 전 확인

리눅스에서 내 ip 확인 명령어 : ifconfig -a

views

ip address = 192.168.1.52


네트워크 인터페이스 작동 중지/시작

if config eth0 down : 중지

if config eth0 up : 작동

views


2) 리눅스 네트워크 설정 전 알아야 할 것

1. IPADDR = 192.168.1.52

ifconfig 명령어를 통해 현재 리눅스에서 사용중인 ip 주소를 알아야 한다.


2. NETMASK = 255.255.255.0

넷마스크 란 ?

  • 하나의 네트워크를 몇 개의 네트워크로 나눠 사용할 때 나눠진 각각의 네트워크를 구분하기 위해 사용하는 특수한 bit이다.
  • IP 주소에 대한 네트워크 아이디와 호스트 아이디를 구분하기 위해서 사용된다.
  • 정확한 표현은 서브넷 마스크(Subnet Mask) 이다.
views


3. GATEWAY = 192.168.1.1 -> ex) 쓰고있는 인터넷 ( 공유기 )

게이트웨이 란?

서로 다른 네트워크를 연결해주는 역할을 하는 특정 장비나 특정 호스트를 의미한다.


4. DNS1 = 168.126.63.1

views

3) 네트워크 설정 - ip 고정시키기

서버를 restart하는 방법 3가지

  1. ifconfig eth0 down

    ifconfig eth0 up

  2. /etc/init.d/network restart

  3. sync

    sync

    sync

    reboot


1. 네트워크 설정 파일 수정하기

vi /etc/sysconfig/network-script/ifcfg-eth0

views

1, BOOTPROTO=static 으로 변경

2, 시작하기 전 알아야 하는 설정 추가


2. 서버 restart

views


3. Xshell 설정

XShell에서 open 명령어를 쳤을 때, 바로 연결할 수 있게 설정하기.

새로만들기 = Alt + N

views
views



14 리눅스 vi 자주쓰는 유용한 단축키, 명령어 정리

|

views

[TOC]

리눅스에서 파일을 수정할 때,

vi {파일} 명령어 입력 후 사용할 수 있는 단축키 정리



0) 실제로 내가 제일 많이 쓰던 명령어

손에 익지 않아서 간단한 것들만 자주 쓰게 된다,,,

단축키 수행작업
shift + g (=window end 키) 커서 맨뒤로
gg (=window home키) 커서 맨앞으로
yy 복사(해당줄에 커서 후 yy)
p, P 붙여넣기(해당줄에 커서 후 p or P)
dd 줄 지우기(한 줄 삭제)
dw 단어 지우기
u 방금 수행 되돌리기
shift + u 해당 줄만 수행 되돌리기
shift + j 현재줄과 다음줄 연결

1) 유용한 단축키

- 삽입 기능 단축키 ( 명령모드 )

단축키 수행작업
i 커서 앞에 삽입
a 커서 뒤에 삽입
o 현재 줄 다음에 삽입
I 현재 줄 첫 칸 앞에 텍스트 입력
A 현재 줄 끝에 텍스트 입력
O 현재 줄 앞에 삽입


- 삭제 기능 단축키 ( 명령모드 )

단축키 삭제 대상 수행작업
x, #x 문자 커서 위치의 문자 삭제
dw, #dw 단어 커서 위치의 단어 삭제
dd, #dd 커서 위치의 줄 삭제
D(shift+d) 줄의 일부 커서 위치부터 줄 끝까지 삭제
u   방금 수행 명령 취소
U   해당 줄의 모든 편집 취소


- 복사 / 잘라내기 / 붙이기 기능 단축키 ( 명령모드 )

단축키 수행작업
yy, #yy 현재 행을 버퍼로 복사 (ex: 5yy - 현재 행부터 아래로 5줄을 버퍼에 저장)
p 현재 행 다음에 버퍼 내용 삽입
P 현재 행 위쪽에 버퍼 내용 삽입
dd, #dd 현재 행을 잘라내기

버퍼

  • vi는 작업 내용을 버퍼에 저장 - 실행 취소 가능
  • 복사하기, 잘라내기에 사용

사용 예

  • a3yy : 현재 행부터 아래로 3줄을 a 버퍼에 저장
  • ap : a 버퍼의 내용을 붙여넣기


- 검색 기능 단축키 ( 명령모드 )

단축키 수행작업
/문자 현재 위치부터 파일 앞쪽으로 문자열 탐색
?문자 현재 위치부터 파일 뒤쪽으로 문자열 탐색
n 다음 문자열 탐색
N 역방향으로 문자열 탐색

- 삽입 기능 단축키


- 기타

vi에서 쉘 명령어 실행

명령어 수행작업
:!명령 vi를 중단하고 지정한 명령 수행
  다시 vi로 돌아올 때 : enter
:sh vi를 잠시 빠져나가서 쉘을 수행
  다시 vi로 돌아올 때 : exit

알아두면 유용한 명령 키

명령어 수행작업
:f 파일명 파일 이름을 지정한 이름으로 변경
:w %.old 현재 파일을 .old 이름으로 저쟁해 둘 때
^g 기본적인 파일 정보 출력(파일명, 라인 수 등..)
J 현재 줄과 다음 줄 연결
. 바로 이전에 수행한 명령 재 실행
~ 현재 커서위치의 한 문자를 소문자 혹은 대문자로 전환


- vi 종료 단축키

저장 : 저장하거나 종료하려면 “명령모드”로 돌아와야 한다.

ex) 편집 후 ESC 키를 눌러 편집모드가 아닌 명령모드 상태로 아래의 명령어를 쳐야한다.

명령어 수행작업
:w 현재의 파일명, 상태로 파일 저장
:w 파일명 지정한 파일명, 상태로 파일 저장


종료 명령 : 저장 후 종료 또는 그냥 종료

명령키 수행작업
:q 작업 내용을 저장했으면 vi종료, 안했으면 종료 불가
:q! 작업 내용을 저장하지 않고 강제로 vi 종료
:wq 작업 내용을 저장한 후 vi 종료
:wq 파일명 작업 내용을 지정한 파일명으로 저장한 후 vi 종료
xx(shift+zz) 작업 내용을 저장한 후 vi 종료



2) 편집모드에서 커서 움직이기

  • 편집 모드에서 마우스로 커서를 움직일 수 없다.

  • 만약 마우스로 움직이고 싶다면, ESC키를 눌러 명령모드로 바꾼 뒤 커서를 움직여야 한다.

  • 화살표 혹은 h, j, k, l 키로 움직일 수 있다.

    views


지정한 곳으로 이동하기

단축키 수행작업
:n 또는 nG 줄 번호 n 위치로
:$ 또는 G 파일의 끝 줄로 이동
n+ n줄 만큼 앞으로 이동
n- n줄 만큼 뒤로 이동
( 현재 문장의 처음으로
) 다음 문장의 처음으로
{ 현재 문단의 처음으로
} 다음 문단의 처음으로



8 Spring Security - ajax 로그인 후 json응답받기(successHandler 구현)

|


[목차]

views


project 전체 코드 보기


[0] login ajax 구현

<script type="text/javascript" src="${pageContext.request.contextPath }/assets/js/jquery/jquery-1.9.0.js"></script>
<sec:csrfMetaTags />
<script> 
    var csrfParameter = $('meta[name="_csrf_parameter"]').attr('content')
    var csrfHeader = $('meta[name="_csrf_header"]').attr('content')
    var csrfToken = $('meta[name="_csrf"]').attr('content')  

    $(function(){
        $('#login-form').submit(function(event){
            event.preventDefault();
            var params = "email=" + $('#email').val() + "&password=" + $('#password').val()

            $.ajaxSetup({
                beforeSend: function(xhr) {
                    xhr.setRequestHeader(csrfHeader, csrfToken);
                }  
            })

            $.ajax({
                url : "${pageContext.request.contextPath}/user/auth",
                type : "post",
                dataType : "json",
                data : params,
                success : function(response) {
                    console.log(response);
                }, error : function(jqXHR, status, e) {
                    console.error(status + " : " + e);
                }

            });	 
        });
    });

</script>	

<body>
    
    ...
    
    <form id="login-form" name="loginform" method="post"
          action="${pageContext.servletContext.contextPath}/user/auth">
        <label class="block-label" for="email">이메일</label> 
        <input id="email" name="email" type="text" value=""> 

        <label class="block-label">패스워드</label> 
        <input id="password" name="password" type="password" value=""> 

        <label class="block-label">자동로그인</label> 
        <input id="remember-me" name="remember-me" type="checkbox">

        <c:if test="${result == 'fail' }"> 
            <p style="color: red;">로그인에 실패 했습니다.</p>
        </c:if>
        <input type="submit" value="로그인">
    </form>
    
    ...
    
</body>

위와 같이 ajax로 로그인을 구현했을 때, 응답부분에서 오류가 있다.

json형식의 응답이 오지않아 에러가 생겼다.

views

[1] successHandler 설정하기

WebSecurityConfigurerAdapter를 구현한 클래스의 configure(HttpSecurity http) 메소드에서 설정한다.

.successHandler(authenticationSuccessHandler())

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
        
    ...
        
    //
    // 2. 로그인 설정
    //
    .and()
    .formLogin()
    .loginPage("/user/login")
    .loginProcessingUrl("/user/auth")  // view form의 action과 맞아야함
    .failureUrl("/user/login?result=fail")
    .successHandler(authenticationSuccessHandler())
    .usernameParameter("email")
    .passwordParameter("password")
        
    ...
}

// AuthenticationSuccessHandler 등록
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler(){
    return new CustomUrlAuthenticationSuccessHandler();
}
}


[2] Json 결과를 만들 dto 구현

JSONResult.java

package com.cafe24.mysite.dto;

public class JSONResult {

    private String result; // success, fail
    private String message; // if fail, set
    private Object data; // if success, set data

    public static JSONResult success(Object data) {
        return new JSONResult("success", null, data);
    }

    public static JSONResult success(Object data, String value) {
        return new JSONResult("success", value, data);
    }

    public static JSONResult fail(String message) {
        return new JSONResult("fail", message, null);
    }

    private JSONResult(String result, String message, Object data) {
        this.result = result;
        this.message = message;
        this.data = data; 
    }

    public JSONResult() {
        super();
        // TODO Auto-generated constructor stub
    }


    public void setResult(String result) {
        this.result = result;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getResult() {
        return result;
    }

    public String getMessage() {
        return message;
    }

    public Object getData() {
        return data;
    }

    @Override
    public String toString() {
        return "JSONResult [result=" + result + ", message=" + message + ", data=" + data + "]";
    }

}


[3] CustomUrlAuthenticationSuccessHandler.java 구현

package com.cafe24.mysite.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

import com.cafe24.mysite.dto.JSONResult;


public class CustomUrlAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    protected final Log logger = LogFactory.getLog(this.getClass());

    private RequestCache requestCache = new HttpSessionRequestCache();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws ServletException, IOException {

        SavedRequest savedRequest = requestCache.getRequest(request, response);

        if (savedRequest != null) {
            requestCache.removeRequest(request, response);
            clearAuthenticationAttributes(request);
        }

        String accept = request.getHeader("accept");

        SecurityUser securityUser = null;
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            if (principal != null && principal instanceof UserDetails) {
                securityUser = (SecurityUser) principal;
            }
        }

        // 일반 응답일 경우
        if (accept == null || accept.matches(".*application/json.*") == false) {

            request.getSession(true).setAttribute("loginNow", true);
            getRedirectStrategy().sendRedirect(request, response, "/guestbook");  
            // 메인으로 돌아가! 
            // 이전페이지로 돌아가기 위해서는 인증페이지로 가기 전 URL을 기억해 놓았다가  
            return;
        }

        // application/json(ajax) 요청일 경우 아래의 처리!
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        MediaType jsonMimeType = MediaType.APPLICATION_JSON;

        JSONResult jsonResult = JSONResult.success(securityUser); 
        if (jsonConverter.canWrite(jsonResult.getClass(), jsonMimeType)) {
            jsonConverter.write(jsonResult, jsonMimeType, new ServletServerHttpResponse(response));
        }
    }

    public void setRequestCache(RequestCache requestCache) {
        this.requestCache = requestCache;
    }
}

일반 응답에서 로그인 전 페이지로 돌아가고싶다면, 이전 페이지의 정보를 저장했다가 보내주면 된다.

String referrer = request.getHeader("Referer");
request.getSession().setAttribute("prevPage", referrer);
getRedirectStrategy().sendRedirect(request, response, (String) session.getAttribute("prevPage"));


알맞은 JSON 응답을 위한 처리 부분

// application/json(ajax) 요청일 경우 아래의 처리!
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
MediaType jsonMimeType = MediaType.APPLICATION_JSON;

JSONResult jsonResult = JSONResult.success(securityUser); 
if (jsonConverter.canWrite(jsonResult.getClass(), jsonMimeType)) {
    jsonConverter.write(jsonResult, jsonMimeType, new ServletServerHttpResponse(response));


[4] 응답 확인하기

위의 코드 작성 후 다시 로그인 페이지에서 로그인을 하면 성공적으로 결과가 오는 것을 볼 수 있다.

views