SumoSunday

ซีรีส์ เขียนโปรแกรมพื้นฐาน · ตอนที่ 6 จาก 7

ไฟล์ .env คืออะไร ทำไม AI บอกให้สร้าง และต้องใส่อะไรลงไป

30 ต.ค. 2569 · อ่าน 14 นาที

AI บอกให้สร้างไฟล์ .env แล้วใส่ API key แต่ไม่ได้บอกว่าไฟล์นี้คืออะไร บทความนี้อธิบายด้วยการเทียบสูตรขนมกับกุญแจร้าน ว่าทำไมต้องแยกกุญแจออกจากโค้ด ในไฟล์มีอะไร .env.example ต่างจาก .env อย่างไร พร้อมตัวอย่างให้ลองสร้างไฟล์แล้วให้โปรแกรมอ่านค่าเอง และเช็กลิสต์ 4 ข้อเมื่อค่าที่อ่านได้กลายเป็น undefined

สมมติคุณให้ AI ช่วยทำเว็บร้านขนม แล้วอยากให้เว็บมีแชตตอบลูกค้าด้วย AI คำตอบที่ได้มีบรรทัดหนึ่งเขียนว่า "สร้างไฟล์ .env แล้วใส่ API key ของคุณลงไป"

คุณทำตามได้ แต่ยังไม่รู้ว่าไฟล์นี้คืออะไร ทำไมชื่อขึ้นต้นด้วยจุด และคีย์ที่ใส่ลงไปจะไปอยู่ที่ไหนบ้าง

บทความนี้เป็นตอนที่ 6 ของซีรีส์ "เขียนโปรแกรมพื้นฐาน" ว่าด้วย .env คืออะไร มีไว้ทำไม และพาลองสร้างไฟล์ให้โปรแกรมอ่านค่า ส่วนข้อห้ามอยู่ในตอนที่ 7

ข้อมูล ณ ตุลาคม 2569 จากเอกสารทางการของ Node.js, Next.js, Laravel, Vercel และ GitHub ตัวอย่างทั้งหมดในบทความนี้เป็นข้อมูลสมมติ ไม่มีคีย์จริง ตัวอย่างในหัวข้อ "ลองเอง" เรารันจริงเมื่อ 30 ต.ค. 2569 ด้วย Node.js v23.11.0 บน macOS

.env คือไฟล์ข้อความธรรมดา เขียนบรรทัดละ 1 ค่า

ไฟล์ .env คือไฟล์ข้อความธรรมดา เปิดด้วยโปรแกรมแก้ข้อความตัวไหนก็ได้ ข้างในเขียนบรรทัดละ 1 ค่า ในรูป ชื่อ=ค่า ตามรูปแบบที่เอกสารของ Node.js กำหนด ตัวอย่างนี้คือ .env ของร้านสมมติชื่อร้านป้าแดง

ข้อความ
# ข้อมูลสมมติ ไม่ใช่คีย์จริง
SHOP_NAME=ร้านป้าแดง
APP_MODE=ทดลอง
API_KEY=ตัวอย่าง-ไม่ใช่คีย์จริง

อ่านไฟล์นี้ทีละส่วนได้ดังนี้

  • คำทางซ้ายของ = คือชื่อ เช่น SHOP_NAME โค้ดใช้ชื่อนี้เรียกหาค่า
  • คำทางขวาของ = คือค่า เช่น ร้านป้าแดง
  • บรรทัดที่ขึ้นต้นด้วย # คือหมายเหตุ โปรแกรมไม่นำไปใช้

ค่าแบบนี้เรียกว่า ตัวแปรสภาพแวดล้อม (environment variables) คือค่าที่โปรแกรมรับมาจากเครื่องที่มันทำงานอยู่ ไม่ได้เขียนไว้ในโค้ด ไฟล์ .env เป็นวิธีจดค่าพวกนี้รวมไว้ในไฟล์เดียว เพื่อให้โปรแกรมโหลดไปใช้

จุดหน้าชื่อทำให้คำสั่ง ls บน Mac และ Linux ไม่แสดงไฟล์นี้ในรายการปกติ (ต้องใช้ ls -a ถึงจะเห็น) แต่ไม่ได้ล็อกไฟล์ ใครเปิดโฟลเดอร์ได้ก็อ่านได้ทุกบรรทัด

