[JS] ES6 - Promise

[JS] ES6 - Promise

이채현

Promises

async

자바스크립트는 순차적으로 처리되는게 아니라 한꺼번에 실행된다. ⇒ 자바스크립트의 비동기성(async)

이벤트 루프에서 비동기적으로 실행시킨다.

Promise

Promise는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.

내가 아직 모르는 값이랑 같이 일하게 해준다

금방 끝나진 않겠지만 곧 오면 이걸 가지고 작업할 게 표시 해주는 것

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const promiseTest1 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "Test Pass");
});

// setInterval(console.log, 1000, promiseTest1);
promiseTest1.then((value) => console.log(value));

const promiseTest1 = new Promise((resolve, reject) => {
setTimeout(reject, 3000, "Test Fail");
});

// setInterval(console.log, 1000, promiseTest1);
promiseTest1
.then((value) => console.log(value))
.catch((error) => console.log(error));

Chaining Promise

.then().then()…. 할때 리턴 필요

1
2
3
4
5
6
7
8
9
10
const promiseTest2 = new Promise((resolve, reject) => {
resolve(2);
});

promiseTest2
.then((number) => {
console.log(number * 2);
return number * 2;
})
.then((otherNumber) => console.log(otherNumber * 2));

Propmise.all

Promise.all은 주어진 모든 Promise를 실행한 후 진행되는 하나의 Promise를 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Promise.all
*/
const p1 = new Promise((resolve) => {
setTimeout(resolve, 5000, "first");
});

const p2 = new Promise((resolve) => {
setTimeout(resolve, 1000, "second");
});

const p3 = new Promise((resolve) => {
setTimeout(resolve, 3000, "third");
});

const motherPromise = Promise.all([p1, p2, p3]);

motherPromise
.then((values) => console.log(values))
.catch((err) => console.log(err));

// 모든 프로미스가 resolve 해야지 출력
// 5초후 마지막 first 끝나야 최종출력
// 중간에 reject 뜨면 바로 중단

Promise.race

기본적으로 promise all이랑 같지만 하나만 resolve 되거나 reject하면 된다. 가장 빨리 리턴 되는 걸로 결정, 부모프로미스를 차지하고 그 값 하나 리턴함

1
2
3
4
5
6
7
8
9
10
/**
* Promise.race
*/
const motherPromise2 = Promise.race([p1, p2, p3]);

motherPromise2
.then((values) => console.log(values))
.catch((err) => console.log(err));

// second

finally

뭘하든 마지막에 실행된다. 보통 작업이 다 끝나고 로딩 끝낼 때 쓴다.

1
2
3
4
5
6
7
8
/**
* Finally
*/
const p1 = new Promise((resolve) => {
setTimeout(resolve, 3000, "first");
})
.then((value) => console.log(value))
.finally(() => console.log("I'm done"));
[JS] ES6 - For

[JS] ES6 - For

이채현

For

forEach

1
2
3
4
5
6
7
8
9
const friends = ["me", "you", "nico"];

const addHeart = (current, index, array ) => ( console.log(current, index, array));

friends.forEach(addHeart);
// 파라미터 첫번째로 값을 주고 두번째로 인덱스를 주고 세번째로 현재 배열을 준다
// me 0 ["me", "you", "nico"]
// you 1 ["me", "you", "nico"]
// nico 2 ["me", "you", "nico"]

for…of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (const friend of friends) {
// 장점 1) const, let 뭐로 할건지 결정가능, forEach에서는 안됨
console.log(friend); // 모두다 출력됨
}

for (const char of "strings") {
console.log(char); // s t r i n g s 출력
}
// 장점 2) iterable한 모든것에서 작동한다

for (const friend of friends) {
if (friend === "steve") {
break;
} else {
console.log(char); // "me", "you", "nico" 이렇게만 출력
}
}
// 장점 3) 루프를 멈출수가있음!, 최고장점
[JS] ES6 - Rest and Spread

[JS] ES6 - Rest and Spread

이채현

Rest and Spread

Spread

기본적으로 변수를 가져와 풀어 해쳐 전개해놓는 것.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Spread
*/
const friends = [1, 2, 3, 4];

console.log(friends); // [1, 2, 3, 4]
console.log(...friends); // 1 2 3 4

const family = ["a", "b", "c"];
console.log(friends + family); // 1,2,3,4a,b,c
console.log([friends, family]); // [ [ 1, 2, 3, 4 ], [ 'a', 'b', 'c' ] ]
console.log([...friends, ...family]); // [ 1, 2, 3, 4, 'a', 'b', 'c' ]
// spread를 통해 모든 요소를 담고 있는 하나의 object를 얻을 수 있다.
// array.push()를 이용하지 않고 값을 추가하여 새로운 객체를 만든다.
const newFriends = [...friends, 5, 6, 7];
console.log(newFriends); // [ 1, 2, 3, 4, 5, 6, 7]

