Skip to content

Commit

Permalink
💚 [Chore] development 및 production 환경 env 파일 분리 (#597)
Browse files Browse the repository at this point in the history
  • Loading branch information
jis-kim authored and nyeoni committed Aug 22, 2023
1 parent 128ee1d commit 5403e8e
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 165 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
./backend/seeding
./backend/yarn-error.log
./backend/test
./backend/.env.development

./frontend/.husky
./frontend/.storybook
Expand Down
4 changes: 0 additions & 4 deletions .env.example

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.env
.env.development
14 changes: 6 additions & 8 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@ CLIENT_URL=

# Postgres database - docker env 로 사용
# database port (default: 5432)
DB_PORT=
POSTGRES_PORT=
# db container name
DB_HOST=
# local - localhost, production - ghostgres
POSTGRES_HOST=
# database name
DB_NAME=
POSTGRES_DB=
# database user (username 은 실행중인 호스트 머신과 달라도 됩니다.)
DB_USER=
POSTGRES_USER=
# database password
DB_PASSWORD=

# db name for test
TEST_DB_NAME=
POSTGRES_PASSWORD=

# 42인트라넷에서 발급받은 API ID
FORTYTWO_APP_ID=
Expand Down
15 changes: 6 additions & 9 deletions backend/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ services:
db:
container_name: ghostgres_dev
image: postgres:15.3-alpine
restart: always
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
restart: on-failure:5
env_file:
- .env.development
volumes:
- db_data:/var/lib/postgresql/data
- db_dev_data:/var/lib/postgresql/data
ports:
- 8000:5432

- ${POSTGRES_PORT}:5432
volumes:
db_data:
db_dev_data:
8 changes: 4 additions & 4 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"start": "nest start",
"start:dev": "NODE_ENV=development nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "NODE_ENV=production nest start",
"db": "docker compose --env-file .env -f ./docker-compose.dev.yml up -d",
"db:down": "docker compose --env-file .env -f ./docker-compose.dev.yml down",
"db:reset": "docker compose --env-file .env -f ./docker-compose.dev.yml down -v",
"start:prod": "NODE_ENV=production node dist/backend/src/main",
"db": "docker compose --env-file .env.development -f ./docker-compose.dev.yml up -d",
"db:down": "docker compose --env-file .env.development -f ./docker-compose.dev.yml down",
"db:reset": "docker compose --env-file .env.development -f ./docker-compose.dev.yml down -v",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
Expand Down
40 changes: 32 additions & 8 deletions backend/seeding/data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import { User } from '../src/entity/user.entity';

import seeder from './seeder/message.seeder';

config();
config({
path: '.env.development',
});

(async () => {
if (process.argv[2] === undefined) {
Expand All @@ -25,18 +27,40 @@ config();

const options: DataSourceOptions = {
type: 'postgres',
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
database: process.env.TEST_DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
host: process.env.POSTGRES_HOST,
port: Number(process.env.POSTGRES_PORT),
database: process.env.POSTGRES_DB,
username: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
synchronize: true,
entities: [Auth, User, Friendship, Message, MessageView, UserRecord, GameHistory, BlockedUser, Achievement],
namingStrategy: new SnakeNamingStrategy(),
};

const dataSource = new DataSource(options);
await dataSource.initialize();

await seeder(dataSource);
try {
await dataSource.initialize();
} catch (e) {
console.table(e);
console.log(e);
if (e.code === 'ENOTFOUND') {
console.error('Please check the database connection options in the .env file.\n');
}
await dataSource.destroy();
process.exit(1);
}
try {
await seeder(dataSource);
} catch (e) {
console.error(e);
if (e.code === '23505') {
console.error(
'\nSeeding data already exists.\nYou can either run "yarn seed reset" to reset the seeding or continue with the development process without performing any seeding.\n',
);
}
await dataSource.destroy();
process.exit(1);
}
await dataSource.destroy();
})();
11 changes: 6 additions & 5 deletions backend/seeding/reset-db.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/bin/bash
DB=$(grep "TEST_DB_NAME" .env | cut -d "=" -f 2)
HOST=$(grep "DB_HOST" .env | cut -d "=" -f 2)
PORT=$(grep "DB_PORT" .env | cut -d "=" -f 2)
USER=$(grep "DB_USER" .env | cut -d "=" -f 2)
psql -p $PORT -h $HOST -d postgres -U $USER -c "drop database $DB" -c "create database $DB"
DB=$(grep "POSTGRES_DB" .env.development | head -1 | cut -d "=" -f 2)
HOST=$(grep "POSTGRES_HOST" .env.development | cut -d "=" -f 2)
PORT=$(grep "POSTGRES_PORT" .env.development | cut -d "=" -f 2)
USER=$(grep "POSTGRES_USER" .env.development | cut -d "=" -f 2)
PASSWORD=$(grep "POSTGRES_PASSWORD" .env.development | cut -d "=" -f 2)
PGPASSWORD=$PASSWORD psql -p "$PORT" -h "$HOST" -U "$USER" -d postgres -c "drop database $DB" -c "create database $DB"

rm -rf seeding/results;
189 changes: 80 additions & 109 deletions backend/seeding/seeder/message.seeder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import * as fs from 'fs';
import * as path from 'path';

import { faker } from '@faker-js/faker';
import { DataSource, Repository } from 'typeorm';

Expand All @@ -17,115 +14,89 @@ import messageFactory from '../factory/message.factory';
import userFactory from '../factory/user.factory';

export default async (dataSource: DataSource) => {
const resultDir = path.join(__dirname, '../results');

const authRepository: Repository<Auth> = dataSource.getRepository(Auth);
const authSeeds = Array(Number(process.argv[2])).fill(null).map(authFactory);
authSeeds[0].status = AuthStatus.REGISTERD;
authSeeds[1].status = AuthStatus.REGISTERD;
authSeeds[2].status = AuthStatus.REGISTERD;

const auths = await authRepository.save(authSeeds);
console.log('auth ' + auths.length + ' rows created.');
fs.mkdir(resultDir, () => {
fs.writeFile(path.join(resultDir, 'auths.json'), JSON.stringify(auths), (err) => {
if (err) throw err;
console.log('created auth information has been saved to results/auths.json\n');
});
});

// generate user
const userRepository = dataSource.getRepository(User);
const users = await userRepository.save(auths.filter((auth) => auth.status === 'REGISTERD').map(userFactory));
console.log('user ' + users.length + ' rows created.');

fs.writeFile(path.join(resultDir, 'users.json'), JSON.stringify(users), (err) => {
if (err) throw err;
console.log('created user information has been saved to seeding/results/users.json\n');
});

// generate user record
const userRecord = users.map((user) => ({
id: user.id,
}));

await dataSource.getRepository(UserRecord).save(userRecord);

// generate friendship
// 1/2 확률로 친구관계 생기게, 그 중 1/2 확률로 accept.
const friendsSeed = [];
for (let i = 0; i < users.length; i++) {
for (let j: number = i + 1; j < users.length; j++) {
if (i == 0 && j == 1) {
friendsSeed.push(frieindshipFactory(users[i], users[j], true, faker.date.past()));
continue;
} else if (i == 0 && j == 2) {
friendsSeed.push(frieindshipFactory(users[i], users[j], false));
continue;
await dataSource.transaction(async (manager) => {
const authRepository: Repository<Auth> = manager.getRepository(Auth);
const authSeeds = Array(Number(process.argv[2])).fill(null).map(authFactory);
authSeeds[0].status = AuthStatus.REGISTERD;
authSeeds[1].status = AuthStatus.REGISTERD;
authSeeds[2].status = AuthStatus.REGISTERD;

const auths = await authRepository.save(authSeeds);

// generate user
const userRepository = manager.getRepository(User);
const users = await userRepository.save(auths.filter((auth) => auth.status === 'REGISTERD').map(userFactory));

// generate user record
const userRecord = users.map((user) => ({
id: user.id,
}));

await manager.getRepository(UserRecord).save(userRecord);

// generate friendship
// 1/2 확률로 친구관계 생기게, 그 중 1/2 확률로 accept.
const friendsSeed = [];
for (let i = 0; i < users.length; i++) {
for (let j: number = i + 1; j < users.length; j++) {
if (i == 0 && j == 1) {
friendsSeed.push(frieindshipFactory(users[i], users[j], true, faker.date.past()));
continue;
} else if (i == 0 && j == 2) {
friendsSeed.push(frieindshipFactory(users[i], users[j], false));
continue;
}

const isFirstUserI = faker.datatype.boolean();
Math.random() <= 0.1 &&
friendsSeed.push(
frieindshipFactory(users[isFirstUserI ? i : j], users[isFirstUserI ? j : i], faker.datatype.boolean()),
);
}

const isFirstUserI = faker.datatype.boolean();
Math.random() <= 0.1 &&
friendsSeed.push(
frieindshipFactory(users[isFirstUserI ? i : j], users[isFirstUserI ? j : i], faker.datatype.boolean()),
);
}
}

const friendshipRepository = dataSource.getRepository(Friendship);
const friends = await friendshipRepository.save(friendsSeed);
console.log('friendship ' + friends.length + ' rows created.');

fs.writeFile(path.join(resultDir, 'friends.json'), JSON.stringify(friends), (err) => {
if (err) throw err;
console.log('created friendship information has been saved to seeding/results/friends.json\n');
});

// generate message
// 친구 수락 && 마지막 메세지 시간이 있으면 메세지 생성
const messageRepository = dataSource.getRepository(Message);

const messageSeed: Partial<Message>[] = [];
friends
.filter((friend) => friend.lastMessageTime !== undefined && friend.accept === true)
.map((friend) => {
const random = Math.floor(Math.random() * 200);
let prevDate: Date | undefined = undefined;
for (let i = 0; i < random; i++) {
const message = messageFactory(friend, prevDate);
messageSeed.push(message);
prevDate = new Date(message.createdAt);
const friendshipRepository = manager.getRepository(Friendship);
const friends = await friendshipRepository.save(friendsSeed);

// generate message
// 친구 수락 && 마지막 메세지 시간이 있으면 메세지 생성
const messageRepository = manager.getRepository(Message);

const messageSeed: Partial<Message>[] = [];
friends
.filter((friend) => friend.lastMessageTime !== undefined && friend.accept === true)
.map((friend) => {
const random = Math.floor(Math.random() * 200);
let prevDate: Date | undefined = undefined;
for (let i = 0; i < random; i++) {
const message = messageFactory(friend, prevDate);
messageSeed.push(message);
prevDate = new Date(message.createdAt);
}
});

// insert 할 양이 많으면 error 가 발생하므로 100개씩 나눠서 insert
const promises = [];
for (let i = 0; i < messageSeed.length; i += 100) {
promises.push(messageRepository.save(messageSeed.slice(i, i + 100)));
}
await Promise.all(promises);

const gameSeed = [];
for (let i = 0; i < users.length; i++) {
for (let j: number = i + 1; j < users.length; j++) {
const isFirstUserI = faker.datatype.boolean();
Math.random() <= 0.1 &&
gameSeed.push(gameHistoryFactory(users[isFirstUserI ? i : j], users[isFirstUserI ? j : i]));
}
});

// insert 할 양이 많으면 error 가 발생하므로 100개씩 나눠서 insert
const promises = [];
for (let i = 0; i < messageSeed.length; i += 100) {
promises.push(messageRepository.save(messageSeed.slice(i, i + 100)));
}
await Promise.all(promises);

console.log('message ' + messageSeed.length + ' rows created.\n');

//fs.writeFile(path.join(resultDir, 'messages.json'), JSON.stringify(messages), (err) => {
// if (err) throw err;
// console.log('created message information has been saved to seeding/results/messages.json\n');
//});

// generate game history

const gameSeed = [];
for (let i = 0; i < users.length; i++) {
for (let j: number = i + 1; j < users.length; j++) {
const isFirstUserI = faker.datatype.boolean();
Math.random() <= 0.1 &&
gameSeed.push(gameHistoryFactory(users[isFirstUserI ? i : j], users[isFirstUserI ? j : i]));
}
}
const gameHistoryRepository = dataSource.getRepository(GameHistory);
await gameHistoryRepository.save(gameSeed);

console.log('game history ' + gameSeed.length + ' rows created.\n');

dataSource.destroy();
const gameHistoryRepository = manager.getRepository(GameHistory);
await gameHistoryRepository.save(gameSeed);

console.log('auth ' + auths.length + ' rows created.');
console.log('user ' + users.length + ' rows created.');
console.log('friendship ' + friends.length + ' rows created.');
console.log('message ' + messageSeed.length + ' rows created.\n');
console.log('game history ' + gameSeed.length + ' rows created.\n');
});
};
1 change: 1 addition & 0 deletions backend/src/config/app/configuration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AppConfigService } from './configuration.service';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: ['.env.development', '.env'],
load: [configuration],
validationSchema: Joi.object({
APP_ENV: Joi.string().valid('development', 'production', 'test').default('development'),
Expand Down
11 changes: 6 additions & 5 deletions backend/src/config/database/configuration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import { DatabaseConfigService } from './configuration.service';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: ['.env.development', '.env'],
load: [configuration],
validationSchema: Joi.object({
DB_HOST: Joi.string(),
DB_PORT: Joi.number(),
DB_NAME: Joi.string(),
DB_USER: Joi.string(),
DB_PASSWORD: Joi.string(),
POSTGRES_HOST: Joi.string(),
POSTGRES_PORT: Joi.number(),
POSTGRES_DB: Joi.string(),
POSTGRES_USER: Joi.string(),
POSTGRES_PASSWORD: Joi.string(),
}),
}),
],
Expand Down
10 changes: 5 additions & 5 deletions backend/src/config/database/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { registerAs } from '@nestjs/config';

export default registerAs('database', () => ({
host: process.env.DB_HOST,
port: process.env.DB_PORT,
name: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
host: process.env.POSTGRES_HOST,
port: process.env.POSTGRES_PORT,
name: process.env.POSTGRES_DB,
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
}));
Loading

0 comments on commit 5403e8e

Please sign in to comment.