ทำไมต้องแยกกุญแจออกจากโค้ด

ลองนึกถึงร้านป้าแดง ป้าแดงมีสูตรขนมและกุญแจร้าน

  • สูตรขนม ป้าแดงแบ่งให้หลานไปเปิดสาขาได้ ถ่ายเอกสารแจกก็ไม่เสียหาย
  • กุญแจร้านและรหัสตู้เซฟ ป้าแดงเก็บไว้ในกระเป๋า ไม่แนบไปกับสูตร และสาขาของหลานก็มีกุญแจของตัวเอง

ในโปรแกรม โค้ดคือสูตรขนม ส่วน .env คือกุญแจในกระเป๋า การแยกสองอย่างนี้ออกจากกันให้ประโยชน์ 2 ข้อ

1. แบ่งโค้ดให้คนอื่นได้ โดยไม่แจกกุญแจไปด้วย

README ของ dotenv (ไลบรารีที่ใช้อ่านไฟล์ .env) อ้างถึงแนวทาง The Twelve-Factor App ซึ่งกำหนดให้ "แยกค่าตั้งค่าออกจากโค้ดอย่างเด็ดขาด" ข้อทดสอบคือ ถ้าเปิดโค้ดให้คนทั้งโลกดูได้ทันทีโดยไม่มีคีย์หลุดออกไป แปลว่าแยกได้ถูกแล้ว

2. แต่ละเครื่องใช้ค่าของตัวเองได้ โดยไม่ต้องแก้โค้ด

เครื่องของคุณตอนทดลองกับเว็บจริงที่ลูกค้าใช้ ควรใช้ค่าคนละชุด เช่น ฐานข้อมูลทดลองกับฐานข้อมูลจริง เอกสารของ Laravel (ชุดเครื่องมือสร้างเว็บภาษา PHP) ให้เหตุผลว่าไม่ควรเก็บ .env ไว้กับโค้ด "เพราะนักพัฒนาแต่ละคนหรือเซิร์ฟเวอร์แต่ละเครื่องอาจต้องใช้ค่าตั้งค่าต่างกัน" โค้ดชุดเดียวจึงใช้ได้ทุกที่ แค่แต่ละที่มี .env ของตัวเอง

ในไฟล์ .env มีอะไรบ้าง

ความลับที่อยู่ใน .env แบ่งได้ 2 กลุ่ม ชื่อในตารางเป็นชื่อตัวอย่าง เพราะแต่ละโปรเจกต์ตั้งชื่อไม่เหมือนกัน

กลุ่มตัวอย่างชื่อถ้าหลุดไปถึงคนอื่น จะเกิดอะไร
คีย์สำหรับเรียกใช้บริการอื่น (API key) เช่น บริการ AI ระบบส่งอีเมล ระบบรับเงินAI_API_KEYคนที่ได้คีย์ไปจะใช้บริการนั้นได้เหมือนเป็นคุณ ถ้าบริการคิดเงินตามการใช้งาน ค่าใช้จ่ายจะเข้าบัญชีของคุณ
ข้อมูลสำหรับเชื่อมฐานข้อมูล เช่น ชื่อผู้ใช้และรหัสผ่านDB_USER DB_PASSคนที่ได้ไปจะเข้าฐานข้อมูลได้ด้วยสิทธิ์ของบัญชีนั้น และอ่านหรือแก้ข้อมูลลูกค้าได้

นอกจากความลับ .env ยังเก็บค่าที่ไม่ลับได้ด้วย เช่น SHOP_NAME เพราะแต่ละเครื่องต้องการค่าต่างกัน

GitHub นิยามความลับว่าเป็นข้อมูลที่ใช้ยืนยันตัวตนหรือให้สิทธิ์เข้าถึง และยกตัวอย่าง API key ข้อมูลเข้าฐานข้อมูล และ private key หลักจำง่ายจึงเป็นแบบนี้ ค่าไหนใช้พิสูจน์ว่าเป็นคุณ หรือใช้เปิดประตูเข้าระบบ ค่านั้นคือความลับ