const admin = {
username: "admin",
};
console.log({ ...admin, password: 123 }); // { username: 'admin', password: 123 }
// 조건식
// lastName을 입력받았을 때 값이 있을 때만 객체에 넣어주기
const lastName = prompt("Last name: ");
const person = {
username: "person",
age: 24,
...(lastName !== "" && { lastName }), // spread로 전개하려면 데이터가 object여야하므로, 중괄호로 감싸줌
// lastName: lastName !== "" ? lastName : undefined,
};
console.log(person);

Rest Parameters

끝없는 인자를 받아 볼때 유용하게 이용할 수있다

spread는 죄다 펼쳐 확대시키는 것이고, ****rest는 하나에 담아서 축소시키는것

어디에 들어가느냐에 따라 spread와 rest(parameter부분에 들어가면 )로 갈릴수있음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const infiniteArge = (...kimchi) => console.log(kimchi);

infiniteArge("1", 2, true, "lalala", [1, 2, 3, 4]);
// 전부 배열에 넣어서 출력된다.

const bestFriends = (firstPotato, ...potatos) => {
console.log(`he is ${firstPotato}`);
console.log(potatos);
}

bestFriends("nico", "lynn", "steve", "flynn");
// he is nico
// ["lynn", "steve", "flynn"]
// 이렇게 출력된다

Rest + Spread + Destructure Magic

object를 지우거나 정리할 때 유용하다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const user = {
name :"nico",
age:24,
password : 12345
};

const killPassword = ({password, ...rest}) => rest; // destructure + rest
// destructuring을 통해 user의 password를 가져오고, 나머지를 rest에 저장

const cleanUser = killPassword(user)
console.log(cleanUser) // {name:"nico", age:24} 출력한다

const setCountry = ({ country = "KR", ...rest }) => ({ country, ...rest });
// default 설정 + rest + spread

console.log(setCountry(user));

// {country : "KR", name :"nico", age:24, password : 12345} 출력
[JS] ES6 - Destructuring

[JS] ES6 - Destructuring

이채현

Destructuring

destructuring(비구조화)는 object나 array 등 안의 변수를 바깥으로 끄집어내는 것

Object Destructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Object Destructuring
*/
const settings = {
notifications: {
follow: true,
alerts: true,
unfollow: false,
},
color: {
theme: "dakr",
},
};

if (settingss.notifications.follow) {
// send email
}

// 기존에는 위와 같이 사용했다. 보기에 매우 불편하다.
// 만약 follow라는 값이 없느면 undefined오류가 발생할 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
// 기본적으로 settings를 열어 notifications에 접근하여 follow를 가져오는 것

const { notifications: { follow = false } = {}, color } = settings;
// settings에 notifications가 없으면 {}, notifications에 follow가 없으면 false로
// default 값 세팅을 해준다.

console.log(follow); // true
console.log(color); // { theme: 'dark' }

// 이 때 notifications는 변수가 아님 -> notifications를 console.log에 찍으면 is not defined 오류 발생
// 이런 방식은 큰 Object에서 특정 변수나 그 안에 속한 작은 Object에 접근할 수 있도록 해주는 것
//

Array Destructuring

array destructuring은 보통 가져온 정보를 조작하기 않을 때 쓰기 좋다.

1
2
3
4
5
6
7
8
9
10
/**
* Array Destructuring
*/
const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

const [mon, tue, wed, , , , sun, aaa = "AAA"] = days; // ,,,은 skippin

// mon 에는 "Mon" , tue에는 "Tue", wed 에는 "Wed" sun에는 "Sun"이 들어가있음
// aaa는 AAA
console.log(sun);

Renaming

api등에서 받아온 데이터의 이름이 별로일 때 바꿔보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Renaming
*/

const settings = {
color: {
chosen_color: "dark",
},
};

const {
color: { chosen_color: chosenColor = "light" },
} = settings;
// :를 붙혀 새로운 변수를 생성하고 그 변수에 값을 담는다.

-----------------

let chosenColor = "blue"; // 변수가 미리 있다면

console.log(chosenColor); // blue

({
color: { chosen_color: chosenColor = "light" },
} = settings);
// 위와 같이 적어 이미 정의가 되어있는 choseColor의 값을 업데이트한다.

console.log(chosenColor); // dark

Function Destructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* Function Destructuring
*/
function saveSettings(followAlert, unfollowAlert, mrkAlert, themeColor) {} // argument가 너무 길다

