diff --git a/.env.sample b/.env.sample index 5cd8a6d..aa51925 100644 --- a/.env.sample +++ b/.env.sample @@ -1,5 +1,5 @@ # node server -NODE_ENV=production +NODE_ENV=development # postgres 설정 @@ -8,7 +8,8 @@ POSTGRES_PORT=5432 # postgres host -POSTGRES_HOST= +# dev - localhost, production - matjum-db 라고 써주세요. +POSTGRES_HOST=loclahost # postgres database 이름 POSTGRES_DB= diff --git a/Dockerfiles/db/Dockerfile b/Dockerfiles/db/Dockerfile new file mode 100644 index 0000000..e4175f8 --- /dev/null +++ b/Dockerfiles/db/Dockerfile @@ -0,0 +1,24 @@ +FROM postgres:16.4-bullseye + +# PostGIS 주 버전 설정 +ENV POSTGIS_MAJOR=3 +ENV POSTGIS_VERSION=3.4.2+dfsg-1.pgdg110+1 + +# 필요한 패키지 설치 및 PostGIS 설치 +# 인증서 오류 발생할 경우 ca-certificates 패키지 설치 +RUN apt-get update \ + && apt-cache showpkg postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR \ + && apt-get install -y --no-install-recommends \ + postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR=$POSTGIS_VERSION \ + postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR-scripts \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /docker-entrypoint-initdb.d +# PostGIS 초기화 스크립트 추가 +COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh +# PostGIS 업데이트 스크립트 추가 +COPY ./update-postgis.sh /usr/local/bin + +RUN chmod +x /docker-entrypoint-initdb.d/10_postgis.sh + +ENV POSTGRES_DB=gis diff --git a/Dockerfiles/db/initdb-postgis.sh b/Dockerfiles/db/initdb-postgis.sh new file mode 100644 index 0000000..c5e12d9 --- /dev/null +++ b/Dockerfiles/db/initdb-postgis.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +echo "Loading PostGIS extensions into $POSTGRES_DB" +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE EXTENSION IF NOT EXISTS postgis; +EOSQL diff --git a/Dockerfiles/db/update-postgis.sh b/Dockerfiles/db/update-postgis.sh new file mode 100644 index 0000000..48761f1 --- /dev/null +++ b/Dockerfiles/db/update-postgis.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e + +# Perform all actions as $POSTGRES_USER +export PGUSER="$POSTGRES_USER" + +# PostGIS 버전 설정 +POSTGIS_VERSION="${POSTGIS_VERSION%%+*}" + +# $POSTGRES_DB에 PostGIS 설치, 업데이트 +echo "Installing PostGIS extension to $POSTGRES_DB" +psql --dbname="$POSTGRES_DB" -c " + -- Install PostGIS (includes raster) + CREATE EXTENSION IF NOT EXISTS postgis VERSION '$POSTGIS_VERSION'; + ALTER EXTENSION postgis UPDATE TO '$POSTGIS_VERSION'; +" diff --git a/Dockerfile b/Dockerfiles/server/Dockerfile similarity index 100% rename from Dockerfile rename to Dockerfiles/server/Dockerfile diff --git a/README.md b/README.md index 0cd5805..cb09bbb 100644 --- a/README.md +++ b/README.md @@ -55,5 +55,10 @@ ## 컨테이너 종료 -- `npm run docker:dev:down` 혹은 `npm run docker:prod:down` 명령어로 컨테이너를 종료할 수 있습니다. +- `npm run docker:dev:stop` 혹은 `npm run docker:prod:stop` 명령어로 컨테이너를 종료할 수 있습니다. - `docker stop` 이나 `docker compose down -f <파일명>` 명령어로도 종료할 수 있습니다. + +## docker volume 삭제해야 할 때 (DB 테이블 변경 등) + +- database 다 날아가니 주의해서 사용해주세요. +- `docker volume rm matjum_db_data` 명령어로 삭제합니다. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 96f04a5..05bf028 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,11 +1,13 @@ services: db: container_name: matjum_db - image: postgres:16.4-alpine + build: + context: ./Dockerfiles/db restart: always env_file: - .env volumes: + - ./init.sql:/docker-entrypoint-initdb.d/init.sql - db_data_dev:/var/lib/postgresql/data ports: - '${POSTGRES_PORT}:5432' # Host:Container 내부 포트 diff --git a/docker-compose.yml b/docker-compose.yml index 67ecdb1..5750e97 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,8 @@ services: db: - container_name: matjum_db - image: postgres:16.4-alpine + container_name: matjum-db + build: + context: ./Dockerfiles/db restart: always env_file: - .env @@ -14,20 +15,28 @@ services: interval: 10s timeout: 5s retries: 5 + networks: + - matjum-network server: - container_name: matjum_server + container_name: matjum-server depends_on: db: condition: service_healthy build: - context: . - dockerfile: Dockerfile + context: ./Dockerfiles/server env_file: - .env ports: - '3000:3000' init: true restart: unless-stopped # 예기치 않은 종료 시 재시작 + networks: + - matjum-network volumes: db_data: + +networks: + matjum-network: + name: matjum-network + driver: bridge diff --git a/src/entities/member.entity.ts b/src/entities/member.entity.ts index afd1894..2b4e032 100644 --- a/src/entities/member.entity.ts +++ b/src/entities/member.entity.ts @@ -1,4 +1,4 @@ -import { Column, Entity, OneToMany } from 'typeorm'; +import { Column, Entity, OneToMany, Point } from 'typeorm'; import { BaseModel } from './base-model.entity'; import { Review } from './review.entity'; @@ -15,11 +15,12 @@ export class Member extends BaseModel { @Column({ type: 'varchar', length: 255, select: false }) password: string; - @Column({ type: 'real', nullable: true }) - lon: number; - - @Column({ type: 'real', nullable: true }) - lat: number; + /** + * 4326 - WGS 84 좌표계, 위도와 경도를 도(degrees) 단위로 표현함, 지구의 곡률을 고려하여 정확하게 거리를 계산하기 위해 필요함 + * 기본값은 0, 평면 좌표계 + * */ + @Column({ type: 'geometry', nullable: true, srid: 4326 }) + location: Point; @Column({ default: false }) isRecommendationEnabled: boolean; diff --git a/src/entities/restaurant.entity.ts b/src/entities/restaurant.entity.ts index caa28fc..1352fff 100644 --- a/src/entities/restaurant.entity.ts +++ b/src/entities/restaurant.entity.ts @@ -1,4 +1,4 @@ -import { Column, Entity, OneToMany, Unique } from 'typeorm'; +import { Column, Entity, OneToMany, Point, Unique } from 'typeorm'; import { BaseModel } from './base-model.entity'; import { Review } from './review.entity'; @@ -19,12 +19,12 @@ export class Restaurant extends BaseModel { @Column({ type: 'varchar', length: 512, nullable: true }) address: string; - // real: 실수형 데이터 타입, 4byte - @Column({ type: 'real', nullable: true }) - lon: number; - - @Column({ type: 'real', nullable: true }) - lat: number; + /** + * 4326 - WGS 84 좌표계, 위도와 경도를 도(degrees) 단위로 표현함, 지구의 곡률을 고려하여 정확하게 거리를 계산하기 위해 필요함 + * 기본값은 0, 평면 좌표계 + * */ + @Column({ type: 'geometry', nullable: true, srid: 4326 }) + location: Point; @Column({ type: 'real', default: 0 }) // review 가 없을 경우 0으로 설정 rating: number;