.env.example คือรายชื่อกุญแจ ที่ไม่มีตัวกุญแจ

คู่หูของ .env คือไฟล์ .env.example ไฟล์นี้มีชื่อตัวแปรครบ แต่ไม่มีค่าจริง หน้าตาเป็นแบบนี้

ข้อความ
SHOP_NAME=
APP_MODE=
API_KEY=

ถ้าเทียบกับร้านป้าแดง .env.example คือกระดาษที่เขียนว่า "ร้านนี้ต้องมีกุญแจประตูหน้า กุญแจหลังร้าน และรหัสตู้เซฟ" แต่ไม่มีกุญแจติดมาด้วย เอกสารของ Laravel อธิบายว่าไฟล์นี้ช่วยให้คนในทีม "เห็นชัดว่าต้องมีตัวแปรอะไรบ้างถึงจะรันแอปได้"

ไฟล์ .env.example แชร์ได้และเก็บไว้กับโค้ดได้ เพราะไม่มีค่าจริง ก่อนแชร์ให้เปิดดูทุกครั้งว่าไม่มีใครเผลอใส่คีย์จริงลงไป

คุณจะเจอไฟล์ .env ตอนไหน

กรณีที่ 1: AI บอกให้สร้าง

เมื่อ AI บอกให้ "สร้างไฟล์ .env แล้วใส่ API key" ให้ถาม AI กลับ 3 ข้อก่อนลงมือ

  1. ต้องมีตัวแปรชื่ออะไรบ้าง สะกดอย่างไร
  2. ค่าของแต่ละตัวเอามาจากไหน เช่น หน้าตั้งค่าของบริการนั้น
  3. ตัวไหนเป็นความลับ และตอนขึ้นเว็บจริงต้องไปตั้งค่าที่ไหนอีก

จากนั้นสร้างไฟล์ชื่อ .env ไว้ที่โฟลเดอร์หลักของโปรเจกต์ แล้วพิมพ์ค่าจริงลงในไฟล์เอง ไม่ต้องวางค่าจริงลงในแชต

กรณีที่ 2: ดาวน์โหลดโปรเจกต์จาก GitHub

ถ้าคู่มือของโปรเจกต์ (ไฟล์ README) เขียนว่า "copy .env.example to .env" แปลว่าให้คัดลอก .env.example เป็นไฟล์ใหม่ชื่อ .env แล้วเติมค่าของคุณเอง โดยไม่ต้องแก้ไฟล์ต้นฉบับ คำสั่งคัดลอกอยู่ในขั้นที่ 1 ของหัวข้อ "ลองเอง" ข้างล่าง

ไฟล์ .env ไม่ทำงานเอง ต้องมีตัวอ่าน

การวางไฟล์ .env ไว้ในโฟลเดอร์ยังไม่พอ ต้องมีบางอย่างโหลดไฟล์นี้ให้โปรแกรม ตัวอย่างตัวอ่าน 3 แบบมีดังนี้

ตัวอ่านสังเกตได้จากอะไร
Node.js รุ่น 20.6.0 ขึ้นไปคำสั่งรันมี --env-file=.env เช่น node --env-file=.env app.js
ไลบรารี dotenvในโค้ดมีบรรทัด require('dotenv').config() หรือ import 'dotenv/config'
Next.jsไม่ต้องเขียนอะไรเพิ่ม เอกสารของ Next.js บอกว่าโหลดค่าจากไฟล์ .env ให้เอง

ถ้าไม่มีตัวอ่านแบบใดเลย ค่าใน .env จะไปไม่ถึงโปรแกรม หัวข้อถัดไปจะลองให้เห็นว่าเกิดอะไรขึ้น

ลองเอง: สร้าง .env แล้วให้โปรแกรมอ่านค่า

ตัวอย่างนี้ต้องใช้ Node.js รุ่น 20.6.0 ขึ้นไป เช็กรุ่นได้ด้วยคำสั่ง node --version คำสั่งในหัวข้อนี้เขียนสำหรับหน้าต่างพิมพ์คำสั่ง (terminal) บน Mac และ Linux ทุกค่าเป็นข้อมูลสมมติ

