2. linux에 Docker 설치하기
24 Nov 2019 | Docker linux[1] 리눅스 실행
리눅스 설치가 안되어있다면, 리눅스설치를 먼저 보고 설치를 해야한다.
(나는 우분투 설치를 참고해 우분투 16.04 버전을 설치했다.)
리눅스 설치가 안되어있다면, 리눅스설치를 먼저 보고 설치를 해야한다.
(나는 우분투 설치를 참고해 우분투 16.04 버전을 설치했다.)
도커는 윈도우용/macOS용에서 안정(stable)버전과 개발(edge)버전으로 나위어 제공된다.
윈도우용 도커를 실행하려면 가상화 기능이 필요하다.
가상화 기능 활성화 확인
작업관리자 > CPU탭 > 가상화 항복 ‘사용’ 확인
사용하지 않음으로 되어있다면 컴퓨터 바이어스(UEFI0) 설정에서 가상화 기능을 활성화 해야한다.
도커 다운로드 url에서 윈도우용 도커 안정버전을 받을 수 있다. 회원가입 후 아래의 버튼을 클릭하면 된다.
도커 인스톨러 파일을 다운로드 했다면 Hyper-V 기능을 활성화 하고 확인버튼을 눌러 설치 완료 후 윈도우를 재시작한다.
도커가 실행되고 작업 표시줄에 Docker is running이라는 메세지가 나타나면 정상적으로 설치된 것이다.
도커가 실행된 상태에서 PowerShell(혹은 gitbash)을 통해 docker version
명령어 실행시 현재 도커버전 확인이 가능하다.
간혹 윈도우에서 메모리 확보 실패 등 이유로 실행 실패하는 경우가 있는데, 서비스 재시작 혹은 설정에서 CPU 혹은 메모리 할당을 줄여야한다.
도커 아이콘 > 오른쪽마우스 클릭 > settings 클릭
Gerneral 탭에서 ‘Start Docker Desktop when you log in’ 체크를 하면 운영체제 로그인 시 도커가 자동으로 실행된다.
Gerneral 탭에서 ‘Automatically check for updates’를 체크하면 최신 버전 출시만 알려줄 뿐 강제 업데이트가 일어나진 않는다.
‘Proxies’ 탭에서 원격 도커 저장소에서 도커 이미지를 받아올 떄 사용할 HTTP/HTTPS 프록시를 설정할 수 있다. 제한된 대상에만 접근을 허용하는 프라이빗 저장소로부터 이미지를 받아와야하는 경우에는 ‘Manual proxy configuration’을 선택해서 설정하면 된다.
‘Daemon-Basic’에서 ‘Insecure registries’에서 비보안 도커 레지스트리를 등록할 수 있다. 도커 레지스트리는 기본적으로 HTTPS통신을 권장하며 HTTP통신을 사용하려면 별도로 설정해줘야한다.
‘Daemon-Advanced’에서는 JSON포맥으로 도커를 설정할 수 있다. 도커 설정화면에 나오지 않는 사항을 변경하려면 JSON문자열을 수정하면 된다.
ifconfig -a
ip address = 192.168.1.52
if config eth0 down
: 중지
if config eth0 up
: 작동
ifconfig
명령어를 통해 현재 리눅스에서 사용중인 ip 주소를 알아야 한다.
넷마스크 란 ?
- 하나의 네트워크를 몇 개의 네트워크로 나눠 사용할 때 나눠진 각각의 네트워크를 구분하기 위해 사용하는 특수한 bit이다.
- IP 주소에 대한 네트워크 아이디와 호스트 아이디를 구분하기 위해서 사용된다.
- 정확한 표현은
서브넷 마스크(Subnet Mask)
이다.
게이트웨이 란?
서로 다른 네트워크를 연결해주는 역할을 하는 특정 장비나 특정 호스트를 의미한다.
서버를 restart하는 방법 3가지
ifconfig eth0 down
ifconfig eth0 up
/etc/init.d/network restart
sync
sync
sync
reboot
1. 네트워크 설정 파일 수정하기
vi /etc/sysconfig/network-script/ifcfg-eth0
1, BOOTPROTO=static 으로 변경
2, 시작하기 전 알아야 하는 설정 추가
2. 서버 restart
3. Xshell 설정
XShell에서 open
명령어를 쳤을 때, 바로 연결할 수 있게 설정하기.
새로만들기 = Alt + N
[TOC]
vi {파일}
명령어 입력 후 사용할 수 있는 단축키 정리손에 익지 않아서 간단한 것들만 자주 쓰게 된다,,,
단축키 | 수행작업 |
---|---|
shift + g (=window end 키) | 커서 맨뒤로 |
gg (=window home키) | 커서 맨앞으로 |
yy | 복사(해당줄에 커서 후 yy) |
p, P | 붙여넣기(해당줄에 커서 후 p or P) |
dd | 줄 지우기(한 줄 삭제) |
dw | 단어 지우기 |
u | 방금 수행 되돌리기 |
shift + u | 해당 줄만 수행 되돌리기 |
shift + j | 현재줄과 다음줄 연결 |
단축키 | 수행작업 |
---|---|
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 | 현재 줄과 다음 줄 연결 |
. | 바로 이전에 수행한 명령 재 실행 |
~ | 현재 커서위치의 한 문자를 소문자 혹은 대문자로 전환 |
저장 : 저장하거나 종료하려면 “명령모드”로 돌아와야 한다.
ex) 편집 후 ESC
키를 눌러 편집모드가 아닌 명령모드 상태로 아래의 명령어를 쳐야한다.
명령어 | 수행작업 |
---|---|
:w | 현재의 파일명, 상태로 파일 저장 |
:w 파일명 | 지정한 파일명, 상태로 파일 저장 |
종료 명령 : 저장 후 종료 또는 그냥 종료
명령키 | 수행작업 |
---|---|
:q | 작업 내용을 저장했으면 vi종료, 안했으면 종료 불가 |
:q! | 작업 내용을 저장하지 않고 강제로 vi 종료 |
:wq | 작업 내용을 저장한 후 vi 종료 |
:wq 파일명 | 작업 내용을 지정한 파일명으로 저장한 후 vi 종료 |
xx(shift+zz) | 작업 내용을 저장한 후 vi 종료 |
편집 모드에서 마우스로 커서를 움직일 수 없다.
만약 마우스로 움직이고 싶다면, ESC키를 눌러 명령모드로 바꾼 뒤 커서를 움직여야 한다.
화살표 혹은 h, j, k, l 키로 움직일 수 있다.
지정한 곳으로 이동하기
단축키 | 수행작업 |
---|---|
:n 또는 nG | 줄 번호 n 위치로 |
:$ 또는 G | 파일의 끝 줄로 이동 |
n+ | n줄 만큼 앞으로 이동 |
n- | n줄 만큼 뒤로 이동 |
( | 현재 문장의 처음으로 |
) | 다음 문장의 처음으로 |
{ | 현재 문단의 처음으로 |
} | 다음 문단의 처음으로 |
<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형식의 응답이 오지않아 에러가 생겼다.
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();
}
}
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 + "]";
}
}
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));
위의 코드 작성 후 다시 로그인 페이지에서 로그인을 하면 성공적으로 결과가 오는 것을 볼 수 있다.