Docker에서 React와 MariaDB를 사용하여 웹 서비스의 병아리 만들기
17458 단어 docker-composeReact도커mariadb
목적
Docker 도입까지
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 && \
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \
sudo yum makecache fast && \
sudo yum install -y docker-ce && \
sudo usermod -aG docker $USER && \
sudo systemctl enable docker
sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname \
-s`-`uname -m` -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose
# バージョン確認して再起動
docker-compose --version
sudo reboot
컨테이너 구성
다음 3개의 컨테이너를 만든다.
Python3 설치
sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm && \
yum search python36 && \
sudo yum install -y python36u python36u-libs python36u-devel python36u-pip && \
sudo ln -s /usr/bin/python3.6 /usr/bin/python3 && \
sudo ln -s /usr/bin/pip3.6 /usr/bin/pip3 && \
python3 --version && pip3 --version
sudo pip3 install pip --upgrade && \
sudo pip3 install sqlalchemy && \
sudo pip3 install PyMySQL && \
sudo pip3 install pandas
MariaDB 클라이언트 설치
sudo yum install -y mariadb
MariaDB 컨테이너 만들기
mkdir docker && cd docker
mkdir container && mkdir container/mariadb && mkdir container/mariadb/init
cat << EOF > container/mariadb/multibyte.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
EOF
# Dockerfileの作成とDocker-composeに設定を追記
cat << EOF > container/mariadb/Dockerfile
FROM mariadb
EXPOSE 3306
EOF
cat << EOF > docker-compose.yaml
version: '3'
services:
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
EOF
docker-compose up
MariaDB의 동작 확인
다른 터미널에서…
cd ~/docker
# テストデータの準備
cat << EOF > test_data.csv
ID,Name,Birthdate,Sex,Occupation,Salary
ID-0001,Abe,1985/1/1,M,Engineer,8422213
ID-0002,Saito,1970/2/11,F,Professor,8222588
ID-0003,Yamada,1975/3/21,M,Doctor,9845288
ID-0004,田中,1980/4/22,F,Sales,8505218
ID-0005,Okamoto,1995/5/25,M,Student,218103
EOF
cat << EOF > test_data.py
import pandas as pd
import sqlalchemy as sa
df = pd.read_csv("test_data.csv")
url = 'mysql+pymysql://username:[email protected]/app?charset=utf8'
engine = sa.create_engine(url, echo=True)
df.to_sql('table1', engine, index=False, if_exists='replace')
EOF
python3 test_data.py test_data.csv && rm test_data.csv && rm test_data.py
mysql -u root -prootpass -h 127.0.0.1
> use app
> SELECT * FROM table1;
# UTF8出力チェック
> exit
일단 docker-compose를 중지
노드 컨테이너 작성
mkdir container/node && mkdir app && mkdir app/src && mkdir app/dist && mkdir app/node_modules
cat << EOF > container/node/Dockerfile
FROM node:9
WORKDIR app
RUN npm install -g npm
EOF
cat << EOF >> docker-compose.yaml
node:
build:
context: ./container/node
container_name: my-node
image: my-node
volumes:
- ./app:/app:z
ports:
- "80:8080"
EOF
docker-compose build
npm install
완성 package.json 준비한 npm update는 무겁고 거동이 수상하기 때문에 조금씩 넣는다.
dev계는 서버에서는 불필요한 것도 있지만 로컬과 설정을 공통으로 하기 위해서 넣어 둔다.
docker-compose run node npm init -y
docker-compose run node npm i -D webpack webpack-cli webpack-dev-server babel-core babel-loader babel-preset-env babel-preset-react babel-polyfill
docker-compose run node npm i -D uglifyjs-webpack-plugin sass-loader node-sass style-loader css-loader style-loader css-loader url-loader
docker-compose run node npm i -S react react-dom redux react-redux
docker-compose run node npm i -D redux-devtools react-hot-loader
docker-compose run node npm i -D eslint eslint-loader eslint-plugin-node eslint-plugin-react babel-eslint
docker-compose run node npm i -D node-mariadb
설정 파일 준비
webpack4로 설정이 쉬워졌지만 충분히 복잡하다.
cat << EOF > update_package_json.py
import json
import collections
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
with open('app/package.json') as read_file:
data = decoder.decode(read_file.read())
data["name"] = "react-test"
data["version"] = "0.1.0"
data["author"] = "tibigame"
data["description"] = "react-test"
data["scripts"]["build"] = "webpack"
data["scripts"]["start"] = "babel-node ./src/server.js"
data["scripts"]["dev"] = "webpack-dev-server --hot"
data["scripts"]["watch"] = "webpack -d --watch --progress"
fw = open('app/package2.json','w')
json.dump(data, fw, indent=4)
EOF
python3 update_package_json.py && rm -rf app/package.json && mv app/package2.json app/package.json
cat << EOF > app/webpack.config.js
module.exports = {
mode: 'production',
entry: [
'babel-polyfill',
'./src/index.js',
],
output: {
filename: 'main.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
],
exclude: /node_modules/
},
{
test: /\.scss/,
use: [
'style-loader',
{loader: 'css-loader', options: {url: false}},
],
}
]
}
};
EOF
cat << EOF > app/.babelrc
{
"presets": [
"react",
["env", {
"targets": {
"browsers": ["last 2 versions"]
},
"modules": false
}
]
],
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
"react-hot-loader/babel"
]
}
EOF
React 및 SCSS 확인 파일 준비
cat << EOF > app/dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
body {
background: #eee;
}
#app {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
<script defer src="main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
EOF
cat << EOF > app/src/style.scss
$red: #FF3333;
h1 {
color: $red;
}
EOF
cat << EOF > app/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./style.scss"
import {TestComponent} from './test_component';
class App extends React.Component {
render() {
return (
<div>
<h1>Hello React!</h1>
<TestComponent name="My Counter for Babel" />
</div>
);
}
}
console.log('テスト');
ReactDOM.render(<App/>, document.querySelector('#app'));
EOF
cat << EOF > app/src/test_component.js
import React from 'react';
export class TestComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
handleClick() {
console.log('クリックされました');
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<h2>{this.props.name}</h2>
<div>{this.state.count}</div>
<button onClick={this.handleClick.bind(this)}>Add +1</button>
</div>
);
}
}
EOF
Nginx 컨테이너 만들기
여기의 설정은 잘 이해하고 있지 않지만, 제한해 두면 개발중에서도 문제 없을 것이다.
mkdir container/nginx
sudo yum install -y httpd-tools
htpasswd -c ./container/nginx/.htpasswd http_user
password
cat << EOF > container/nginx/Dockerfile
FROM nginx
EOF
vim container/nginx/default.conf
--------
server {
listen 8080;
server_name localhost;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /www/app;
}
# IPアドレスによる制限
allow xxx.xxx.xxx.xxx;
deny all;
# BASIC認証による制限
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
--------
cat << EOF > docker-compose.yaml
version: '3'
services:
node:
build:
context: ./container/node
container_name: my-node
image: my-node
command: npm run build
volumes:
- ./app:/app:z
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
expose:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
nginx:
build:
context: ./container/nginx
image: nginx
container_name: nginx
ports:
- '80:8080'
volumes:
- ./container/nginx:/etc/nginx/conf.d:ro
- ./app/dist:/www/app:ro
links:
- 'node'
- 'mariadb'
EOF
docker-compose run node npm run build
docker-compose up
브라우저에서의 동작 확인
우선 React의 컴퍼넌트는 제대로 빌드되어 Nginx도 기능하고 있는 것 같다.
하지만 데이터베이스와의 연결은 일근줄이 아니었다.
TODO
sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm && \
yum search python36 && \
sudo yum install -y python36u python36u-libs python36u-devel python36u-pip && \
sudo ln -s /usr/bin/python3.6 /usr/bin/python3 && \
sudo ln -s /usr/bin/pip3.6 /usr/bin/pip3 && \
python3 --version && pip3 --version
sudo pip3 install pip --upgrade && \
sudo pip3 install sqlalchemy && \
sudo pip3 install PyMySQL && \
sudo pip3 install pandas
sudo yum install -y mariadb
MariaDB 컨테이너 만들기
mkdir docker && cd docker
mkdir container && mkdir container/mariadb && mkdir container/mariadb/init
cat << EOF > container/mariadb/multibyte.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
EOF
# Dockerfileの作成とDocker-composeに設定を追記
cat << EOF > container/mariadb/Dockerfile
FROM mariadb
EXPOSE 3306
EOF
cat << EOF > docker-compose.yaml
version: '3'
services:
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
EOF
docker-compose up
MariaDB의 동작 확인
다른 터미널에서…
cd ~/docker
# テストデータの準備
cat << EOF > test_data.csv
ID,Name,Birthdate,Sex,Occupation,Salary
ID-0001,Abe,1985/1/1,M,Engineer,8422213
ID-0002,Saito,1970/2/11,F,Professor,8222588
ID-0003,Yamada,1975/3/21,M,Doctor,9845288
ID-0004,田中,1980/4/22,F,Sales,8505218
ID-0005,Okamoto,1995/5/25,M,Student,218103
EOF
cat << EOF > test_data.py
import pandas as pd
import sqlalchemy as sa
df = pd.read_csv("test_data.csv")
url = 'mysql+pymysql://username:[email protected]/app?charset=utf8'
engine = sa.create_engine(url, echo=True)
df.to_sql('table1', engine, index=False, if_exists='replace')
EOF
python3 test_data.py test_data.csv && rm test_data.csv && rm test_data.py
mysql -u root -prootpass -h 127.0.0.1
> use app
> SELECT * FROM table1;
# UTF8出力チェック
> exit
일단 docker-compose를 중지
노드 컨테이너 작성
mkdir container/node && mkdir app && mkdir app/src && mkdir app/dist && mkdir app/node_modules
cat << EOF > container/node/Dockerfile
FROM node:9
WORKDIR app
RUN npm install -g npm
EOF
cat << EOF >> docker-compose.yaml
node:
build:
context: ./container/node
container_name: my-node
image: my-node
volumes:
- ./app:/app:z
ports:
- "80:8080"
EOF
docker-compose build
npm install
완성 package.json 준비한 npm update는 무겁고 거동이 수상하기 때문에 조금씩 넣는다.
dev계는 서버에서는 불필요한 것도 있지만 로컬과 설정을 공통으로 하기 위해서 넣어 둔다.
docker-compose run node npm init -y
docker-compose run node npm i -D webpack webpack-cli webpack-dev-server babel-core babel-loader babel-preset-env babel-preset-react babel-polyfill
docker-compose run node npm i -D uglifyjs-webpack-plugin sass-loader node-sass style-loader css-loader style-loader css-loader url-loader
docker-compose run node npm i -S react react-dom redux react-redux
docker-compose run node npm i -D redux-devtools react-hot-loader
docker-compose run node npm i -D eslint eslint-loader eslint-plugin-node eslint-plugin-react babel-eslint
docker-compose run node npm i -D node-mariadb
설정 파일 준비
webpack4로 설정이 쉬워졌지만 충분히 복잡하다.
cat << EOF > update_package_json.py
import json
import collections
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
with open('app/package.json') as read_file:
data = decoder.decode(read_file.read())
data["name"] = "react-test"
data["version"] = "0.1.0"
data["author"] = "tibigame"
data["description"] = "react-test"
data["scripts"]["build"] = "webpack"
data["scripts"]["start"] = "babel-node ./src/server.js"
data["scripts"]["dev"] = "webpack-dev-server --hot"
data["scripts"]["watch"] = "webpack -d --watch --progress"
fw = open('app/package2.json','w')
json.dump(data, fw, indent=4)
EOF
python3 update_package_json.py && rm -rf app/package.json && mv app/package2.json app/package.json
cat << EOF > app/webpack.config.js
module.exports = {
mode: 'production',
entry: [
'babel-polyfill',
'./src/index.js',
],
output: {
filename: 'main.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
],
exclude: /node_modules/
},
{
test: /\.scss/,
use: [
'style-loader',
{loader: 'css-loader', options: {url: false}},
],
}
]
}
};
EOF
cat << EOF > app/.babelrc
{
"presets": [
"react",
["env", {
"targets": {
"browsers": ["last 2 versions"]
},
"modules": false
}
]
],
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
"react-hot-loader/babel"
]
}
EOF
React 및 SCSS 확인 파일 준비
cat << EOF > app/dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
body {
background: #eee;
}
#app {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
<script defer src="main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
EOF
cat << EOF > app/src/style.scss
$red: #FF3333;
h1 {
color: $red;
}
EOF
cat << EOF > app/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./style.scss"
import {TestComponent} from './test_component';
class App extends React.Component {
render() {
return (
<div>
<h1>Hello React!</h1>
<TestComponent name="My Counter for Babel" />
</div>
);
}
}
console.log('テスト');
ReactDOM.render(<App/>, document.querySelector('#app'));
EOF
cat << EOF > app/src/test_component.js
import React from 'react';
export class TestComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
handleClick() {
console.log('クリックされました');
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<h2>{this.props.name}</h2>
<div>{this.state.count}</div>
<button onClick={this.handleClick.bind(this)}>Add +1</button>
</div>
);
}
}
EOF
Nginx 컨테이너 만들기
여기의 설정은 잘 이해하고 있지 않지만, 제한해 두면 개발중에서도 문제 없을 것이다.
mkdir container/nginx
sudo yum install -y httpd-tools
htpasswd -c ./container/nginx/.htpasswd http_user
password
cat << EOF > container/nginx/Dockerfile
FROM nginx
EOF
vim container/nginx/default.conf
--------
server {
listen 8080;
server_name localhost;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /www/app;
}
# IPアドレスによる制限
allow xxx.xxx.xxx.xxx;
deny all;
# BASIC認証による制限
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
--------
cat << EOF > docker-compose.yaml
version: '3'
services:
node:
build:
context: ./container/node
container_name: my-node
image: my-node
command: npm run build
volumes:
- ./app:/app:z
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
expose:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
nginx:
build:
context: ./container/nginx
image: nginx
container_name: nginx
ports:
- '80:8080'
volumes:
- ./container/nginx:/etc/nginx/conf.d:ro
- ./app/dist:/www/app:ro
links:
- 'node'
- 'mariadb'
EOF
docker-compose run node npm run build
docker-compose up
브라우저에서의 동작 확인
우선 React의 컴퍼넌트는 제대로 빌드되어 Nginx도 기능하고 있는 것 같다.
하지만 데이터베이스와의 연결은 일근줄이 아니었다.
TODO
mkdir docker && cd docker
mkdir container && mkdir container/mariadb && mkdir container/mariadb/init
cat << EOF > container/mariadb/multibyte.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
EOF
# Dockerfileの作成とDocker-composeに設定を追記
cat << EOF > container/mariadb/Dockerfile
FROM mariadb
EXPOSE 3306
EOF
cat << EOF > docker-compose.yaml
version: '3'
services:
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
EOF
docker-compose up
다른 터미널에서…
cd ~/docker
# テストデータの準備
cat << EOF > test_data.csv
ID,Name,Birthdate,Sex,Occupation,Salary
ID-0001,Abe,1985/1/1,M,Engineer,8422213
ID-0002,Saito,1970/2/11,F,Professor,8222588
ID-0003,Yamada,1975/3/21,M,Doctor,9845288
ID-0004,田中,1980/4/22,F,Sales,8505218
ID-0005,Okamoto,1995/5/25,M,Student,218103
EOF
cat << EOF > test_data.py
import pandas as pd
import sqlalchemy as sa
df = pd.read_csv("test_data.csv")
url = 'mysql+pymysql://username:[email protected]/app?charset=utf8'
engine = sa.create_engine(url, echo=True)
df.to_sql('table1', engine, index=False, if_exists='replace')
EOF
python3 test_data.py test_data.csv && rm test_data.csv && rm test_data.py
mysql -u root -prootpass -h 127.0.0.1
> use app
> SELECT * FROM table1;
# UTF8出力チェック
> exit
일단 docker-compose를 중지
노드 컨테이너 작성
mkdir container/node && mkdir app && mkdir app/src && mkdir app/dist && mkdir app/node_modules
cat << EOF > container/node/Dockerfile
FROM node:9
WORKDIR app
RUN npm install -g npm
EOF
cat << EOF >> docker-compose.yaml
node:
build:
context: ./container/node
container_name: my-node
image: my-node
volumes:
- ./app:/app:z
ports:
- "80:8080"
EOF
docker-compose build
npm install
완성 package.json 준비한 npm update는 무겁고 거동이 수상하기 때문에 조금씩 넣는다.
dev계는 서버에서는 불필요한 것도 있지만 로컬과 설정을 공통으로 하기 위해서 넣어 둔다.
docker-compose run node npm init -y
docker-compose run node npm i -D webpack webpack-cli webpack-dev-server babel-core babel-loader babel-preset-env babel-preset-react babel-polyfill
docker-compose run node npm i -D uglifyjs-webpack-plugin sass-loader node-sass style-loader css-loader style-loader css-loader url-loader
docker-compose run node npm i -S react react-dom redux react-redux
docker-compose run node npm i -D redux-devtools react-hot-loader
docker-compose run node npm i -D eslint eslint-loader eslint-plugin-node eslint-plugin-react babel-eslint
docker-compose run node npm i -D node-mariadb
설정 파일 준비
webpack4로 설정이 쉬워졌지만 충분히 복잡하다.
cat << EOF > update_package_json.py
import json
import collections
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
with open('app/package.json') as read_file:
data = decoder.decode(read_file.read())
data["name"] = "react-test"
data["version"] = "0.1.0"
data["author"] = "tibigame"
data["description"] = "react-test"
data["scripts"]["build"] = "webpack"
data["scripts"]["start"] = "babel-node ./src/server.js"
data["scripts"]["dev"] = "webpack-dev-server --hot"
data["scripts"]["watch"] = "webpack -d --watch --progress"
fw = open('app/package2.json','w')
json.dump(data, fw, indent=4)
EOF
python3 update_package_json.py && rm -rf app/package.json && mv app/package2.json app/package.json
cat << EOF > app/webpack.config.js
module.exports = {
mode: 'production',
entry: [
'babel-polyfill',
'./src/index.js',
],
output: {
filename: 'main.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
],
exclude: /node_modules/
},
{
test: /\.scss/,
use: [
'style-loader',
{loader: 'css-loader', options: {url: false}},
],
}
]
}
};
EOF
cat << EOF > app/.babelrc
{
"presets": [
"react",
["env", {
"targets": {
"browsers": ["last 2 versions"]
},
"modules": false
}
]
],
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
"react-hot-loader/babel"
]
}
EOF
React 및 SCSS 확인 파일 준비
cat << EOF > app/dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
body {
background: #eee;
}
#app {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
<script defer src="main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
EOF
cat << EOF > app/src/style.scss
$red: #FF3333;
h1 {
color: $red;
}
EOF
cat << EOF > app/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./style.scss"
import {TestComponent} from './test_component';
class App extends React.Component {
render() {
return (
<div>
<h1>Hello React!</h1>
<TestComponent name="My Counter for Babel" />
</div>
);
}
}
console.log('テスト');
ReactDOM.render(<App/>, document.querySelector('#app'));
EOF
cat << EOF > app/src/test_component.js
import React from 'react';
export class TestComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
handleClick() {
console.log('クリックされました');
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<h2>{this.props.name}</h2>
<div>{this.state.count}</div>
<button onClick={this.handleClick.bind(this)}>Add +1</button>
</div>
);
}
}
EOF
Nginx 컨테이너 만들기
여기의 설정은 잘 이해하고 있지 않지만, 제한해 두면 개발중에서도 문제 없을 것이다.
mkdir container/nginx
sudo yum install -y httpd-tools
htpasswd -c ./container/nginx/.htpasswd http_user
password
cat << EOF > container/nginx/Dockerfile
FROM nginx
EOF
vim container/nginx/default.conf
--------
server {
listen 8080;
server_name localhost;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /www/app;
}
# IPアドレスによる制限
allow xxx.xxx.xxx.xxx;
deny all;
# BASIC認証による制限
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
--------
cat << EOF > docker-compose.yaml
version: '3'
services:
node:
build:
context: ./container/node
container_name: my-node
image: my-node
command: npm run build
volumes:
- ./app:/app:z
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
expose:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
nginx:
build:
context: ./container/nginx
image: nginx
container_name: nginx
ports:
- '80:8080'
volumes:
- ./container/nginx:/etc/nginx/conf.d:ro
- ./app/dist:/www/app:ro
links:
- 'node'
- 'mariadb'
EOF
docker-compose run node npm run build
docker-compose up
브라우저에서의 동작 확인
우선 React의 컴퍼넌트는 제대로 빌드되어 Nginx도 기능하고 있는 것 같다.
하지만 데이터베이스와의 연결은 일근줄이 아니었다.
TODO
mkdir container/node && mkdir app && mkdir app/src && mkdir app/dist && mkdir app/node_modules
cat << EOF > container/node/Dockerfile
FROM node:9
WORKDIR app
RUN npm install -g npm
EOF
cat << EOF >> docker-compose.yaml
node:
build:
context: ./container/node
container_name: my-node
image: my-node
volumes:
- ./app:/app:z
ports:
- "80:8080"
EOF
docker-compose build
완성 package.json 준비한 npm update는 무겁고 거동이 수상하기 때문에 조금씩 넣는다.
dev계는 서버에서는 불필요한 것도 있지만 로컬과 설정을 공통으로 하기 위해서 넣어 둔다.
docker-compose run node npm init -y
docker-compose run node npm i -D webpack webpack-cli webpack-dev-server babel-core babel-loader babel-preset-env babel-preset-react babel-polyfill
docker-compose run node npm i -D uglifyjs-webpack-plugin sass-loader node-sass style-loader css-loader style-loader css-loader url-loader
docker-compose run node npm i -S react react-dom redux react-redux
docker-compose run node npm i -D redux-devtools react-hot-loader
docker-compose run node npm i -D eslint eslint-loader eslint-plugin-node eslint-plugin-react babel-eslint
docker-compose run node npm i -D node-mariadb
설정 파일 준비
webpack4로 설정이 쉬워졌지만 충분히 복잡하다.
cat << EOF > update_package_json.py
import json
import collections
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
with open('app/package.json') as read_file:
data = decoder.decode(read_file.read())
data["name"] = "react-test"
data["version"] = "0.1.0"
data["author"] = "tibigame"
data["description"] = "react-test"
data["scripts"]["build"] = "webpack"
data["scripts"]["start"] = "babel-node ./src/server.js"
data["scripts"]["dev"] = "webpack-dev-server --hot"
data["scripts"]["watch"] = "webpack -d --watch --progress"
fw = open('app/package2.json','w')
json.dump(data, fw, indent=4)
EOF
python3 update_package_json.py && rm -rf app/package.json && mv app/package2.json app/package.json
cat << EOF > app/webpack.config.js
module.exports = {
mode: 'production',
entry: [
'babel-polyfill',
'./src/index.js',
],
output: {
filename: 'main.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
],
exclude: /node_modules/
},
{
test: /\.scss/,
use: [
'style-loader',
{loader: 'css-loader', options: {url: false}},
],
}
]
}
};
EOF
cat << EOF > app/.babelrc
{
"presets": [
"react",
["env", {
"targets": {
"browsers": ["last 2 versions"]
},
"modules": false
}
]
],
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
"react-hot-loader/babel"
]
}
EOF
React 및 SCSS 확인 파일 준비
cat << EOF > app/dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
body {
background: #eee;
}
#app {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
<script defer src="main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
EOF
cat << EOF > app/src/style.scss
$red: #FF3333;
h1 {
color: $red;
}
EOF
cat << EOF > app/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./style.scss"
import {TestComponent} from './test_component';
class App extends React.Component {
render() {
return (
<div>
<h1>Hello React!</h1>
<TestComponent name="My Counter for Babel" />
</div>
);
}
}
console.log('テスト');
ReactDOM.render(<App/>, document.querySelector('#app'));
EOF
cat << EOF > app/src/test_component.js
import React from 'react';
export class TestComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
handleClick() {
console.log('クリックされました');
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<h2>{this.props.name}</h2>
<div>{this.state.count}</div>
<button onClick={this.handleClick.bind(this)}>Add +1</button>
</div>
);
}
}
EOF
Nginx 컨테이너 만들기
여기의 설정은 잘 이해하고 있지 않지만, 제한해 두면 개발중에서도 문제 없을 것이다.
mkdir container/nginx
sudo yum install -y httpd-tools
htpasswd -c ./container/nginx/.htpasswd http_user
password
cat << EOF > container/nginx/Dockerfile
FROM nginx
EOF
vim container/nginx/default.conf
--------
server {
listen 8080;
server_name localhost;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /www/app;
}
# IPアドレスによる制限
allow xxx.xxx.xxx.xxx;
deny all;
# BASIC認証による制限
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
--------
cat << EOF > docker-compose.yaml
version: '3'
services:
node:
build:
context: ./container/node
container_name: my-node
image: my-node
command: npm run build
volumes:
- ./app:/app:z
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
expose:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
nginx:
build:
context: ./container/nginx
image: nginx
container_name: nginx
ports:
- '80:8080'
volumes:
- ./container/nginx:/etc/nginx/conf.d:ro
- ./app/dist:/www/app:ro
links:
- 'node'
- 'mariadb'
EOF
docker-compose run node npm run build
docker-compose up
브라우저에서의 동작 확인
우선 React의 컴퍼넌트는 제대로 빌드되어 Nginx도 기능하고 있는 것 같다.
하지만 데이터베이스와의 연결은 일근줄이 아니었다.
TODO
cat << EOF > update_package_json.py
import json
import collections
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
with open('app/package.json') as read_file:
data = decoder.decode(read_file.read())
data["name"] = "react-test"
data["version"] = "0.1.0"
data["author"] = "tibigame"
data["description"] = "react-test"
data["scripts"]["build"] = "webpack"
data["scripts"]["start"] = "babel-node ./src/server.js"
data["scripts"]["dev"] = "webpack-dev-server --hot"
data["scripts"]["watch"] = "webpack -d --watch --progress"
fw = open('app/package2.json','w')
json.dump(data, fw, indent=4)
EOF
python3 update_package_json.py && rm -rf app/package.json && mv app/package2.json app/package.json
cat << EOF > app/webpack.config.js
module.exports = {
mode: 'production',
entry: [
'babel-polyfill',
'./src/index.js',
],
output: {
filename: 'main.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
],
exclude: /node_modules/
},
{
test: /\.scss/,
use: [
'style-loader',
{loader: 'css-loader', options: {url: false}},
],
}
]
}
};
EOF
cat << EOF > app/.babelrc
{
"presets": [
"react",
["env", {
"targets": {
"browsers": ["last 2 versions"]
},
"modules": false
}
]
],
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
"react-hot-loader/babel"
]
}
EOF
cat << EOF > app/dist/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<style>
body {
background: #eee;
}
#app {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
<script defer src="main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
EOF
cat << EOF > app/src/style.scss
$red: #FF3333;
h1 {
color: $red;
}
EOF
cat << EOF > app/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import "./style.scss"
import {TestComponent} from './test_component';
class App extends React.Component {
render() {
return (
<div>
<h1>Hello React!</h1>
<TestComponent name="My Counter for Babel" />
</div>
);
}
}
console.log('テスト');
ReactDOM.render(<App/>, document.querySelector('#app'));
EOF
cat << EOF > app/src/test_component.js
import React from 'react';
export class TestComponent extends React.Component {
constructor() {
super();
this.state = {
count: 0
};
}
handleClick() {
console.log('クリックされました');
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<h2>{this.props.name}</h2>
<div>{this.state.count}</div>
<button onClick={this.handleClick.bind(this)}>Add +1</button>
</div>
);
}
}
EOF
Nginx 컨테이너 만들기
여기의 설정은 잘 이해하고 있지 않지만, 제한해 두면 개발중에서도 문제 없을 것이다.
mkdir container/nginx
sudo yum install -y httpd-tools
htpasswd -c ./container/nginx/.htpasswd http_user
password
cat << EOF > container/nginx/Dockerfile
FROM nginx
EOF
vim container/nginx/default.conf
--------
server {
listen 8080;
server_name localhost;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /www/app;
}
# IPアドレスによる制限
allow xxx.xxx.xxx.xxx;
deny all;
# BASIC認証による制限
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
--------
cat << EOF > docker-compose.yaml
version: '3'
services:
node:
build:
context: ./container/node
container_name: my-node
image: my-node
command: npm run build
volumes:
- ./app:/app:z
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
expose:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
nginx:
build:
context: ./container/nginx
image: nginx
container_name: nginx
ports:
- '80:8080'
volumes:
- ./container/nginx:/etc/nginx/conf.d:ro
- ./app/dist:/www/app:ro
links:
- 'node'
- 'mariadb'
EOF
docker-compose run node npm run build
docker-compose up
브라우저에서의 동작 확인
우선 React의 컴퍼넌트는 제대로 빌드되어 Nginx도 기능하고 있는 것 같다.
하지만 데이터베이스와의 연결은 일근줄이 아니었다.
TODO
mkdir container/nginx
sudo yum install -y httpd-tools
htpasswd -c ./container/nginx/.htpasswd http_user
password
cat << EOF > container/nginx/Dockerfile
FROM nginx
EOF
vim container/nginx/default.conf
--------
server {
listen 8080;
server_name localhost;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /www/app;
}
# IPアドレスによる制限
allow xxx.xxx.xxx.xxx;
deny all;
# BASIC認証による制限
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
}
--------
cat << EOF > docker-compose.yaml
version: '3'
services:
node:
build:
context: ./container/node
container_name: my-node
image: my-node
command: npm run build
volumes:
- ./app:/app:z
mariadb:
build:
context: ./container/mariadb
container_name: mariadb
image: mariadb
volumes:
- ./mariadb_data:/var/lib/mysql:z
- ./container/mariadb/multibyte.cnf:/etc/mysql/conf.d/multibyte.cnf
- ./container/mariadb/init:/docker-entrypoint-initdb.d
expose:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=app
- MYSQL_USER=username
- MYSQL_PASSWORD=secret
nginx:
build:
context: ./container/nginx
image: nginx
container_name: nginx
ports:
- '80:8080'
volumes:
- ./container/nginx:/etc/nginx/conf.d:ro
- ./app/dist:/www/app:ro
links:
- 'node'
- 'mariadb'
EOF
docker-compose run node npm run build
docker-compose up
우선 React의 컴퍼넌트는 제대로 빌드되어 Nginx도 기능하고 있는 것 같다.
하지만 데이터베이스와의 연결은 일근줄이 아니었다.
TODO
Reference
이 문제에 관하여(Docker에서 React와 MariaDB를 사용하여 웹 서비스의 병아리 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tibigame/items/2c3b51dd7c0cca401889텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)