ขั้นที่ 1: สร้างโฟลเดอร์ทดลองและไฟล์ .env

สร้างโฟลเดอร์ใหม่ที่ไม่ได้อยู่ในโปรเจกต์ไหน แล้วเข้าไปในโฟลเดอร์นั้น เพื่อไม่ให้ไฟล์ทดลองไปปนกับงานจริง

คำสั่ง
mkdir env-lab
cd env-lab

สร้างไฟล์ .env.example ในโฟลเดอร์นี้ด้วยโปรแกรมแก้ข้อความ ใส่ 3 บรรทัดเหมือนตัวอย่างในหัวข้อ .env.example ข้างบน แล้วคัดลอกเป็น .env แบบเดียวกับตอนดาวน์โหลดโปรเจกต์มา

คำสั่ง
cp .env.example .env

เปิดไฟล์ .env ที่ได้ แล้วเติมค่าสมมติให้ครบทั้ง 3 บรรทัด

ข้อความ
SHOP_NAME=ร้านป้าแดง
APP_MODE=ทดลอง
API_KEY=ตัวอย่าง-ไม่ใช่คีย์จริง

ขั้นที่ 2: เขียนโปรแกรม 3 บรรทัดที่อ่านค่า

สร้างไฟล์ app.js ในโฟลเดอร์ env-lab แล้วใส่โค้ดนี้

โค้ด JavaScript
console.log("ชื่อร้าน:", process.env.SHOP_NAME);
console.log("โหมด:", process.env.APP_MODE);
console.log("มี API key ไหม:", process.env.API_KEY ? "มี" : "ไม่มี");

process.env คือที่ที่ Node.js รวมตัวแปรสภาพแวดล้อมไว้ให้โค้ดเรียกใช้ process.env.SHOP_NAME จึงแปลว่า "ขอค่าของชื่อ SHOP_NAME"

บรรทัดที่ 3 บอกแค่ว่ามีคีย์หรือไม่ ไม่พิมพ์คีย์ออกมา เพราะ GitHub แนะนำให้ปิดบังความลับก่อนบันทึกการทำงาน (log)

ขั้นที่ 3: รันโดยบอกให้ Node.js อ่าน .env

สั่งรันโดยใส่ --env-file=.env เพื่อบอกให้ Node.js โหลดไฟล์ .env ก่อน

คำสั่ง
node --env-file=.env app.js

ผลที่ได้มีดังนี้

ผลลัพธ์
ชื่อร้าน: ร้านป้าแดง
โหมด: ทดลอง
มี API key ไหม: มี

โปรแกรมได้ค่าทั้ง 3 ตัวจาก .env โดยไม่มีค่าไหนเขียนอยู่ในโค้ดเลย ถ้าเปลี่ยน SHOP_NAME ใน .env เป็นชื่ออื่นแล้วรันใหม่ ชื่อร้านในผลลัพธ์จะเปลี่ยนตาม โดยไม่ต้องแก้ app.js

ขั้นที่ 4: รันโดยไม่ได้บอกให้อ่าน .env

ครั้งนี้สั่งรันแบบไม่ใส่ --env-file

คำสั่ง
node app.js

ผลที่ได้มีดังนี้

ผลลัพธ์
ชื่อร้าน: undefined
โหมด: undefined
มี API key ไหม: ไม่มี

undefined แปลว่า "ไม่มีค่านี้" ไฟล์ .env ยังอยู่ครบ แต่ไม่มีตัวอ่านโหลดให้ โปรแกรมจึงมองไม่เห็นค่า และทำงานจนจบโดยไม่เตือนอะไรเลย

ขั้นที่ 5: ถ้าไม่มีไฟล์ .env

เปลี่ยนชื่อไฟล์ .env เป็นชื่ออื่นชั่วคราว แล้วรันคำสั่งเดิมจากขั้นที่ 3

คำสั่ง
mv .env .env-backup
node --env-file=.env app.js

ครั้งนี้ Node.js หยุดทันทีและแจ้ง error ผลที่ได้มีดังนี้

ผลลัพธ์
node: .env: not found