function saveSettings({ follow, alert, color = "blue" }) {
console.log(color); // green
}

saveSettings({
follow: true,
alert: true,
mkt: true,
color: "green",
});

----------- 더 간단히..

function saveSettings({ notifications, color: { theme = "blue" } = {} }) {
console.log(theme); // blue
}

saveSettings({
notifications: {
follow: true,
alert: true,
mkt: true,
},
// color: { theme: "green" },
});

Value shorthands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const follow = checkFollow();
const alert = checkAlert();

const settings = {
notifications: {
follow: follow,
alert: alert,
},
};

// 위 아래 같다. key와 value가 같다면...

const settings = {
notifications:{
follow,
alert
}
}
[JS] ES6 - Array

[JS] ES6 - Array

이채현

Array

Array.of()

무엇이든 Array로 만들어준다.

1
2
3
4
// Array.of()
const alphabet = ["a", "b", "c", "d"];
const alphabet = Array.of("a", "b", "c", "d")const alphabet = Array.of("a", "b", "c", "d", 1, 2, 3);;
console.log(alphabet);

Array.from()

Array.from(array같이 생긴 것)

😠 querySelectorgetElementbyClassName으로 엘리먼트 찾으면 array 같지만 아닌 다른 저장 포맷으로 저장된다

array-like object를 array로 바꿔준다.

1
2
3
4
5
6
7
8
9
10
11
const buttons = document.getElementsByClassName("btn");
console.log(buttons);
// buttons는 Array가 아니기 때문에
// 아래와 같이 forEach를 사용할 수 없다.
buttons.forEach((button) => {
button.addEventListener("click", () => console.log("I ve been clickeds"));
});
----------------
Array.from(buttons).forEach((button) => {
button.addEventListener("click", () => console.log("I ve been clickeds"));
});

Array.find()

Array.prototype.find() - JavaScript | MDN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Array.find()
*/
const friends = [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
];

const target1 = friends.find((friend) => friend.includes("@yahoo.com"));
// 조건을 넣어주면 forEach를 돌리면서 그에 맞는 값을 리턴해준다
// 찾은 첫번째 값만 반환해준다
// 없으면 undefined반환한다
console.log(target1);

Array.findIndex()

Array.prototype.findIndex() - JavaScript | MDN

1
2
3
4
5
6
7
8
9
10
/**
* Array.findIndex()
*/
const target2 = friends.findIndex((friend) => friend.includes("@yahoo.com"));
// 인덱스가 필요할때!
// 없으면 -1반환한다
console.log(target2);
const userName = friends[target2].split("@")[0];
const email = "yahoo.com";
console.log(`${userName}@${email}`);

Array.fill()

Array.prototype.fill() - JavaScript | MDN

1
2
3
4
5
if (target2 !== -1) {
friends.fill("*".repeat(5), target2 + 1);
// target부터 모든 변수는 다 채울값으로 채워줌
}
console.log(friends);
[JS] ES6 - Strings

[JS] ES6 - Strings

이채현

Strings

Template Literal

variable을 가진 문자열을 쓰는 방법에 대한 개선

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const sayHi = (aName = "anon") => {
return "Hello " + aName;
};

==>
/**
* 변수
*/
const sayHi = (aName = "anon") => {
return `Hello ${aName}`;
}
/**
* 함수
*/
const add = (a, b) => a + b;
console.log(`hello how are you ${add(6, 6)}`);

HTML Fragments 1

1
2
3
4
5
6
7
8
9
10
11
const wrapper = document.querySelector(".wrapper");

const addWelcome = () => {
const div = document.createElement("div");
const h1 = document.createElement("h1");
h1.innerText = "Hello";
div.append(h1);
wrapper.append(div);
};

setTimeout(addWelcome, 1000);

