먼제 AWS에 인스턴스를 만들고 난 후를 가정한다

AWS에서 ec2인스턴스를 아직 못 만들었다면 이 글을 읽고 따라하길 바란다 

 

AWS 인스턴스 개념잡기

https://youtu.be/Pv2yDJ2NKQA

출처 : 생활코딩

 

실제로 배포할때 따라했던 AWS셋팅 

 

https://youtu.be/eLa6Ud5RYR8?t=1346 

 

이후 3강에 puTTY를 이용한 ubuntu 접속까지.

https://youtu.be/S5ETW2zCbuA

 

이 강의 5개를 (6강은 docker) 2번 정독 했다.

출처:데어 프로그래밍

 

데어 프로그래밍

getinthere@naver.com

www.youtube.com

 

 

자 AWS EC2 셋팅과 인스턴스를 설정했고 puTTY를 이용해서 ubuntu에 접속했다면, 이제 본격적으로 ubuntu에서 war파일을 배포할 준비가 끝났다는 것이다.

프로젝트 mvc : SPRING4
언어: JAVA
Cloud: AWS/ EC2/ UBUNTu
WAS : Tomcat9
DB: MARIADB

 

 

 

고생길 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏ

 

 

 

 

첫 화면

이 떻다면 ubuntu를 입력해주고 시작하자.

 

본인은 5일동안 하루에 3시간 자며 개고생했으며 war 배포방법을 여러가지로 접했는데 모든 방법과 경험을 취합해서 하나의 메인 스트림으로 쭉 알려드리려고자 한다.

 

 

 