ข้อความนี้แปลว่า "หาไฟล์ .env ไม่เจอ" และบรรทัดในโปรแกรมไม่ถูกรันเลยสักบรรทัด ตรงกับที่เอกสารของ Node.js กำหนดว่าถ้าไม่มีไฟล์ที่ระบุใน --env-file ให้แจ้ง error

ขั้นที่ 4 กับขั้นที่ 5 ต่างกันตรงนี้ ถ้ามีตัวอ่านแต่หาไฟล์ไม่เจอ Node.js จะบอกคุณทันที แต่ถ้าไม่มีตัวอ่านเลย โปรแกรมจะทำงานต่อด้วยค่า undefined โดยไม่เตือน แบบหลังจึงสังเกตยากกว่า

เมื่อทดลองเสร็จ เปลี่ยนชื่อไฟล์กลับด้วย mv .env-backup .env แล้วลบโฟลเดอร์ env-lab ทิ้งได้

ค่าออกมาเป็น undefined: เช็ก 4 ข้อ

เมื่อโปรแกรมที่ AI เขียนให้อ่านค่าจาก .env ไม่ได้ ให้เช็กตามลำดับนี้

  1. ไฟล์ชื่อตรงกับที่ตัวอ่านมองหาหรือยัง

    ในตัวอย่างนี้ --env-file=.env มองหาไฟล์ชื่อ .env และไฟล์ก็ชื่อนั้นพอดี

    ถ้าไม่ผ่าน ให้ใช้ ls -a ดูชื่อจริงของไฟล์ ชื่อที่ต่างไปแม้ตัวเดียว เช่น env ที่ไม่มีจุด จะไม่ถูกโหลด

  2. ไฟล์อยู่ในโฟลเดอร์ที่ถูกต้องหรือยัง

    ในตัวอย่างนี้ ไฟล์อยู่ใน env-lab และสั่งรันจาก env-lab

    ถ้าไม่ผ่าน ให้ย้าย .env ไปไว้ที่โฟลเดอร์หลักของโปรเจกต์ เพราะ Node.js หาไฟล์โดยนับจากโฟลเดอร์ที่สั่งรัน และ Next.js อ่านจากโฟลเดอร์หลัก ไม่ใช่จากโฟลเดอร์ src

  3. ชื่อตัวแปรในไฟล์ตรงกับในโค้ดทุกตัวอักษรหรือยัง

    ในตัวอย่างนี้ ทั้งไฟล์และโค้ดเขียน SHOP_NAME เหมือนกัน

    ถ้าไม่ผ่าน เช่น ไฟล์เขียน SHOPNAME แต่โค้ดเรียก SHOP_NAME ค่าจะเป็น undefined ให้แก้ชื่อในไฟล์ให้ตรงกับในโค้ด

  4. มีตัวอ่านโหลด .env หรือยัง

    ในตัวอย่างนี้ ขั้นที่ 3 มี --env-file จึงได้ค่า ส่วนขั้นที่ 4 ไม่มี จึงได้ undefined

    ถ้าไม่ผ่าน ให้ถาม AI ว่าโปรเจกต์นี้โหลดไฟล์ .env ด้วยวิธีไหน แล้วเทียบกับตารางตัวอ่านข้างบน

ถ้าครบทั้ง 4 ข้อแล้วยังได้ undefined ให้ส่งชื่อตัวแปรและข้อความ error ให้ AI ดู โดยไม่ต้องส่งค่าจริง

บนเว็บจริง ค่าพวกนี้อยู่ที่ไหน

ไฟล์ .env ใช้กับเครื่องของคุณ ส่วนเว็บจริงใช้ค่าอีกชุดหนึ่ง ซึ่งตั้งไว้ในหน้าตั้งค่าของที่วางเว็บ (hosting) ไม่ใช่อัปโหลดไฟล์ .env ขึ้นไปพร้อมโค้ด

เทียบกับร้านป้าแดง สาขาของหลานไม่ได้รับกุญแจที่แนบมากับสูตร แต่มีกุญแจของสาขาเองเก็บไว้ที่สาขา

