-
[๊ฐ์] ๋ฐ๋ผํ๋ฉฐ ๋ฐฐ์ฐ๋ ๋์ปค์ CIํ๊ฒฝ -6STUDY/CLOUD 2022. 6. 28. 02:50
์ด์ : ํ๋ก ํธ๋ง ์ฌ์ฉ
์ด๋ฒ : ๋ฐฑ์๋์ DB๋ ๊ตฌํํด์ ๋ง์ ์ปจํ ์ด๋ ์ฌ์ฉ
๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ์ค๊ณ ๊ฐ๋ฅ -> ์ฒซ ๋ฒ์งธ ๋ฐฉ์์ผ๋ก ๊ฐ์ ์งํ
- Nginx์ Proxy๋ฅผ ์ด์ฉํ ์ค๊ณ
- Nginx๋ ์ ์ ํ์ผ์ ์ ๊ณต๋ง ํด์ฃผ๋ ์ค๊ณ
ํฐ๊ทธ๋ฆผ
๐ซNode JS ๊ตฌ์ฑํ๊ธฐ
backendํด๋ ๋ง๋ค๊ณ ์ฌ๊ธฐ์ npm init
nodemon์ ์ฌ์ฉํ๋ ์ด์ : ๋ ธ๋ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํด๋ ๋ฐ๋ก ์ค๋จ, ์ฌ๊ฐ๋ ์์ผ์ค ์ ์๋๋ก ํ๊ธฐ ์ํด
db.js
const mysql = require("mysql"); const pool = mysql.createPool({ connectionLimit: 10, host: 'mysql', user: 'root', password: 'johnahn', database: 'myapp' }); exports.pool = pool;
server.js
const express = require("express"); const bodyParser = require('body-parser'); const db = require('./db'); const app = express(); app.user(bodyParser.json()); db.pool.query(`CREATE TABLE lists ( id INTEGER AUTO_INCREMENT, value TEXT, PRIMARY KEY (id))`, (err, results, fileds) => { console.log('results', results) }) ap.get('/api/values', function (req, res) { db.pool.query(`SELECT * FROM lists;`, (err, results, fileds) => { if (err) return res.status(500).send(err) else return res.json({ success: true, value: req.body.value }) } }) ap.post('/api/values', function (req, res, next) { db.pool.query(`INSERT INTO lists (vlaue) VALUES("${req.body.value}"))`, (err, results, fileds) => { if (err) return res.status(500).send(err) else return res.json({ success: true, value: req.body.value }) } }) app.listen(5000, () => { console.log('์ดํ๋ฆฌ์ผ์ด์ ์ด ์๋ฒ 5000๋ฒ ํฌํธ์์ ์์๋์์ต๋๋ค.') })
๐ซReact JS ๊ตฌ์ฑํ๊ธฐ
frontend ํด๋ ์์ฑ
npx create-react-app frontend ๋ช ๋ น์ด๋ก react ํ์ผ ์์ฑ
App.js
axios ์๋ผ์ ํ์ฐธ ํค๋งค๋ค ์ง์ ์ค์นํ๋๋ฐ ๋ด๊ฐ์์ ์๋ชป๋๋ค๊ณ ์๋ ค์ฃผ์ฌ
๊ฐํน๋ฐ๋๋คimport logo from './logo.svg'; import './App.css'; import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { useEffect(() => { axios.get(`/api/values`) .then(response => { console.log('response', response.data) setLists(response.data) }) }, []) const [lists, setLists] = useState([]) const [value, setValue] = useState("") const changeHandler = (event) => { setValue(event.currentTarget.value) } const submitHandler = (event) => { event.preventDefault(); axios.post(`/api/value`, { value: value }) .then(response => { if (response.data.success) { console.log('response.data', response.data) setLists([...lists, response.data]) setValue(""); } else { alert("๊ฐ์ DB์ ๋ฃ๋๋ฐ ์คํจํ์ต๋๋ค.") } }) } return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <div className="container"> {lists && lists.map((list, index) => ( <li key={index}>{list.value}</li> ))} <form className="example" onSubmit={submitHandler}> <input type="text" placeholder="์ ๋ ฅํด์ฃผ์ธ์..." onchange={changeHandler} value={value} /> <button type="submit">ํ์ธ</button> </form> </div> </header> </div> ); } export default App;
๐ณ for ๋ฆฌ์กํธ ์ฑ ๋์ปค ํ์ผ ๋ง๋ค๊ธฐ
default.conf ๋ฅผ ์ด์์์ฌ index.html์ด home์ด๋ผ๋ ๊ฒ์ ์๋ ค์ค๋ค
server{ listen 3000; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } }
Dockerfile
FROM node:alpine as builder WORKDIR /app COPY ./package.json ./ RUN npm install COPY ./ ./ RUN npm run build FROM nginx EXPOSE 3000 COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf COPY --from=builder /app/build /usr/share/nginx/html
๐ณ for ๋ ธ๋ ์ฑ ๋์ปค ํ์ผ ๋ง๋ค๊ธฐ
mysql ํด๋ ์์ฑ
Dockerfile.dev
์ ํ์ผ๊ณผ "start"->"dev"ํ๋ ์ฐจ์ด
Dockerfile
Dockerfile.dev์์ "start"๋ง ๊ทธ๋๋ก ๋
๐ณ for MySQL ๋์ปค ํ์ผ ๋ง๋ค๊ธฐ
Dockerfile
FROM mysql:5.7 ADD ./my.cnf /etc/mysql/conf.d/my.cnf
my.cnf
ํ๊ธ ๊นจ์ง ํ์ ๋ฐฉ์ง ์ํจ
initialize.sql
DROP DATABASE IF EXIST myapp; CREATE DATABASE myapp; USE myapp; CREATE TABLE lists( id INTEGER AUTO_INCREMENT, value TEXT, PRIMARY KEY (id) )
๐ณ for Nginx ๋์ปค ํ์ผ ๋ง๋ค๊ธฐ
nginx ํด๋ ์์ฑ
ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ฐ๋ผ ์ ์ ํ์ผ์ ์ํ๋ฉด React.js API ์์ฒญ์ด๋ฉด Node.js๋ก ๋ณด๋ธ๋ค.
->๊ธฐ์ค: /api๋ก ์์ํ๋์ง, /๋ก ์์ํ๋์ง
default.conf
React.js๋ก ๋ณด๋ผ ๊ฒ๊ณผ Node.js๋ก ๋ณด๋ผ ๊ฒ ๋ถ๋ฆฌ
Dockerfile
FROM nginx COPY ./default.conf /etc/nginx/conf.d/default.conf
๐ Docker Compose ํ์ผ ์์ฑํ๊ธฐ
version: "3" services: frontend: build: context: ./frontend dockerfile: Dockerfile.dev volumes: - /app/node_modules - ./frontend:/app stdin_open: true nginx: restart : always #์ฌ์์ ์ ์ฑ , ํญ์ ์ฌ์์ build: context: ./nginx dockerfile: Dockerfile ports: - "3000:80" backend: build: context: ./backend dockerfile: Dockerfile.dev container_name: app_backend volumes: - /app/node_modules - ./backend:/app mysql: build: ./mysql restart: unless-stopped #๊ฐ๋ฐ์๊ฐ ์์๋ก ๋ฉ์ถ๋ ค๊ณ ํ๋๊ฑฐ ์๋๋ฉด ํญ์ ์ฌ์์ container_name: app_mysql ports: - "3306:3306" volumes: - ./mysql/mysql_data:/var/lib/mysql - ./mysql/sqls/:/docker-entrypoint-initdb.d/ environment: MYSQL_ROOT_PASSWORD: johnahn MYSQL_DATABASE: myapp
docker-compose up ์ผ๋ก ์คํ
๋นก๋๊ฐ๋ฆฌ์ ์ค๋ฅ์ผ๊ธฐ
1. nginx ์คํ ๋ง ํ๋ฆผ nginix๋ผ๊ณ ์คํ๋(์์ง๋์ค ๋ง์๋..)
2. "3306":"3306" ํจ
3. ์ฃผ์๋ค๋๋ผ ํ๊ธ ์จ๋๊ณ utf-8๋ก ์ ์ฅ ์ํจ
๐ Volume์ ์ด์ฉํ ๋ฐ์ดํฐ ๋ฒ ์ด์ค ๋ฐ์ดํฐ ์ ์งํ๊ธฐ
์ด์ : ์ปจํ ์ด๋ ๋ด๋ถ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฒ ๋๋ฏ๋ก, ์ปจํ ์ด๋ ์ญ์ ์ ์ปจํ ์ด๋ ์์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ ํจ๊ป ์ญ์ ๋๋ค.
-> ์์์ฑ์ด ํ์ํ ๋ฐ์ดํฐ๋? -> Volumes
ํธ์คํธ ํ์ผ ์์คํ ์ ๋์ปค์ ์ํด์๋ง ํต์ ๋๋ ๋์ปค Area์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ค
-> ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง์ง ์๋๋ค.
'STUDY > CLOUD' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์์ํ์ธ์ ๋์ปค/์ฟ ๋ฒ๋คํฐ์ค] 01. ๋์ปค๋? (1) 2023.09.26 [๊ฐ์] ๋ฐ๋ผํ๋ฉฐ ๋ฐฐ์ฐ๋ ๋์ปค์ CIํ๊ฒฝ -7 (3) 2022.07.05 [๊ฐ์] ๋ฐ๋ผํ๋ฉฐ ๋ฐฐ์ฐ๋ ๋์ปค์ CIํ๊ฒฝ -5 (0) 2022.06.21 [๊ฐ์] ๋ฐ๋ผํ๋ฉฐ ๋ฐฐ์ฐ๋ ๋์ปค์ CIํ๊ฒฝ -4 (0) 2022.05.31 [๊ฐ์] ๋ฐ๋ผํ๋ฉฐ ๋ฐฐ์ฐ๋ ๋์ปค์ CIํ๊ฒฝ -3 (0) 2022.05.24