그림으로 설명해준대로면
Node.js에서 올린 서버는 AWS SDK 를 사용하면 S3와 연동할 수 있겠구나!
목차
* JavaScript용 AWS SDK에서는 AWS 서비스용 JavaScript API를 제공합니다. JavaScript API를 사용하여 Node.js용 또는 브라우저용 라이브러리 또는 애플리케이션을 빌드할 수 있습니다.
AWS SDK를 API로 제공해서 Node.js난 브라우저에서 바로 사용할 수 있겠네요.
`npm install aws-sdk` 로 aws-sdk를 설치한 후에
```
// import entire SDK
import AWS from 'aws-sdk';
// import AWS object without services
import AWS from 'aws-sdk/global';
// import individual service
import S3 from 'aws-sdk/clients/s3';
```
그런데 우리 프로젝트에서는 Typescript를 써야해요.
조건들이 있어요.
Use TypeScript v2.x
Includes the TypeScript definitions for node. You can use npm to install this by typing the following into a terminal window:
Typescript를 node에 추가하래요.
`npm install --save-dev @types/node`
자세한것은 [Pre-requisite](https://github.com/aws/aws-sdk-js) 참고
S3 가 있고,
S3 Control이 있네?
S3 contorl은
AWS S3 Control provides access to Amazon S3 control plane operations.
컨트롤 판넬 운영에 접근을 제공한다? 이건 아닌거 같어.
S3는
Method Summary 보니까. createBucket, createMultipartUpload 등등 우리가 개발에 필요한 API들이 있다!
버킷이 없으면 버킷부터 만들어야지. S3에서 버킷은 데이터를 담을 수 있는 디렉토리, 그 외에도 static web hosting 등등도 제공한다.
createBucket(params, callback) ⇒ AWS.Request
이 둘의 차이점은 createBucket(params, 콜백)
params에 들어갈 정보(프로퍼티)들이 다르다.createMultipartUpload(params = {}, callback) ⇒ AWS.Request
params에 Bucket name하고 Key가 있네?
Key는 뭘까?
[S3 버킷에 파일 및 폴더를 업로드하려면 어떻게 해야 합니까?](https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/user-guide/upload-objects.html)
하나의 파일이나 폴더 전체를 Amazon S3버킷에 업로드 하는 방법은?
파일과 폴더를 업로드하려면 해당 버킷에 대한 쓰기 권한이 있어야 합니다!
액세스 권한은 [여기](https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/user-guide/set-permissions.html) 참조
버킷 및 객체는 Amazon S3 리소스입니다. 리소스 기반 액세스 정책을 사용하여 버킷과 객체에 액세스 권한을 부여합니다.
S3 === 리소스
리소스 기반은 액세스 정책을 사용하여 권한을 버킷과 객체에 부여!
권한이 있어야 버킷에 파일 업로드 할 수 있음!
그러면 SDK로 권한을 읽어올 수도 있나?
ㅋㅋㅋ SDK 보다가 put Object라는 API도 있는데?
`putObject(params = {}, callback) ⇒ AWS.Request`
get Object도 있어.
`getObject(params = {}, callback) ⇒ AWS.Request
`aws-sdk 메서드들 많은데 어쩌라는거야? 언제 어떻게 사용해야하는지 알아야 쓰징
도커는 도커인데 client는 또 뭐고 server는 또 뭐야
client는 아래 그림에 표시된 것이고 , server는 Docker daemon 으로 보면 됌.
클라이언트가 서버에게 docker 명령을 보내면 서버가 명령어에 따라 container를 빌드하든 가져오든 실행하는구나!
brew install docker
# after install docker
docker version
$docker version
client: ~
...
server: ~
뜨면 성공
설치가 다 되었다는 가정...
docker 명령은 항상 root 권한에서만 사용 가능하다 -> sudo를 붙여라 ( 제 환경에서는 안해도 되네용)
싫다면? docker에서는
docker 그룹에 사용자 계정을 추가하는 방식으로 sudo를 쓰지 않을 수도 있다. (신경안써도 됌..)
docker --help
docker version
docker images
docker pull <REPOSITORY>:<TAG>
Minio를 예를 들어서
docker pull minio/minio
minio 프로그램만 딱 들어있는게 아니라
커널을 제외한 리눅스 배포판이 그대로 들어가 있음.
즉, minio를 실행하기 위한 가장 기본적인 프로그램들이 들어가있는 리눅스 이미지에
minio 프로그램만 넣은 구조이다.
docker 이미지를 검색하는 명령어도 있지만 docker hub 사이트에서 검색하는 것이 편하다.
docker run <옵션> <이미지 이름, ID> <명령> <매개 변수>
minio라는 프로그램을 예로 들었어요.
docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v ~/data:/data \
minio/minio server /data
$docker ps
// (리눅스에서 ps명령어와 흡사) 현재 실행되고 있는 컨테이너 조회
$docker ps -a
// 종료된 컨테이너까지 볼 수 있다.
docker stop <container name>
docker rm <container name>
docker rmi <Image name>
docker start <container name>
docker attach <container name>
docker exec -i -t <container name> /bin/sh
cmt+p+q(sh빠져나오는 명령어)
exit
docker run <옵션> <이미지 이름, ID> <명령> <매개 변수>
-p, --publish=[]: 호스트에 연결된 컨테이너의 특정 포트를 외부에 노출합니다. 보통 웹 서버의 포트를 노출할 때 주로 사용합니다.
<호스트 포트>:<컨테이너 포트> 예) -p 80:80
<IP 주소>:<호스트 포트>:<컨테이너 포트> 호스트에 네트워크 인터페이스가 여러 개이거나 IP 주소가 여러 개 일 때 사용합니다. 예) -p 192.168.0.10:80:80
<IP 주소>::<컨테이너 포트> 호스트 포트를 설정하지 않으면 호스트의 포트 번호가 무작위로 설정됩니다. 예) -p 192.168.0.10::80
<컨테이너 포트> 컨테이너 포트만 설정하면 호스트의 포트 번호가 무작위로 설정됩니다. 예) -p 80
$docker run -p 9000:9000 minio/minio server /data
//server는 프로그램이고 /data는 그 프로그램의 파라미터다?
//minio shell로 들어가보자.
docker run -p 9000:9000 --name minio minio/minio server /data
$docker exec -it minio /bin/sh
-e, --env=[]: 컨테이너에 환경 변수를 설정합니다. 보통 설정 값이나 비밀번호를 전달할 때 사용합니다.
-e MYSQL_ROOT_PASSWORD=examplepassword
--entrypoint=””: Dockerfile의 ENTRYPOINT 설정을 무시하고 강제로 다른 값을 설정합니다.
--entrypoint=”/bin/bash”
docker minio 이미지를 pull 받았다는 가정하에...
다음과 같이 docker에 minio server를 구동시킨다.
그러면 url을 뱉어낸다. 그 url(엔드포인트)로
sdk로 client를 뚫어놓는다.
docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v ~/data:/data \
minio/minio server /data
도커 container가 종료되면 데이터도 사라지므로, -v 옵션을 통해 host 디렉토리와 연동시켜둔다.
minio가 server client가 있는데 이게 뭐지...
이게 뭐야?
server는 s3랑 똑같다고 봐도 되고
client는 s3를 접근하는 aws cli라고 생각하면 되겠네?
minio server : s3
minio client : aws cli
key의 의미는
minio에
접속할 수 있는
선택한사람만 접근할 수 있게
액세스키, 시크릿키 - 서버를 올릴때 임의로 쓰고
레퍼런스
위의 액세스키, 시크릿키를 Node.js로 sdk를 이용해 요청을 보낼때 사용한다!!
레퍼런스
minio 도커 이미지 가져오기
docker pull minio/minio
minio 도커 컨테이너 실행하기
docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v ~/data:/data \
minio/minio server /data
Node.js 에서 가장 인기있던 웹 프레임워크인 Express.js 의 개발팀이, Koa 라는 웹프레임워크를 새로 만들었습니다.
npm install @types/koa
npm install @types/koa-router
<- typescript 모듈의 경우 보통 @types/js모듈이름 으로 패키지를 설치해야하나보다;;
app.use(ctx => {
ctx.body = 'Hello Koa';
});
ctx는 뭐야?
ctx 는, 웹 요청과, 응답에 대한 정보를 지니고있고, next 는 다음 미들웨어를 실행시키는 함수입니다. 만약에 미들웨어에서 next 호출하지 않게 된다면, 그 부분에서 요청처리를 완료시키고, 응답을 하게됩니다.
ctx.status = 200;
ctx.body = "";
MDN
FormData 인터페이스는 form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공합니다.
또한 XMLHttpRequest.send() 메서드를 사용하여 쉽게 전송할 수 있습니다.
인코딩 타입이 "multipart/form-data"로 설정된 경우, form에서 사용하는 것과 동일한 포맷을 사용해야 합니다.
객체에요. 객체면 뭔가를 담을 수 있는 저장소라는 얘기인데,
FormData 객체는 XMLHttpRequest를 사용하여 전송할 수 있도록 키/값 쌍들의 집합을 저장하는 객체에요.
<input type="file" />
input엘리먼트, FormData(), fetch()를 사용하여 파일을 업로드 할 수 있습니다.
레퍼런스
var formData = new FormData();
var fileField = document.querySelector('input[type="file"]');
formData.append('username', 'abc123');
formData.append('avatar', fileField.files[0]);
fetch('https://example.com/profile/avatar', {
method: 'PUT',
body: formData
})
.then(response => response.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', JSON.stringify(response)));
개발자 PC
개발자는 PC에 realease, hotfix, feature, issue 브랜치를 생성하여 작업을 진행한다. 작업이 완료된 브랜치는 병합 후 삭제 가능하며, GitHub에 반영하지 않는다.
hotfix 브랜치
master 브랜치로부터 생성하는 브랜치이다. master 브랜치에 심각한 오류가 있는 경우에만 생성한다.
명명규칙: hotfix/<issue_number>
완료 후 master, release, develop 브랜치에 병합한다.
feature 브랜치
develop 브랜치로부터 생성하는 브랜치이다.
명명규칙: feature/<issue_number>/<짧은설명>
완료 후 develop 브랜치에 병합한다.
issue 브랜치
develop, feature, release 브랜치로부터 생성하는 브랜치이다.
명명규칙: issue/<issue_number>
완료 후에는 생성된 부모 브랜치로 병합한다.
koa나 express나 똑같으니까 express 기준으로 정리
클라이언트 HTTP POST request data의 body로부터 파라미터를 편리하게 추출합니다.
var express = require('express')
var app = express()
app.post('/profile', function(req, res) => {
console.log(req.body)
})
그런데, 위 코드 기준 5번째 줄 console.log(req.body) 라인에서 undefined Error를 마주하게 됩니다.
req.body는 body-parser를 사용하기 전에는 디폴트 값으로 Undefined이 설정되기 때문입니다. (출처: Express Docs)
그래서 body-parser를 쓴다~ body-parser는 node module package
Node.js에서 사용하는 코드의 묶음이다~
var express = require('express')
var bodyParser = require('body-parser')
var app = express();
app.use(express.json()) <- app.use(bodyParser().json())
//express.js도 빌트인 body parser를 넣었다는 점을 알게 되었습니다.(Express v4.16.0 기준)(출처: Express Docs)
//그래서 다음과 같이 써도 문제는 해결됩니다.
app.post('/profile', function(req, res) => {
console.log(req.body)
})
마크다운 내용이 너무 길면 목차를 클릭해서 딱 위치로 해당 내용으로 가고싶어
레퍼런스
해석해보면 markdown 도 html로 변환이 되는데...
h1, h2, ..., h6 내용이 헤더가 유니크 id로 할당된대
그래서
나도 구글개발자 도구로 검사해서 어떻게 헤더가 id로 구성되는지 확인해서 사용했음.
ㅎㅎ그런데, velog에서는 오른쪽에 anchor 기능이 있다.ㅎㅎ
마크다운도 -> HTMl로 변환된다.
그때 # sth ## sth2 등 h1 h2의 내용이