ubuntu에 war파일을 이용하여 배포하기 위해 해야 할것은

 

  1. jre 설치 
  2. jdk 설치
  3. JAVA_HOME 환경변수 설정
  4. tomcat9 설치 (apt-get install tomcat9
    • tar.gz 다운 방식은 해봤는데 초큼.... 파일 접근 권한 설정이 신경쓰여서...
  5. mysql설치
  6. war 배포(git clone, tomcat9-manager)

 

순서대로 잘따라오길 바란다!

 

1. jre 설치 

 

$ sudo apt-get update

리파지토리 업데이트

 

$sudo apt-get upgrade

리파지토리 업데이트

 

$sudo dpkg-reconfigure tzdata

날짜 시간변경 asia 엔터 ->seoul 엔터

 

 

$sudo apt-get install openjdk-8-jre-headless

jre 설치

 

 

2. jdk 설치

사실 리눅스에는 open jdk가 별도 내장되어 있어서 설치가 필요없긴하다 그래도 모르니

java -version 검색후 안뜨면 ㄱ

$sudo apt-get install openjdk-8-jdk

 

잘 설치 되어있는지 확인:

$java -version

$javac -version

둘 다 입력했을때 버전이 잘뜨면 됩니다. (jdk=java, jre = javac)

 

 

 

 

3. JAVA_HOME 환경변수 설정

 

JAVA_HOME 즉 자바 경로을 알려주기 위해 설정을 해야하는데 

$sudo nano /etc/profile

에 하는게 좋다 nano는 메모장 마치 txt 파일 작성을 편하게 해줌

제일 밑 하단에 

#JAVA
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64


#path
export PATH=$PATH:$JAVA_HOME/bin

를 추가해준다 (나중에 톰캣 설치하면 catalina_home이랑 path도 설장 할 것이다.)

 

$ source /etc/profile 입력 하여 즉시 적용 필수

 

JAVA_HOME의 경로는  환경마다 다를 수 있는데 수 많이 해본결과 apt-get intall로 설치하거나 리눅스 내장 경로는 저것일 것이다 혹시 모르니 경로 검색은

$sudo find / -name java-8-openjdk-amd64

하면 경로가 뜸 그걸 /bin/java 파일 전 경로까지 입력

 

 

4. tomcat9 설치

wget 으로 tar.gz 파일 받아서 war하려 했지만 추후 404에러 크리로 정식 루트를 타서 설치하려고함

$sudo apt-get install tomcat9
$sudo apt-get install tomcat9-admin (톰캣 매니저 사용위함)

y/n 뜨면 y눌러서 계속 설치 

 

다 설치 되었으면 CATALINA_HOME 환경변수 설정

$sudo nano /etc/profile

JAVA_HOME 밑에
#Tomcat9 Home
export CATALINA_HOME=/usr/share/tomcat9

#path에 추가 
export PATH=$PATH:$CATALINA_HOME/bin

 

/etc/profile 최하단 전문

#JAVA
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64


#Tomcat8 Home
export CATALINA_HOME=/usr/share/tomcat9


#path
export PATH=$PATH:$JAVA_HOME/bin
export PATH=$PATH:$CATALINA_HOME/bin

 

5. mariaDB 설치

 

 

$sudo apt-get install mariadb

 

마리아 db 실행 코드

$sudo mysql -r root -p 엔터 두번

root계정을 들어가는건데 처음엔 root로 들어가서 유저 설정 후 설정 유저로 들어가는걸 추천

설치 직후엔 root 계정 비번 설정을 안했기 때문에 password 요구해도 엔터 치면 넘어가짐

 

- 유저 설정(나중에 heidiSQL로 외부접속 하려면 필수 애초에 root로 접근 비추)

use myslq;

create user '유저명'@'%' identified by'비번';

%는 외부에서 접근 허용 하겠다는 말(내부만 가능하게 하려면 % -> localhost)

 

이제 권한을 주자 

GRANT ALL privileges ON DB명.* TO 유저명@'%';

 

본인 프로젝트에 맞는 sql를 사용하여

create database OO;를 해주자

 

6. war 프로젝트 파일 배포

 

방법은 3가지

git clone을 이용하여 파일 받아서 배포 

filezilla 사용

tomcat9-manager 사용하여  deploy

본인은 마지막 방법 사용 할 것이다.

 

이제 톰캣을 구동 할 것인데 톰캣 구동시 항상

$sudo tail -f /var/log/tomcat9/catalina.날짜.log

를 실행해둔 putty 창을 하나 띄워놓고 하길바란다 실시간 로그 띄워서 어디서 에러 터트리는지 알아야함.

permision denied 뜨면  cd /var, cd log, cd tomcat9 으로 한칸씩 접속하다 보면

아마 tomca9 접근할때 permision denied 가 뜰 것이다. 그럴때 

$sudo chmod 755 tomcat9 하면 접근가능

거기서 $sudo tail -f catalina.날짜.log 를 치면 댐

 

 

 

톰캣 start stop restart


$sudo service tomcat9 start
$sudo service tomcat9 stop
$sudo service tomcat9 restart

$sudo service tomcat9 start 시작해서

IP:8080 으로 접속 기본 index.html이 출력 될것이다. (이건 webapps 안 root폴더안에 있는 놈)

거기서 밑에 manager 링크를 클릭하면

 

IP:8080/manager/html 으로 가는데 404에러를 터트릴것

이걸 해결하기위해 tomcat9 폴더안 tomcat-users.xml를 수정해야한다

 

$cd /var/lib/tomcat9/conf 으로 접근
permision 또뜨면 한칸씩 올라가면서 
$sudo chmod 755 파일명 으로 뚫어주자

conf 폴더안 tomcat-users.xml 수정

$sudo nano tomcat-users.xml

<tomcat-users>
	<role rolename="manager-gui"/>
	<role rolename="manager-script"/>
	<role rolename="manager-jmx"/>
	<role rolename="manager-status"/>
	<role rolename="admin-gui"/>
	<role rolename="admin-script"/>
	<user username="admin" password="admin" 
	<roles="manager-gui,manager-script,
	manager-jmx,manager-status,admin-gui,admin-script"/>   ==> 추가
</tomcat-users>

설정후 톰캣 재시작 $sudo service tomcat9 restart

 

톰캣 가동후

IP:8080/manager 로들어가면 아이디 비밀번호 치라고 하는데 본인이 설정한 아이디 비번 치면댐

초기 설정 안했다면 admin/admin 으로 위에 설정하였다.

 

이런 화면이 뜬다면 밑에 war로 추출한 프로젝트를 선택하여 Delploy 시키면된다

선택한 war프로젝트가 자동으로 webapps 안에 위치하게 해줌

 

위에 리스트에 추가되면서 Running이 true로 바뀐다면 오른쪽 탭에 start를 눌러준다.

 

끘!!!!!

 

ps. 톰캣 가동후 계속 실시간 로그를 봐야한다 에러터지면 하나하나 검색하여 수정해줘야 함 start 눌러서 IP:8080/프로젝트 접글 할 때까지 로그에서 눈 떼지말라

PS. css 나 js가 먹히지 않고 로딩이 되었다면 호출되는 css,js 경로가 : /프로젝트명/경로/이름.css,js 에서 /프로젝트명 이빠져서 그런것일 수 도있다. 이럴땐 url 접근 경로를 바꾸기 위해 tomcat9/conf/server.xml안 <host><Context path="/" docBase="프로젝트명" reloadable="false"/></host>로 수정하자. 수정 톰캣 재실행 하면 IP:8080으로 접근 가능하면 바로 프로젝트가 뜰것

PS. 프로젝트404에러가 터지면 프로젝트 webapps안에 프로젝트 파일의 tomcat접근 권한이 있는지 확인해보자

cd /var/lib/tomcat9/webapps 로가서 ls -al를 치면 본인 프로젝트 파일 소유가 tomcat9 tomcat9이 되어 잇어야 한다.

'프로젝트' 카테고리의 다른 글

To do list 만들기(1)  (1) 2021.05.07

DB와 연결하여 이클립스로 게시판을 만드는 연습하고 있다가, 친구가 to do list을 먼저 만들고 있길레 옆에 가서 지켜보던중 처음써보는 코드가 있길레 연습을 하기로 했다.

 

사용 언어 : JavaScrpit/Java
태그 lib : jstl

 

결과 화면.png

  • 원하는 기능
    • 해 야 할 일을 넣으면 자동으로 목록 추가
    • 한 페이지 안에서 페이지 변환 없이 모든 기능 수행 ★★★
    • BD와 연동 하여 데이터 보존
    • 수정 누르기전엔 readonly 수정 누르면 readonly 해제

한페이지 안에서 페이지 변환 없이 수행 한다는 말은 메인.jsp와 연결된 메인 서블렛과 각각 기능(수정, 삭제)을 가지고 있는 서블렛 하나씩이 메인.jsp으로만 포워딩이 되야 한다.

설계또.png

main.jsp

전체코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인</title>
</head>
<body>
    <div>
        <h1>To do List</h1>
    </div>
    <!-- 할 일 추가 문단-->
    <form action="/todolist" method="post">
        할 일 : <input type="text" name="todo">
        <button type="submit">추가</button>
        <!-- <input type="submit" value="추가"> -->

    </form>

    <table>
        <tr>
            <th>No</th>
            <th>할일</th>
        </tr>
    </table>

    <!--ForEach문으로 리스트 뽑아오기 -->

    <!-- table태그 안엔 form이 존재 할 수 없으니 form으로 table을 감싸고 onsubmit으로
    데이터 보내기 여부 판단후 전송-->
    <c:forEach var="list" items="${list}">
        <form action="/todoUplist?no=${list.iboard }" method="post"
            onsubmit="return changeReadonly(${list.iboard })">
            <input type="hidden" value="${list.iboard}" name="no">
            <table>
                <tr>
                    <td>${list.iboard }</td>
                    <td><input type="text" name="ctntbox"
                        id="ctntbox${list.iboard }" value="${list.ctnt }" readonly></td>
                    <td><button type="submit" id="btn${list.iboard }">수정</button>
                    <td><button onclick="location.href='/del?no=${list.iboard }'">삭제</button></td>
                </tr>
            </table>
        </form>
    </c:forEach>

    <!-- readOnly 전환 여부 스크립트 -->
    <script>
        function changeReadonly(i) {
            var txt = document.getElementById('ctntbox'+i);
            const btn = document.getElementById('btn'+i);

            if (btn.innerText === '수정'){
                btn.innerText = '완료';
                txt.readOnly = false ; 
                return false;

            } else {
                btn.innerText = '수정';
                txt.readOnly = true ;
                return true ;
            }

        }

    </script>
</body>
</html>

전체를 한번에 이해 하려하지 말고 한줄씩, 혹은 한 문단씩 이해 하려고 해보면 될 뜻 하다. 아마 그럴 것이다.

선생님.. 코딩을 더 잘하고싶어요..

그렇다. 막상 전체 내가쓴 내 코드를 보아도 제대로된 방법인지, 옳바른 방법인지, 유동성과 확장성은 충분한지

잘모르겠다

어찌되었든 결과는 만들어 졌으니

하나하나 해부해보자.

<form action="/todolist" method="post">
        <div>
        해 야 할일 : <input type="text" name="todo"> <input type="submit"
                value="작성">
        </div>
</form>

해 야 할일 문단은 최상단에 위치해야 하고 주위에 오브젝트가 있으면 눈에 띄지 않으므로 <div>

로 감싸주었고

Input 태그, 타입은 text, name은 todo의 이름으로 form태그에 의해 /todolist로 브라우저를 통해 post 방식으로 보내 주었다. 즉 해 야 할일 들은 추가 될 때마다 /todolist에 post 방식으로 보내주었고 이걸 todolist가 주소창에 들어 왔을때

반응 하는 Servlet이 처리 할 것이다.

 

 

 

<div>
         <!-- forEach으로 반복 수행-->
    <c:forEach var="list" items="${list }">

        <!--readOnly 전환과 동시에 수정시 데이터 전송-->
        <form action="/todouplist?no=${list.itodo }" method="post"
            onsubmit="return mod(${list.itodo})">

        <!-- 리스트 노출 부문-->
            <table>
                <tr>
                    <td>${list.itodo}</td>
                    <td><input type="text" name="r_ctnt"
                        id="r_ctnt${list.itodo }" value="${list.ctnt }" readonly></td>

                    <td><input type="submit" id="r_btn${list.itodo }" value="수정"></td>
                    <td><button type="button"
                    onclick="location.href='/del?no=${list.itodo}'">삭제</button></td>

                </tr>

            </table>
        </form>
    </c:forEach>
</div>

이제 DB에 저장된 리스트들을 뽑아야 하는데, DB에 저장된 데이터 횟수만큼 forEach문을 돌려서 리스트를 뽑게 하였다.

jstl도움을 받아서 list라는 변수이름으로 ${list}를 정의하였고

해 야 할일이 저장되어 있는 ArrayList를 말한다

jstl에 의해 list.todo, list.ctnt만 적어도 리스트 객체에 저장되어 있는 todo 객체를 가져올수 있는 것이다.

list는 ArrayList를 가르키고 있고 ArrayList 각 방들은 추가된 해 야 할일들 하나씩 가르키고 있다.

 

readonly를 true, false로 변환시키는 매소드와

1번째 수정 버튼 누를시 글자를 완료 번경 되고 한번더 눌러야 수정된 내용을 전송하는 매커니즘이 필요하다.

이 방법을 쓰기위해 readonly를 true, false를 만드는 매소드에 onclick을 한번 더 넣어야 되나 시도해보았다. 물론 처참히 실패 했지만.

이 매커니즘을 만들기 위해서는 두가지 문제가 있다.

  • table태그 안에 form가 존재할 수 없다.
  • 수정 버튼 클릭시 바로 form로 인해 데이터가 전송이 돼서는 않되고 두번째 클릭때 데이터를 전송해야 한다

 

이를 해결하기 위해 form 태그를 밖으로 꺼내어 table태그를 감싸게 만들었고, 두번째 문제를 해결하기 위해

onsubmit 태그를 사용 한것이다.

 

onsubmit : "return ~" 양식 제출 이벤트가 발생 되었을때 return 값이 ture일때 전송한다.
return 값이 false면 전송하지 않는다.

 

 <form action="/todouplist?no=${list.itodo }" method="post"
            onsubmit="return mod(${list.itodo})">

 

onsubmit 태그를 이용해 첫번째 수정 onclick 시 value값, readonly 값를 바꿔주는 mod 매서드를 실행 한 뒤 그 return 값을 false로 해서 전송하지 않는다. 두번째 클릭시mod 매서드의  return 값을 ture 줘서 그때야 수정된 내용을 전송하는 것이다!!!

<script>
	function mod(i){
		/*ctnt = 내용, btn= 버튼, i = list.itodo(글번호) */
        var ctnt = document.getElementById('r_ctnt'+i);
	var btn = document.getElementById('r_btn'+i);
		
		if(btn.value ==='수정'){
			btn.value = '저장';
			ctnt.readOnly = false;
			return false;
		} else {
			btn.value = '수정';
			ctnt.readOnly = true;
			return true;
		}
		
	}	

</script>

mod(i), 버튼+i 그리고 ctnt+i 하나하나 에게 접근하기 위해 forEach이 반복 될때마다 자동적으로 부여되고, 1씩 늘어나는 itodo값을 DB에서 설정한다. 만약 i= 글번호를 넣어 주지 않는다면 어떤 글을 수정하는지 삭제하는지 모를 것이다 컴파일러가 모를 것이다.

 

jsp끝!

+ Recent posts