GitHub แนะนำว่าอย่าเขียนความลับลงในโค้ด ให้ใช้ตัวแปรสภาพแวดล้อมหรือเครื่องมือเก็บความลับของแพลตฟอร์มที่ใช้อยู่แทน ที่วางเว็บแต่ละเจ้าตั้งชื่อหน้านี้ต่างกัน เช่น Vercel เรียกว่า Environment Variables

ถ้าแก้ค่าแล้วเว็บยังใช้ค่าเดิม ให้เช็กว่าส่งเว็บขึ้นใหม่ (deploy) แล้วหรือยัง เพราะเอกสารของ Vercel บอกว่าค่าที่แก้มีผลกับการ deploy ครั้งถัดไปเท่านั้น

คำสั่งสำเร็จรูป: ให้ AI ทำแผนที่ตัวแปรของโปรเจกต์คุณ

ถ้าใช้เครื่องมือ AI ที่อ่านไฟล์ในโปรเจกต์ได้ วางข้อความนี้เพื่อให้ AI ทำตารางตัวแปรทุกตัวที่โปรเจกต์ต้องใช้

prompt
อ่านไฟล์ .env.example และโค้ดในโปรเจกต์นี้ แล้วทำตารางภาษาไทยของตัวแปรสภาพแวดล้อมทุกตัวที่โค้ดใช้
คอลัมน์: ชื่อตัวแปร, ใช้ทำอะไร, เป็นความลับไหม, เอาค่ามาจากไหน, ต้องตั้งในหน้าตั้งค่าของที่วางเว็บด้วยไหม
บอกด้วยว่าโปรเจกต์นี้โหลดไฟล์ .env ด้วยวิธีไหน
ถ้ามีตัวแปรที่โค้ดใช้แต่ไม่มีใน .env.example ให้แยกบอกไว้ต่างหาก
ห้ามเปิดอ่านไฟล์ .env และห้ามพิมพ์ค่าจริงของตัวแปรใดออกมา ให้ดูเฉพาะชื่อ

ตารางที่ได้ใช้เช็กว่าเติมค่าครบหรือยัง และตัวไหนต้องตั้งบนเว็บจริงด้วย บรรทัดสุดท้ายกันไม่ให้ค่าจริงไปโผล่ในแชต

3 ใน 6 ข้อห้ามที่ควรรู้ก่อน

ตอนที่ 7 รวบรวมข้อห้ามกับไฟล์ .env ไว้ 6 ข้อ 3 ข้อแรกมีดังนี้

  1. ห้าม commit ไฟล์ .env ขึ้นที่เก็บโค้ด ลบทีหลังก็ยังค้างอยู่ในประวัติ ดูตัวอย่างได้ในตอน Git คืออะไร
  2. ห้ามวางคีย์จริงในแชตหรือในภาพหน้าจอ
  3. ห้ามใส่คีย์ลับในตัวแปรที่ถูกส่งไปถึงเบราว์เซอร์ เช่น ตัวแปรที่ขึ้นต้นด้วย NEXT_PUBLIC_ หรือ VITE_

อ่านครบทั้ง 6 ข้อได้ที่ 6 ข้อห้ามกับไฟล์ .env เพื่อไม่ให้คีย์หลุด

สรุป

ไฟล์ .env คือไฟล์ข้อความธรรมดา เขียนบรรทัดละ ชื่อ=ค่า ใช้เก็บกุญแจแยกจากโค้ด เหมือนป้าแดงแบ่งสูตรขนมให้คนอื่นได้ แต่เก็บกุญแจร้านไว้ในกระเป๋า ส่วน .env.example คือรายชื่อกุญแจที่ไม่มีตัวกุญแจ จึงแชร์ได้

ไฟล์ .env ไม่ทำงานเอง ต้องมีตัวอ่าน ถ้าค่าออกมาเป็น undefined ให้เช็ก 4 ข้อข้างบน ส่วนเว็บจริงใช้ค่าที่ตั้งไว้ในหน้าตั้งค่าของที่วางเว็บ

ตอนถัดไปในซีรีส์ เราจะดูข้อห้ามทั้ง 6 ข้อกับไฟล์ .env เพื่อไม่ให้คีย์หลุด

อาทิตย์ละสกิล เดี๋ยวก็เก่ง