/alpacasalon-backend

Primary LanguageTypeScriptGNU General Public License v3.0GPL-3.0

๐Ÿฆ™ ์•ŒํŒŒ์นด์‚ด๋กฑ (Alpacasalon) Backend

์•ŒํŒŒ์นด๊ฐ€ ๋ชจ์—ฌ ๊ณต๊ฐํ•ด์ฃผ๊ณ  ์ฆ๊ฒ๊ฒŒ ์–˜๊ธฐํ•˜๋Š” ๊ณต๊ฐ„

Requires

git --version
node --version
yarn --version
code --version
docker --version
docker-compose --version

์œ„ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋žจ์ด ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

Project structure

images/architecture.webp

Quick start

Download codes

git clone https://github.com/rmfpdlxmtidl/alpacasalon-backend.git
cd alpacasalon-backend
git checkout main
yarn

ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ณ  ํ•ด๋‹น ํด๋”๋กœ ์ด๋™ํ•œ ํ›„ ์ ์ ˆํ•œ ๋ธŒ๋žœ์น˜(main ๋“ฑ)๋กœ ์ด๋™ํ•˜๊ณ  ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ์™ธ๋ถ€ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ์ ํŠธ ํด๋”์—์„œ VSCode๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜ค๋ฅธ์ชฝ ์•„๋ž˜์— '๊ถŒ์žฅ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ ์„ค์น˜' ์•Œ๋ฆผ์ด ๋œจ๋Š”๋ฐ, ํ”„๋กœ์ ํŠธ์—์„œ ๊ถŒ์žฅํ•˜๋Š” ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ(ESLint, Prettier ๋“ฑ)์„ ๋ชจ๋‘ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

Create environment variables

๋ฃจํŠธ ํด๋”์— .env, .env.development, .env.development.local, .env.local, .env.test ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

Initialize database

yarn import ์˜ต์…˜

๊ทธ๋ฆฌ๊ณ  import ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ด database/initialization.sql์™€ CSV ํŒŒ์ผ๋กœ ๋˜์–ด ์žˆ๋Š” ๋”๋ฏธ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

Start Node.js server

$ yarn dev

TypeScript ํŒŒ์ผ์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ด Nodemon์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

or

$ yarn build && yarn start

TypeScript ํŒŒ์ผ์„ JavaScript๋กœ ํŠธ๋žœ์ŠคํŒŒ์ผํ•œ ํ›„ Node.js๋กœ ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

or

$ docker-compose up --detach --build --force-recreate

(Cloud Run ํ™˜๊ฒฝ๊ณผ ๋™์ผํ•œ) Docker ํ™˜๊ฒฝ์—์„œ Node.js ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Google Cloud Platform

Cloud Run

Cloud Run + Cloud Build๋ฅผ ํ†ตํ•ด GitHub์— commit์ด push๋  ๋•Œ๋งˆ๋‹ค Cloud Run์— ์ž๋™์œผ๋กœ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

Cloud SQL (For production database)

Configure database

CREATE USER alpacasalon CREATEDB;
-- \c postgres alpacasalon
CREATE DATABASE alpacasalon OWNER alpacasalon TEMPLATE template0 LC_COLLATE "C" LC_CTYPE "ko_KR.UTF-8";
-- \c alpacasalon postgres
-- ALTER SCHEMA public OWNER TO alpacasalon;

Connect to Cloud SQL with proxy

PROJECT_NAME=ํ”„๋กœ์ ํŠธID
CONNECTION_NAME=$PROJECT_NAME:๋ฆฌ์ „:์ธ์Šคํ„ด์ŠคID

gcloud auth login
gcloud config set project $PROJECT_NAME

curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
chmod +x cloud_sql_proxy
./cloud_sql_proxy -instances=$CONNECTION_NAME=tcp:54321

psql "host=127.0.0.1 port=54321 sslmode=disable dbname=$POSTGRES_DB user=$POSTGRES_USER"

Database schema update

yarn export-db .env
initialization.sql
CSV ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ˆ˜์ •
yarn import-db .env

Compute Engine (For development database)

Connect to Compute Engine via SSH

GCP_ID=GCP๊ณ„์ •์ด๋ฆ„
GCE_ID=GCE์ธ์Šคํ„ด์Šค์ด๋ฆ„

gcloud init
gcloud components update
gcloud compute ssh $GCP_ID@$GCE_ID

Run PostgreSQL container

