# Environment

## Environment

คือ ตัวแปร หรือว่าค่า ที่จะเป็นเเวดล้อมของโปรแกรมที่เรารัน อาจจะเป็นที่อยู่ฐานข้อมูล ที่เราไม่ควรจะเขียนลงโค้ดตรง ๆ เราเลยควรแยกตัวแปรเหล่านั้นออกมา เหมือนกับไฟล์ `.env` ซึ่งในการที่จะกำหนดมัน ก็สามารถทำได้หลายแบบ เช่น

1. เขียนลงคำสั่ง CLI ที่จะใช้รัน Container
2. เขียนลงไฟล์ Dockerfile
3. เขียนไฟล์ .env เเล้วโหลดเข้าไปตอนรัน container

### Environment with CLI

เราสามารถเขียนตัวแปร Environment ของเราลงคำสั่ง `docker run` ตรง ๆ ได้เลย ด้วย `-e`

```
docker run -e DB_HOST=127.0.0.1 -e DB_USERNAME=root alpine
```

ด้วย -e เราสามารถกำหนดตัวแปร Environment ของเราลงใน Container ที่เรากำลังจะรันได้เลย เเต่ว่าการทำแบบนี้อาจจะยุ่งยากหากว่าตัวแปรของเรามีจำนวนมาก ๆ เนื่องจากจะทำให้คำสั่งยาว เราจึงควรเขียนลงบน Dockerfile

### Environment with Dockerfile

เราสามารถเขียนตัวแปรลง Dockerfile ของเราได้เลย ด้วย ENV

```
FROM alpine

ENV DB_HOST=127.0.0.1
ENV DB_USERNAME=root
ENV DB_PASSWORD=12345678
```

แบบนี้เราจะสามารถจัดการตัวแปรที่มีจำนวนมาก ๆ ได้ง่ายกว่า

### Environment files

เราสามารถเขียนไฟล์ .env เเยกกัน เเล้วโหลดเข้ามาใน container ตอนที่เรารันคำสั่ง run container ได้ ด้วยคำสั่ง `--env-file`

```
docker run --env-file ./.env node:17-alpine3.12
```

ด้วย `--env-file` เราสามารถเขียนไฟล์ `.env` เเยกออกไปได้ โดยต้องใส่ที่อยู่ของไฟล์ `.env` โดยไฟล์จะมีหน้าตาดังนี้

```
DB_HOST=127.0.0.1
DB_USERNAME=root
DB_PASSWORD=12345678
```

## Argument

Argument จะเป็นตัวแปรที่เอาไว้ใช้ในขั้นตอน build image ขึ้นมา อย่างเช่น กำหนดเวอร์ชั่น Image ที่เราจะ build ทำให้เวลาเราเขียน Dockerfile เราสามารถเว้นไว้เพื่อให้เวลา Build เราสามารถกำหนดตัวแปรลงไปได้

การกำหนดตัวแปร Argument เราสามารถเขียนลงใน Dockerfile ได้ด้วยคำสั่ง `ARG` ดังนี้

```
ARG NODE_VERSION=16

FROM node:${NODE_VERSION}
```

การเขียน `${VAR}` จะเป็นการเรียกใช้ตัวแปร Argument ที่เรากำหนดไว้

การใส่ `ARG` จะเป็นค่า Default ของตัวแปรนั้น ซึ่งเวลารันเราสามารถกำหนดค่าของตัวแปรนั้นได้ ดังนี้

```
docker build . --build-arg NODE_VERSION=17-alpine3.12
```

การใช้ `--build-arg` จะเป็นการกำหนด Argument ลงในการ build Image ของเรา

ความเเตกต่างของ Environment เเละ Argument คือ Environment จะเป็นตัวแปรที่ใช้ระหว่างการรัน Container เเต่ Argument จะเป็นตัวแปรที่ใช้ในขั้นตอนการ build container เพราะฉะนั้นการใช้งานจะใช้คนละกรณีกัน