1
2
3
4
5
6
7
8
const addWelcome = () => {
const div = `
<div class="hello">
<h1>Hello</h1>
</div>
`;
wrapper.innerHTML = div;
};
  • template literal은 ``` … space를 고려한다.

HTML Fragments 2

1
2
3
4
5
6
7
8
9
10
const alphas = ["A", "B", "C", "D"];

const ul = document.createElement("ul");
const list = `
<h1>Alphabet</h1>
<ul>
${alphas.map(alpha => `<li>${alpha}</li>`).join("")}
</ul>
`;
wrapper.innerHTML = list;

Cloning Styled Components

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* Cloning Styled Components
*/

const styled = (aElement) => {
const el = document.createElement(aElement);
return (args) => {
const styles = args[0];
el.style = styles;
return el;
};
};

// 아래 코드는 함수를 두변 연속 호출 하는 꼴이기 때문에
// 위 함수에서 클로저로 함수를 또 한번 호출할 필요가 있다.
const title = styled("h1")`
background-color: red;
color: blue;
`;

const subTitle = styled("span")`
color: green;
`;

title.innerText = "We just cloned";
subTitle.innerText = "Styled Components";

document.body.append(title, subTitle);

More String Improvements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* includes()
*/
const isEmail = (email) => email.includes("@");
console.log(isEmail("[email protected]")); // true
console.log(isEmail("myEmail")); // false

/**
* repeat()
*/
const CC_NUMBER = "6060"; // ************6060로 보여주기
const displayName = `${"*".repeat(10)}${CC_NUMBER}`;
console.log(displayName); // **********6060

/**
* startsWith(), endsWith()
*/
const name = "Mr. abc";
console.log(name.startsWith("Mr")); // true
console.log(name.endsWith("abc")); // true
[JS] ES6 - Functions

[JS] ES6 - Functions

이채현

Functions

Arrow Functions

기존 함수의 모습을 개선했다.

기존 함수

1
2
3
4
5
6
7
8
9
10
11
function Hello() {
return "hi";
}
console.log(Hello());

const names = ["kim", "lee", "park"];

const hearts = names.map(function (name) {
return name + " ❤️";
});
console.log(hearts);

Arrow Functions(1) - base

1
2
3
4
5
6
7
8
9
10
11
const Hello = () => {
return "hi";
};
console.log(Hello());

const names = ["kim", "lee", "park"];

const hearts = names.map((name) => {
return name + " ❤️";
});
console.log(hearts);

Arrow Functions(2) - implicit return

1
2
3
4
5
6
7
const Hello = () => "hi";
console.log(Hello());

const names = ["kim", "lee", "park"];

const hearts = names.map(name => name + " ❤️");
console.log(hearts);

this in Arrow Functions (Event listener in arrow function)

일반 콜백 함수안에서 this는 이벤트리스너에 연결 된 엘리먼트를 가리킨다. 하지만, arrow function안에서 this는 window를 가리킨다.

결론, this를 함수 안에 익명함수로 사용할 때는 Arrow Function이 아닌 일반 표준 funtion 형태로 사용해야한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const thisTest = {
cnt: 0,
addCnt() {
this.cnt++;
},
addCnt2: () => {
this.cnt++;
},
};
console.log(thisTest.cnt); // 0
thisTest.addCnt();
console.log(thisTest.cnt); // 1
thisTest.addCnt2;
console.log(thisTest.cnt); // 1

Default Values

1
2
3
4
5
6
const sayHi = (aName = "anon") => {
return `Hello ${aName}`;
}

console.log(sayHi());
console.log(sayHi('chaehyeon'));
[JS] ES6 - Variables

[JS] ES6 - Variables

이채현

Variables

Let and Const

var를 절대 사용하지 않고 let & const 사용하기

  • var를 쓰면 안되는 이유

    • var hoisting
      

      때문에…

      • var는 라이프사이클에서… 선언과 초기화를 동시에 한다.
      • global scope에 변수/함수를 선언할 경우 아무리 아래에 선언해도 제일 위로 올라간다. → 어디서 선언했든 상관없이, 항상 제일 위로 선언을 끌어올려준다.
      • block scope를 철저히 무시한다.

    ⇒ 이러한 유연성으로 작은 어플리케이션을 금방 만들 수 있지만, 프로젝트의 규모가 커지면서 나중에서는 선언하지도 않은 값이 멋대로 출력되거나, 개발자들간의 협업에서 여러가지 문제점이 생길 수 있다.

  • let은 선언과 초기화가 분리되어 그 사이에 TDZ가 생성되고, 접근할 경우 Reference Error가 발생한다.

  • const는 선언과 초기화가 동시에 진행되지만, 선언 이전에 TDZ가 생성되어 접근하면 Reference Error가 발생한다.

    Dead Zone

    temporal dead zone(TDZ)에 영향을 받는 구문은 크게..

    • const 변수
    • let 변수
    • class 구문
    • constructor() 내부의 super()
    • 기본 함수 매개변수

Block Scope

let & const는 block scope {}를 가짐

  • 외부에서 접근 불가능하다.

var는 function scope를 가짐

  • function 안에서 생성 된 var변수는 외부 function에서 접근 할 수 없지만, if/else, for등안에서 생성 된 var는 어디서는 접근 가능하다.

Immutabe Data Types

primitive types, frozen objects … 값이 바뀌지 않은 type

CONSTANTS는 Immutable Data Types이며, 프로그래밍할 때 왠만하면 Immutable Data Types를 사용하자.

💁🏻‍♀️ Immutable Data Types을 사용해야 하는 이유

  • security 해커들이 코드의 값을 바꾸는 것을 방지한다.
  • thread safety 어플리케이션을 실행하면 한가지의 프로세스가 할당되고, 그 프로세스 안에서 다양한 thread가 동시에 돌아가게 된다.이때 이 다양한 thread가 동시에 변수에 접근해서 값을 변경할 수 있게 되는 위험성이 생기는데, 이것을 방지한다.
  • reduce human mistakes 앞으로 해당 코드를 변경할 더 좋은 방안이 없다면, const 를 이용해 작성하여 본인 혹은 다른 개발자가 코드를 변경할때 발생할 수 있는 실수를 방지해준다.
[Ubuntu] Certbot을 이용한 인증서 발급하기

[Ubuntu] Certbot을 이용한 인증서 발급하기

노션에서 보기

이채현

snapd 설치하기 (snapd 없는 경우)

최신 버전의 우분투에는 snapd가 설치되어있는 것으로 알고 있음

1
2
3
4
# apt # snap
# Ubuntu
sudo apt install snapd
sudo reboot

certbot 설치하기 (snap)

1
2
3
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

cloudflare plugin 설치하기

1
2
3
# dns  cloudflare
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

cloudflare api token 넣기

1
2
3
4
5
6
mkdir -p ~/.secrets/certbot
vi ~/.secrets/certbot/cloudflare.ini
----------------------------------
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = IdgrE2pGEQxdq43kQPJ8*****************
chmod 600 ~/.secrets/certbot/cloudflare.ini

자신의 도메인 인증서 등록하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#
# *.4084.live
sudo certbot certonly --dns-cloudflare \\
--dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \\
-d *.4084.live

-----------------
ubuntu@dev-project-app:~$ sudo certbot certonly --dns-cloudflare \\
> --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \\
> -d *.4084.live
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): [email protected]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
<https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf>. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Account registered.
Requesting a certificate for *.4084.live
Waiting 10 seconds for DNS changes to propagate

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/4084.live/fullchain.pem
Key is saved at: /etc/letsencrypt/live/4084.live/privkey.pem
This certificate expires on 2022-02-26.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: <https://letsencrypt.org/donate>
* Donating to EFF: <https://eff.org/donate-le>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

생성된 인증서 경로 /etc/letsencrypt/live/4084.live/fullchain.pem /etc/letsencrypt/live/4084.live/privkey.pem

인증서 갱신하기

1
2
3
4
5
#     (--dry-run)
sudo certbot renew --dry-run

#(xx )
sudo certbot renew

crontab을 이용하여 주기적으로 갱신

(매주 일요일 2시 1분에 실행)

1
2
3
4
crontab -e
-----------
# cert renewal
1 2 * * 0 sudo /usr/bin/certbot renew

참고링크


[Ubuntu] EC2 Ubuntu에 접속 후 초기 셋팅

[Ubuntu] EC2 Ubuntu에 접속 후 초기 셋팅

노션에서 보기

이채현

인스턴스를 생성할 때 키페어 생성하여 위치확인하기

키 페어 저장

다운로드 한 키페어를 ~/.ssh 폴더 안에 위치시키고 권한을 600으로 변경한다

1
2
cp ~/Downloads/{keypair-name.pem} ~/.ssh/AWS
chmod 600 {keypair-name.pem}

접속

1
ssh -i ./{keypair-name.pem} ubuntu@{public ipv4 주소}

로그인 후

패키지 업데이트

1
2
sudo apt update
sudo apt upgrade

hostname 변경

1
2
sudo hostnamectl set-hostname {원하는 이름}
# 재접속

타임존 변경

1
sudo timedatectl set-timezone Asia/Seoul

개인PC에서 간단히 접속하기

ssh명령어를 이용하여 접속할 때에는 인증키의 위치를 계정명, 주소를 같이 입력해줘야하는 번거로움이 있다.

이를 개인pc의 인증서를 등록하여 인증서없이 바로 로그인해보자

id_rsa 키 생성하기 (개인-Mac)

1
2
cd ~/.ssh
ssh-keygen

이후 ~/.ssh 폴더 내부에 생성 된 id_rsa(private) id_rsa.pub(public) 두개의 키를 확인할 수 있다.
이 중 id_rsa.pub의 내용을 복사한다.

authorized_keys 수정하기 (원격-Ubuntu)

1
2
vim ~/.ssh/authorized_keys
위에서 복사한 id_rsa.pub 내용을 붙여넣고 저장한다.