# Set variables
DOCKER_VOLUME_NAME=๋„์ปค๋ณผ๋ฅจ์ด๋ฆ„
POSTGRES_HOST=DB์„œ๋ฒ„์ฃผ์†Œ
POSTGRES_USER=DB๊ณ„์ •์ด๋ฆ„
POSTGRES_PASSWORD=DB๊ณ„์ •์•”ํ˜ธ
POSTGRES_DB=DB์ด๋ฆ„

# generate the server.key and server.crt https://www.postgresql.org/docs/14/ssl-tcp.html
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=Alpacasalon"
chmod og-rwx root.key

openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=$POSTGRES_HOST"

openssl x509 -req -in server.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out server.crt

# set postgres (alpine) user as owner of the server.key and permissions to 600
sudo chown 0:70 server.key
sudo chmod 640 server.key

# set client connection policy
echo "
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# 'local' is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust

hostssl all all all scram-sha-256
" > pg_hba.conf

# start a postgres docker container, mapping the .key and .crt into the image.
sudo docker volume create $DOCKER_VOLUME_NAME
sudo docker run \
  -d \
  -e POSTGRES_USER=$POSTGRES_USER \
  -e POSTGRES_PASSWORD=$POSTGRES_PASSWORD \
  -e POSTGRES_DB=$POSTGRES_DB \
  -e LANG=ko_KR.UTF8 \
  -e LC_COLLATE=C \
  -e POSTGRES_INITDB_ARGS=--data-checksums \
  --name postgres \
  -p 5432:5432 \
  --restart=always \
  --shm-size=256MB \
  -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro" \
  -v "$PWD/server.key:/var/lib/postgresql/server.key:ro" \
  -v "$PWD/pg_hba.conf:/var/lib/postgresql/pg_hba.conf" \
  -v $DOCKER_VOLUME_NAME:/var/lib/postgresql/data \
  postgres:14-alpine \
  -c ssl=on \
  -c ssl_cert_file=/var/lib/postgresql/server.crt \
  -c ssl_key_file=/var/lib/postgresql/server.key \
  -c hba_file=/var/lib/postgresql/pg_hba.conf

๋„์ปค๋ฅผ ํ†ตํ•ด PostgreSQL ์ปจํ…Œ์ด๋„ˆ์™€ ๋„์ปค ๋ณผ๋ฅจ์„ ์ƒ์„ฑํ•˜๊ณ , OpenSSL์„ ์ด์šฉํ•ด ์ž์ฒด ์„œ๋ช…๋œ ์ธ์ฆ์„œ๋ฅผ ์ƒ์„ฑํ•ด์„œ SSL ์—ฐ๊ฒฐ์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

Test connection

# Set variables
POSTGRES_HOST=DB์„œ๋ฒ„์ฃผ์†Œ
POSTGRES_USER=DB๊ณ„์ •์ด๋ฆ„
POSTGRES_DB=DB์ด๋ฆ„

psql "host=$POSTGRES_HOST port=5432 dbname=$POSTGRES_DB user=$POSTGRES_USER sslmode=verify-ca"

Cloud Function

Slack

# https://github.com/rmfpdlxmtidl/google-cloud-build-slack
export SLACK_WEBHOOK_URL=
export PROJECT_ID=
./setup.sh

Scripts

test

์‹คํ–‰ ์ค‘์ธ GraphQL ์„œ๋ฒ„์— ํ…Œ์ŠคํŠธ์šฉ GraphQL ์ฟผ๋ฆฌ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ ํ•˜๊ธฐ ์ „์— localhost ๋˜๋Š” ์›๊ฒฉ์—์„œ GraphQL API ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

generate-db

$ yarn generate-db {ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํŒŒ์ผ ์œ„์น˜}

PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์กฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ TypeScript ๊ธฐ๋ฐ˜ ์ž๋ฃŒํ˜•์ด ๋‹ด๊ธด ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

export

$ yarn export ์˜ต์…˜

PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ๋Š” ๋ชจ๋“  ์Šคํ‚ค๋งˆ์˜ ๋ชจ๋“  ํ…Œ์ด๋ธ”์„ CSV ํŒŒ์ผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋”๋ฏธ ๋ฐ์ดํ„ฐ CSV ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „์— ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

import

$ yarn import ์˜ต์…˜

CSV ํŒŒ์ผ์„ PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

Slack

https://slack.github.com/

# https://github.com/integrations/slack#subscribing-and-unsubscribing
/github subscribe rmfpdlxmtidl/alpacasalon-backend commits:* reviews comments
/github unsubscribe rmfpdlxmtidl/alpacasalon-backend deployments