Docker Express TypeScript postgreSQL環境構築

初心者のメモです。

* 環境
```sh:Terminal
$ uname -a
Linux haruki 6.1.7-hardened1-1-hardened #1 SMP PREEMPT_DYNAMIC Thu, 19 Jan 2023 00:16:46 +0000 x86_64 GNU/Linux

$ cat /etc/os-release
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://archlinux.org/"
DOCUMENTATION_URL="https://wiki.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://bugs.archlinux.org/"
PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/"
LOGO=archlinux-logo
```

インストール
```sh:Terminal
sudo pacman -S docker docker-compose 
```
ディレクトリ構造
```
app
  |-Dockerfile
  |-package.json
  |-src
     |-index.ts
     |-db.ts
docker-compose.yml
initdb
  |-setup.sql
```
* Dockerfile
```Dockerfile:Dockerfile
FROM node:16.2.0

RUN yarn install

WORKDIR /app

CMD ["yarn", "start"]

```
* docker-compose.yml
```yml:docker-compose.yml
version: "3"
services:
  node:
    container_name: node_express
    build: ./app
    volumes:
      - ./app:/app
    tty:  true
    ports:
      - 3000:3000

  postgres:
    container_name: postgres
    image: postgres:13
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: postgres_db
    volumes:
      - db_data:/var/lib/posrgresql/data
      - ./initdb:/docker-entrypoint-initdb.d

volumes:
  db_data: {}
```
+ packege.json

```json:package.json
{
	"name": "postgre-tutorial",
	"version": "1.0.0",
	"main": "index.js",
	"license": "MIT",
	"scripts": {
		"preinstall": "typesync || : ",
		"build": "tsc",
		"start": "nodemon  --exec ts-node src/index.ts"
	},
	"devDependencies": {
		"@types/express": "^4.17.16",
		"@types/node": "^18.11.18",
		"@types/pg": "^8.6.6",
		"@typescript-eslint/eslint-plugin": "^5.49.0",
		"@typescript-eslint/parser": "^5.49.0",
		"eslint": "^8.32.0",
		"eslint-config-prettier": "^8.6.0",
		"eslint-config-standard": "^17.0.0",
		"express": "^4.18.2",
		"nodemon": "^2.0.20",
		"pg": "^8.8.0",
		"prettier": "^2.8.3",
		"ts-node": "^10.9.1",
		"typescript": "^4.9.4"
	}
}

```
* tsconfig.json
```json:tsconfig.json
{
  "compilerOptions": {
    "target": "ES3",
    "module": "CommonJS",
    "lib": ["es2020"],
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "noImplicitAny": true,
    "noUncheckedIndexedAccess": true,
    "moduleResolution": "node",
    "baseUrl": "src",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["dist", "node_modules"],
  "compileOnSave": false
}

```

あとはbuildします。

* パッケージのインストール
```sh:Terminal
docker-compose run node yarn
```

* ビルド

```sh:Terminal
docker-compose build
```
* アップ
```
docker-compose up
```
あとはnodemonが起動して変更があったら自動で更新してくれます。

* バンドル
```
docker-compose run node yarn tsc
```

あとはindex.tsに変更を書くとOKです。

****

例
```sql:setup.sql
set client_encoding = 'UTF8';

create table users(
    id serial primary key,
    name varchar(255),
    email varchar(255),
    age int
);
```
```db.ts
import { Pool } from "pg";

const pool = new Pool({
  user: 'postgres',
  host: 'postgres',
  database: 'postgres_db',
  password: 'password',
  port: 5432,
})

export default pool;

```
```index.ts
import express from "express";
import pool from "./db";

const app = express();

app.listen(PORT, () => {
	console.log("server is running on PORT " + PORT);
});

app.get("/users/:id", (req, res) => {
	console.log(req.params.id);
	pool.query(
		"SELECT * FROM users WHERE id = $1",
		[req.params.id],
		(error, results) => {
			if (error) throw error;
			return res.status(200).json(results.rows);
		}
	);
});
```
これでSQLが操作できるようになりました。