Express.js와 타입스크립트로 백엔드 개발하기 🚀
안녕하세요, 열정 넘치는 개발자 여러분! 오늘은 현대 웹 개발의 핵심 기술인 Express.js와 타입스크립트를 활용한 백엔드 개발에 대해 깊이 있게 알아보겠습니다. 이 글을 통해 여러분은 안정적이고 확장 가능한 백엔드 시스템을 구축하는 방법을 배우게 될 것입니다.
최근 재능넷과 같은 재능 공유 플랫폼에서도 이러한 기술 스택을 활용한 개발자들의 수요가 늘어나고 있죠. 그만큼 이 기술의 중요성과 실용성이 증명되고 있다고 볼 수 있습니다.
이 가이드는 초보자부터 중급 개발자까지 모두에게 유용한 정보를 제공할 것입니다. 우리는 기본 개념부터 시작해 고급 기술까지 단계별로 살펴볼 예정이에요. 자, 이제 Express.js와 타입스크립트의 세계로 함께 떠나볼까요? 🌟
1. Express.js와 타입스크립트 소개 📚
1.1 Express.js란?
Express.js는 Node.js 환경에서 동작하는 웹 애플리케이션 프레임워크입니다. 간결하고 유연한 구조를 가지고 있어, 개발자들 사이에서 큰 인기를 얻고 있죠.
Express.js의 주요 특징은 다음과 같습니다:
- 미들웨어 기반 아키텍처
- 라우팅 시스템
- 템플릿 엔진 지원
- 정적 파일 제공
- HTTP 요청 처리 간소화
이러한 특징들 덕분에 Express.js는 RESTful API 개발부터 복잡한 웹 애플리케이션 구축까지 다양한 용도로 활용됩니다.
1.2 타입스크립트의 장점
타입스크립트는 자바스크립트의 상위 집합(Superset) 언어로, 정적 타입 검사와 객체 지향 프로그래밍 기능을 제공합니다.
타입스크립트를 사용하면 다음과 같은 이점을 얻을 수 있습니다:
- 코드 품질 향상
- 버그 조기 발견
- 개발 생산성 증가
- 더 나은 코드 문서화
- 강력한 IDE 지원
이러한 장점들로 인해 타입스크립트는 대규모 프로젝트에서 특히 빛을 발합니다.
1.3 Express.js와 타입스크립트의 시너지
Express.js와 타입스크립트를 함께 사용하면, 강력하고 안정적인 백엔드 시스템을 구축할 수 있습니다. 타입스크립트의 정적 타입 검사는 Express.js 애플리케이션의 안정성을 크게 향상시키며, 코드의 가독성과 유지보수성도 개선됩니다.
이 조합은 특히 다음과 같은 상황에서 유용합니다:
- 복잡한 비즈니스 로직을 다루는 대규모 프로젝트
- 팀 단위의 협업이 필요한 프로젝트
- 장기적인 유지보수가 필요한 프로젝트
- 높은 신뢰성이 요구되는 시스템
이제 우리는 Express.js와 타입스크립트의 기본을 알아보았습니다. 다음 섹션에서는 실제 개발 환경 설정부터 시작해 보겠습니다. 🛠️
2. 개발 환경 설정 ⚙️
2.1 Node.js 설치
Express.js와 타입스크립트를 사용하기 위해서는 먼저 Node.js를 설치해야 합니다. Node.js 공식 웹사이트(https://nodejs.org)에서 LTS 버전을 다운로드하여 설치하세요.
설치가 완료되면 터미널에서 다음 명령어를 실행하여 설치가 제대로 되었는지 확인합니다:
node --version
npm --version
2.2 프로젝트 초기화
새 프로젝트 디렉토리를 만들고, 그 디렉토리로 이동한 후 npm을 초기화합니다:
mkdir express-typescript-project
cd express-typescript-project
npm init -y
이 명령어는 package.json 파일을 생성합니다.
2.3 필요한 패키지 설치
이제 Express.js와 타입스크립트, 그리고 관련 패키지들을 설치합니다:
npm install express
npm install -D typescript @types/express @types/node ts-node nodemon
여기서 각 패키지의 역할은 다음과 같습니다:
- express: 웹 애플리케이션 프레임워크
- typescript: 타입스크립트 컴파일러
- @types/express: Express.js의 타입 정의
- @types/node: Node.js의 타입 정의
- ts-node: 타입스크립트를 직접 실행할 수 있게 해주는 도구
- nodemon: 파일 변경을 감지하여 자동으로 서버를 재시작해주는 도구
2.4 타입스크립트 설정
타입스크립트 설정 파일(tsconfig.json)을 생성합니다:
npx tsc --init
생성된 tsconfig.json 파일을 열고 다음과 같이 수정합니다:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
2.5 프로젝트 구조 설정
다음과 같은 프로젝트 구조를 만듭니다:
express-typescript-project/
├── src/
│ ├── routes/
│ ├── controllers/
│ ├── models/
│ ├── middleware/
│ └── app.ts
├── package.json
└── tsconfig.json
2.6 스크립트 설정
package.json 파일에 다음 스크립트를 추가합니다:
"scripts": {
"start": "node dist/app.js",
"dev": "nodemon src/app.ts",
"build": "tsc -p ."
}
이제 기본적인 개발 환경 설정이 완료되었습니다! 🎉
다음 섹션에서는 실제로 Express.js와 타입스크립트를 사용하여 간단한 서버를 만들어보겠습니다. 계속해서 따라와 주세요! 💪
3. 첫 번째 Express.js + 타입스크립트 서버 만들기 🖥️
3.1 기본 서버 설정
src/app.ts 파일을 생성하고 다음 코드를 작성합니다:
import express, { Express, Request, Response } from 'express';
const app: Express = express();
const port = 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Hello, Express.js with TypeScript!');
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
이 코드는 간단한 Express.js 서버를 설정하고, 루트 경로('/')에 대한 GET 요청을 처리합니다.
3.2 서버 실행
터미널에서 다음 명령어를 실행하여 서버를 시작합니다:
npm run dev
브라우저에서 http://localhost:3000 에 접속하면 "Hello, Express.js with TypeScript!" 메시지를 볼 수 있습니다.
3.3 라우팅 추가하기
src/routes 디렉토리에 users.ts 파일을 생성하고 다음 코드를 작성합니다:
import express, { Router, Request, Response } from 'express';
const router: Router = express.Router();
router.get('/', (req: Request, res: Response) => {
res.send('Users list');
});
router.get('/:id', (req: Request, res: Response) => {
res.send(`User with ID ${req.params.id}`);
});
export default router;
그리고 app.ts 파일을 수정하여 이 라우터를 사용합니다:
import express, { Express, Request, Response } from 'express';
import userRoutes from './routes/users';
const app: Express = express();
const port = 3000;
app.use('/users', userRoutes);
app.get('/', (req: Request, res: Response) => {
res.send('Hello, Express.js with TypeScript!');
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
3.4 미들웨어 추가하기
Express.js의 강력한 기능 중 하나는 미들웨어입니다. 간단한 로깅 미들웨어를 만들어 봅시다.
src/middleware/logger.ts 파일을 생성하고 다음 코드를 작성합니다:
import { Request, Response, NextFunction } from 'express';
export const logger = (req: Request, res: Response, next: NextFunction) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next();
};
그리고 app.ts 파일에 이 미들웨어를 추가합니다:
import express, { Express, Request, Response } from 'express';
import userRoutes from './routes/users';
import { logger } from './middleware/logger';
const app: Express = express();
const port = 3000;
app.use(logger);
app.use('/users', userRoutes);
app.get('/', (req: Request, res: Response) => {
res.send('Hello, Express.js with TypeScript!');
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
3.5 에러 처리
마지막으로, 간단한 에러 처리 미들웨어를 추가해 봅시다. app.ts 파일의 맨 아래에 다음 코드를 추가합니다:
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
이제 우리는 기본적인 Express.js + 타입스크립트 서버를 만들었습니다! 🎉
이 서버는 다음과 같은 기능을 가지고 있습니다:
- 기본 라우팅
- 사용자 관련 라우팅
- 로깅 미들웨어
- 기본적인 에러 처리
다음 섹션에서는 이 서버를 더욱 발전시켜, 데이터베이스 연결, 인증 처리, 테스팅 등 더 고급 주제들을 다뤄보겠습니다. 계속해서 따라와 주세요! 💪
4. 데이터베이스 연결: MongoDB와 Mongoose 🗄️
4.1 MongoDB 소개
MongoDB는 NoSQL 데이터베이스로, JSON과 유사한 형태의 문서를 저장하고 관리합니다. 유연한 스키마와 높은 확장성으로 인해 현대적인 웹 애플리케이션 개발에 많이 사용됩니다.
4.2 Mongoose 소개
Mongoose는 MongoDB를 위한 ODM(Object Data Modeling) 라이브러리입니다. 이를 통해 MongoDB와의 상호작용을 더 쉽고 직관적으로 할 수 있습니다.
4.3 필요한 패키지 설치
먼저, 필요한 패키지들을 설치합니다:
npm install mongoose
npm install -D @types/mongoose
4.4 데이터베이스 연결 설정
src/config/database.ts 파일을 생성하고 다음 코드를 작성합니다:
import mongoose from 'mongoose';
export const connectDB = async () => {
try {
await mongoose.connect('mongodb://localhost:27017/myapp');
console.log('MongoDB connected');
} catch (error) {
console.error('MongoDB connection error:', error);
process.exit(1);
}
};
그리고 app.ts 파일에서 이 함수를 호출합니다:
import { connectDB } from './config/database';
// ... 기존 코드 ...
connectDB();
// ... 기존 코드 ...
4.5 모델 정의하기
이제 사용자 모델을 정의해 봅시다. src/models/user.ts 파일을 생성하고 다음 코드를 작성합니다:
import mongoose, { Schema, Document } from 'mongoose';
export interface IUser extends Document {
name: string;
email: string;
password: string;
createdAt: Date;
}
const UserSchema: Schema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
createdAt: { type: Date, default: Date.now }
});
export default mongoose.model<iuser>('User', UserSchema);</iuser>
4.6 컨트롤러 만들기
이제 사용자 관련 로직을 처리할 컨트롤러를 만들어 봅시다. src/controllers/userController.ts 파일을 생성하고 다음 코드를 작성합니다:
import { Request, Response } from 'express';
import User, { IUser } from '../models/user';
export const createUser = async (req: Request, res: Response) => {
try {
const { name, email, password } = req.body;
const user: IUser = new User({ name, email, password });
await user.save();
res.status(201).json(user);
} catch (error) {
res.status(500).json({ error: 'Error creating user' });
}
};
export const getUsers = async (req: Request, res: Response) => {
try {
const users: IUser[] = await User.find();
res.status(200).json(users);
} catch (error) {
res.status(500).json({ error: 'Error fetching users' });
}
};
export const getUserById = async (req: Request, res: Response) => {
try {
const user: IUser | null = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.status(200).json(user);
} catch (error) {
res.status(500).json({ error: 'Error fetching user' });
}
};
4.7 라우터 업데이트
이제 src/routes/users.ts 파일을 수정하여 새로 만든 컨트롤러를 사용하도록 합니다:
import express, { Router } from 'express';
import { createUser, getUsers, getUserById } from '../controllers/userController';
const router: Router = express.Router();
router.post('/', createUser);
router.get('/', getUsers);
router.get('/:id', getUserById);
export default router;
4.8 body-parser 미들웨어 추가
POST 요청의 body를 파싱하기 위해 body-parser 미들웨어를 추가해야 합니다. app.ts 파일에 다음 코드를 추가합니다:
import express, { Express } from 'express';
import bodyParser from 'body-parser';
// ... 기존 코드 ...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// ... 기존 코드 ...
이제 우리의 Express.js + 타입스크립트 서버가 MongoDB와 연동되어 동작합니다! 🎉
이 서버는 다음과 같은 기능을 가지고 있습니다:
- MongoDB 연결
- 사용자 모델 정의
- 사용자 생성, 조회 기능
- MongoDB를 이용한 데이터 저장 및 조회
다음 섹션에서는 인증 기능을 추가하고, 테스트 코드를 작성하는 방법에 대해 알아보겠습니다. 계속해서 따라와 주세요! 💪
5. 인증 기능 구현: JWT를 이용한 사용자 인증 🔐
5.1 JWT 소개
JWT(JSON Web Token)는 웹 애플리케이션에서 사용자 인증을 위해 널리 사용되는 방식입니다. 토큰 기반 인증 시스템으로, 서버 측에서 상태를 유지할 필요가 없어 확장성이 뛰어납니다.
5.2 필요한 패키지 설치
JWT 관련 패키지를 설치합니다:
npm install jsonwebtoken bcrypt
npm install -D @types/jsonwebtoken @types/bcrypt
5.3 사용자 모델 업데이트
src/models/user.ts 파일을 수정하여 비밀번호 해싱 기능을 추가합니다:
import mongoose, { Schema, Document } from 'mongoose';
import bcrypt from 'bcrypt';
export interface IUser extends Document {
name: string;
email: string;
password: string;
createdAt: Date;
comparePassword(candidatePassword: string): Promise<boolean>;
}
const UserSchema: Schema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
createdAt: { type: Date, default: Date.now }
});
UserSchema.pre<iuser>('save', async function(next) {
if (!this.isModified('password')) return next();
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
});
UserSchema.methods.comparePassword = async function(candidatePassword: string): Promise<boolean> {
return bcrypt.compare(candidatePassword, this.password);
};
export default mongoose.model<iuser>('User', UserSchema);</iuser></boolean></iuser></boolean>
5.4 JWT 유틸리티 함수 만들기
src/utils/jwt.ts 파일을 생성하고 다음 코드를 작성합니다:
import jwt from 'jsonwebtoken';
import { IUser } from '../models/user';
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
export const generateToken = (user: IUser): string => {
return jwt.sign({ id: user._id }, JWT_SECRET, { expiresIn: '1d' });
};
export const verifyToken = (token: string): jwt.JwtPayload => {
return jwt.verify(token, JWT_SECRET) as jwt.JwtPayload;
};
5.5 인증 미들웨어 만들기
src/middleware/auth.ts 파일을 생성하고 다음 코드를 작성합니다:
import { Request, Response, NextFunction } from 'express';
import { verifyToken } from '../utils/jwt';
export const auth = (req: Request, res: Response, next: NextFunction) => {
const token = req.header('Authorization')?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'No token, authorization denied' });
}
try {
const decoded = verifyToken(token);
(req as any).userId = decoded.id;
next();
} catch (error) {
res.status(401).json({ error: 'Token is not valid' });
}
};
5.6 인증 컨트롤러 만들기
src/controllers/authController.ts 파일을 생성하고 다음 코드를 작성합니다:
import { Request, Response } from 'express';
import User, { IUser } from '../models/user';
import { generateToken } from '../utils/jwt';
export const login = async (req: Request, res: Response) => {
try {
const { email, password } = req.body;
const user: IUser | null = await User.findOne({ email });
if (!user) {
return res.status(400).json({ error: 'Invalid credentials' });
}
const isMatch = await user.comparePassword(password);
if (!isMatch) {
return res.status(400).json({ error: 'Invalid credentials' });
}
const token = generateToken(user);
res.json({ token });
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
};
export const register = async (req: Request, res: Response) => {
try {
const { name, email, password } = req.body;
let user: IUser | null = await User.findOne({ email });
if (user) {
return res.status(400).json({ error: 'User already exists' });
}
user = new User({ name, email, password });
await user.save();
const token = generateToken(user);
res.status(201).json({ token });
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
};
5.7 인증 라우터 만들기
src/routes/auth.ts 파일을 생성하고 다음 코드를 작성합니다:
import express, { Router } from 'express';
import { login, register } from '../controllers/authController';
const router: Router = express.Router();
router.post('/login', login);
router.post('/register', register);
export default router;
5.8 메인 앱에 인증 라우터 추가
app.ts 파일을 수정하여 인증 라우터를 추가합니다:
import express, { Express } from 'express';
import userRoutes from './routes/users';
import authRoutes from './routes/auth';
import { connectDB } from './config/database';
const app: Express = express();
const port = 3000;
connectDB();
app.use(express.json());
app.use('/api/users', userRoutes);
app.use('/api/auth', authRoutes);
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
이제 우리의 Express.js + 타입스크립트 서버에 JWT를 이용한 인증 기능이 추가되었습니다! 🎉
이 서버는 이제 다음과 같은 기능을 가지고 있습니다:
- 사용자 등록 및 로그인
- 비밀번호 해싱
- JWT 토큰 생성 및 검증
- 보호된 라우트에 대한 인증 미들웨어
다음 섹션에서는 우리가 만든 API의 테스트 코드를 작성하는 방법에 대해 알아보겠습니다. 계속해서 따라와 주세요! 💪
6. 테스트 코드 작성: Jest를 이용한 단위 테스트 및 통합 테스트 🧪
6.1 Jest 소개
Jest는 Facebook에서 만든 JavaScript 테스팅 프레임워크로, 간단한 설정으로 빠르고 효율적인 테스트를 할 수 있습니다. 타입스크립트와의 호환성도 뛰어나 우리 프로젝트에 적합합니다.
6.2 필요한 패키지 설치
Jest와 관련 패키지들을 설치합니다:
npm install -D jest ts-jest @types/jest supertest @types/supertest
6.3 Jest 설정
프로젝트 루트에 jest.config.js 파일을 생성하고 다음 내용을 작성합니다:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootdir>/src'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
transform: {
'^.+\\.ts$': 'ts-jest',
},
};</rootdir>
6.4 단위 테스트 작성
src/__tests__/unit/user.test.ts 파일을 생성하고 다음 코드를 작성합니다:
import User from '../../models/user';
describe('User Model Test', () => {
it('should create & save user successfully', async () => {
const userData = {
name: 'Test User',
email: 'test@example.com',
password: 'password123'
};
const user = new User(userData);
const savedUser = await user.save();
expect(savedUser._id).toBeDefined();
expect(savedUser.name).toBe(userData.name);
expect(savedUser.email).toBe(userData.email);
expect(savedUser.password).not.toBe(userData.password); // password should be hashed
});
it('should fail to save user with missing required field', async () => {
const userWithoutRequiredField = new User({ name: 'Test User' });
let err;
try {
await userWithoutRequiredField.save();
} catch (error) {
err = error;
}
expect(err).toBeInstanceOf(Error);
});
});
6.5 통합 테스트 작성
src/__tests__/integration/auth.test.ts 파일을 생성하고 다음 코드를 작성합니다:
import request from 'supertest';
import { Express } from 'express';
import mongoose from 'mongoose';
import { createServer } from '../../app'; // 서버 생성 함수를 별도로 만들어야 합니다.
let app: Express;
beforeAll(async () => {
app = await createServer();
});
afterAll(async () => {
await mongoose.connection.close();
});
describe('Authentication Endpoints', () => {
it('should register a new user', async () => {
const res = await request(app)
.post('/api/auth/register')
.send({
name: 'Test User',
email: 'test@example.com',
password: 'password123'
});
expect(res.statusCode).toEqual(201);
expect(res.body).toHaveProperty('token');
});
it('should login an existing user', async () => {
const res = await request(app)
.post('/api/auth/login')
.send({
email: 'test@example.com',
password: 'password123'
});
expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty('token');
});
});
6.6 테스트 실행을 위한 스크립트 추가
package.json 파일의 "scripts" 섹션에 다음 내용을 추가합니다:
"scripts": {
...
"test": "jest",
"test:watch": "jest --watch"
}
6.7 테스트 실행
다음 명령어로 테스트를 실행할 수 있습니다:
npm test
또는 파일 변경을 감지하여 자동으로 테스트를 실행하려면:
npm run test:watch
이제 우리의 Express.js + 타입스크립트 서버에 테스트 코드가 추가되었습니다! 🎉
이 테스트 코드는 다음과 같은 기능을 검증합니다:
- 사용자 모델의 생성 및 저장
- 필수 필드 누락 시 에러 발생
- 사용자 등록 API
- 사용자 로그인 API
테스트 코드를 작성함으로써 우리는 애플리케이션의 신뢰성을 높이고, 버그를 조기에 발견할 수 있게 되었습니다. 또한 새로운 기능을 추가하거나 기존 코드를 수정할 때 더 자신감 있게 작업할 수 있게 되었습니다.
다음 섹션에서는 우리가 만든 서버를 실제 운영 환경에 배포하는 방법에 대해 알아보겠습니다. 계속해서 따라와 주세요! 💪
7. 배포: Docker와 AWS를 이용한 서버 배포 🚀
7.1 Docker 소개
Docker는 애플리케이션을 컨테이너화하여 개발, 배포, 실행을 쉽게 만들어주는 플랫폼입니다. 컨테이너를 사용하면 애플리케이션과 그 의존성을 하나의 패키지로 묶어 어떤 환경에서도 일관되게 실행할 수 있습니다.
7.2 Dockerfile 작성
프로젝트 루트에 Dockerfile을 생성하고 다음 내용을 작성합니다:
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/app.js"]
7.3 .dockerignore 파일 작성
프로젝트 루트에 .dockerignore 파일을 생성하고 다음 내용을 작성합니다:
node_modules
npm-debug.log
dist
7.4 Docker 이미지 빌드
터미널에서 다음 명령어를 실행하여 Docker 이미지를 빌드합니다:
docker build -t my-express-app .
7.5 Docker 컨테이너 실행
다음 명령어로 Docker 컨테이너를 실행합니다:
docker run -p 3000:3000 my-express-app
7.6 AWS EC2 인스턴스 생성
- AWS 콘솔에 로그인합니다.
- EC2 대시보드로 이동합니다.
- "인스턴스 시작" 버튼을 클릭합니다.
- Amazon Linux 2 AMI를 선택합니다.
- 인스턴스 유형을 선택합니다 (예: t2.micro).
- 보안 그룹 설정에서 SSH (22번 포트)와 HTTP (80번 포트) 접근을 허용합니다.
- 새 키 페어를 생성하고 다운로드합니다.
- "인스턴스 시작" 버튼을 클릭합니다.
7.7 EC2 인스턴스에 Docker 설치
SSH를 사용하여 EC2 인스턴스에 접속한 후, 다음 명령어를 실행하여 Docker를 설치합니다:
sudo yum update -y
sudo amazon-linux-extras install docker
sudo service docker start
sudo usermod -a -G docker ec2-user
7.8 EC2 인스턴스에 애플리케이션 배포
- 로컬 머신에서 Docker 이미지를 Docker Hub에 푸시합니다:
docker tag my-express-app your-dockerhub-username/my-express-app
docker push your-dockerhub-username/my-express-app
- EC2 인스턴스에서 다음 명령어를 실행하여 Docker 이미지를 가져오고 실행합니다:
docker pull your-dockerhub-username/my-express-app
docker run -d -p 80:3000 your-dockerhub-username/my-express-app
7.9 도메인 연결 (선택사항)
- 도메인 이름을 구매합니다 (예: AWS Route 53 사용).
- EC2 인스턴스의 퍼블릭 IP 주소를 도메인 이름에 연결합니다.
이제 우리의 Express.js + 타입스크립트 서버가 AWS EC2 인스턴스에 성공적으로 배포되었습니다! 🎉
이 배포 과정을 통해 우리는 다음과 같은 것들을 달성했습니다:
- Docker를 이용한 애플리케이션 컨테이너화
- AWS EC2 인스턴스 생성 및 설정
- Docker Hub를 이용한 이미지 공유
- 실제 운영 환경에 애플리케이션 배포
이로써 우리는 Express.js와 타입스크립트를 이용한 백엔드 개발부터 배포까지의 전체 과정을 완료했습니다. 이 과정에서 우리는 현대적인 백엔드 개발의 핵심 기술들을 다루었고, 실제 운영 환경에 배포할 수 있는 안정적이고 확장 가능한 서버를 구축했습니다.
앞으로 여러분은 이 지식을 바탕으로 더 복잡하고 규모가 큰 프로젝트에도 도전할 수 있을 것입니다. 계속해서 학습하고 경험을 쌓아가며, 더 나은 개발자로 성장하시기 바랍니다. 화이팅! 💪