เขียน LaTeX ด้วย VSCode และ TeX Live Docker Image — EP1
Tags: vscode, thailatex, latex, docker
Published: 2021-03-25 23:01:18

---
title: เขียน LaTeX ด้วย VSCode และ TeX Live Docker Image — EP1
published: true
date: 2021-03-25 22:52:47 UTC
tags: vscode,thailatex,latex,docker
canonical_url: 
---

### เขียน LaTeX ด้วย VSCode และ TeX Live Docker Image — EP1

บันทึกการเขียน LaTeX ด้วย VSCode โดยใช้ TeX Live Docker Image และ การใช้ Visual Studio Code Remote — (SSH,Container) และ Visual Studio Code LaTeX Workshop Extension

โดยปกติผมรู้จัก LaTeX มานานแต่ไม่เคยเข้าถึงมันเลย ใช้แค่ระดับทดสอบไม่ได้ใช้จริงจังเป็นกิจวัตรดังนั้นหลายๆ อย่างก็ไม่ค่อยรู้เรื่อง ช่วงนี้ก็นำเอามาใช้งาน เช่นตัวช่วยสร้าง PDF และ ลองเขียนโน้นนี่ไปเรื่อย ปกติเครื่องมือที่ใช้เขียน LaTeX มีหลายตัว แต่ในบันทึกครั้งนี้ผมจะใช้ VSCode + Visual Studio Code Remote — (SSH,Container) Extension+ Visual Studio Code LaTeX Workshop Extension และ TeX Live Docker Image ซึ่งสามารถใช้ได้ทั้งบนเครื่องส่วนตัว และ การตั้งเป็น Server ให้เพื่อนร่วมทีมเข้ามาใช้งานร่วมกันได้

EP1 จะเป็นเรื่องการเตรียม Docker Container นะครับ ส่วน EP 2 จะแนะนำการเขียน LaTeX เบื้องต้น

บันทึกนี้มีอยู่สองสามวิธีค่อยๆ อ่านนะครับอาจจะงงๆ ไปบ้างแต่ถ้าเข้าใจก็จะใช้มันสนุกมาก ถ้าใช้งานปกติใช้ แบบ Remote — Container จะง่ายสุด แต่ถ้าใช้หลายๆ คนบน Server แบบ Remote — Container มันอาจจะยุ่งยากหน่อยเรื่อง docker context เราอาจจะใช้แบบ SSH เข้ามาช่วยก็ได้

### Run TeX Live Docker Container

สำหรับ Docker Image ที่ใช้ผมสร้างไว้ใช้เองรายละเอียดอ่านด้านล่างของบทความ

#### TeX Live Only Image

```
docker run -itd \
  --hostname texlive \
  --name texlive \
  -v ${PWD}/datas:/root/data \
  mrchoke/texlive
```

ข้างบนจะใช้ options ดังนี้

- hostname จะตั้งหรือไม่ก็ได้แต่ถ้าตั้งไว้ตอน ssh เข้าไป prompt ก็จะขึ้นชื่อแทน hash ของ ID
- name จะตั้งหรือไม่ก็ได้ถ้าตั้งก็จะง่ายตอนจัดการเช่น ps ดูก็เข้าใจง่าย จะสั่ง stop start restart หรือ delete ด้วยชื่อก็ง่ายหน่อย
- v mount volume เข้าไปเพื่อจะได้จัดการ files งานของเราได้ง่ายเวลาลบ container ทิ้ง files จะได้ไม่หาย (สำหรับ Windows 10 ให้ใช้บน PowerShell ${PWD} ถึงจะทำงานได้ถูกต้อง)
- mrchoke/texlive เป็น image ที่ผม publish ไว้ที่ hub.docker

#### With SSH

```
docker run -itd \
  --hostname texlive \
  --name texlive \
  -v ${PWD}/datas:/root/data \
  -p 2222:22 \
  mrchoke/texlive:2021-ssh
```

- p ในกรณีที่ run docker เพื่อแชร์กับเพื่อนๆ ให้ bind port 22 มายัง host เพื่อจะได้ ssh เข้าไปได้ตรงนี้ถ้ากำหนด 2222:22 ก็จะ bind ที่ 0.0.0.0 ใครก็ได้สามารถเข้ามายังเครื่องเราได้ถ้าเป็น public server ก็ต้องระวังให้ดีซึ่งเราสามารถ กำหนดเป็น 127.0.0.1:2222:22 หรือ 192.168.0.1:2222:22 ก็แล้วแต่เราจะเข้มงวดการเข้าถึงขนาดไหน แต่ถ้าใช้คนเดียวไม่จำเป็นต้อง bind นะครับเราสามารถใช้ Remote Container Extension เข้ามาได้เลย

#### With authorized\_keys

```
docker run -itd \
  --hostname texlive \
  --name texlive \
  -v ${PWD}/datas:/root/data \
  -v ${PWD}/.ssh:/root/.ssh \
  -p 2222:22 \
  mrchoke/texlive:2021-ssh
```

หรือถ้าใครต้องการใช้ ssh-key ในการ login ก็สามารถ mount .ssh ที่มี file authorized\_keys เข้าไปใน /root ของ container ก็ได้

ลองตรวจสอบว่า docker สามารถ run ได้สำเร็จหรือไม่

#### TeX Live Only

```
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7615fbdb871 mrchoke/texlive “/bin/sh” 6 seconds ago Up 5 seconds texlive
```

#### With SSH

```
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24ad39e3cae9 mrchoke/texlive:2021-ssh "/usr/sbin/sshd -D" 4 seconds ago Up 3 seconds 0.0.0.0:2222->22/tcp texlive
```

#### ข้อดี — ข้อเสีย

**TeX Live Only**

- ใช้บนเครื่องเราได้เลยไม่ต้องเปิด port เพิ่มเติม exec เข้าไปใช้งานได้ปกติ
- เชื่อมต่อกับ VSCode Remote — Container ได้เลยสะดวกมาก
- ใช้งานร่วมกันอาจจะต้องใช้ผ่าน git ในการจัดการอาจจะ conflict กันได้ถ้าจัดการแบ่งงานกันไม่ดี
- ถ้าใช้บน Server ทางฝั่ง Client ต้องใช้ Docker context ซึ่งอาจจะยุ่งยากไปบ้าง

**With SSH**

- กรณีใช้งานร่วมกันหลายคนบน Server เราสามารถสร้าง user เข้ามาใช้งานใน container ที่เราสร้างขึ้นไม่ยุ่งกับ user บนระบบจริง
- กรณีเขียนร่วมกันเข้าไปที่เดียวกันได้เลยแต่ต้องแบ่งกันเขียนเป็นส่วนๆ ไปจะได้ไม่ทับกัน
- กรณีใช้ VSCode เข้าไปยัง Server ก็ใช้ผ่าน Remote — SSH ได้เลยสะดวกกว่าแบบ Docker Context
- มันเหมือน Linux Server เครื่องหนึ่งดีๆ นี่เอง
- ถ้าทำบนระบบที่ public ก็ต้องระวังผู้ไม่หวังดีบุกรุกเพราะความปลอดภัยไม่ได้ตั้งไว้สูง

### Remote (SSH,Container)

หลังจาก Start Container เรียบร้อยแล้วเราสามารถเข้าไปยัง container ได้ 3 รูปแบบคือ

1. docker exec เข้าไปใช้งาน

```
docker exec -it texlive bash
```

2. SSH

ใช้ port ที่ bind ไว้ตอน run ครั้งแรก

```
ssh -p 2222 root@localhost
```

หรือ ในกรณีเข้าไปยัง server

```
ssh -p 2222 root@server-ip
```

ถ้าไม่ได้ใช้ ssh-key ก็ใส่รหัสผ่าน default **123456** แต่ถ้าจะเปลี่ยนรหัสผ่านก็สามารถใช้คำสั่ง

```
docker exec -it texlive passwd
```

3. Visual Studio Code Remote — (SSH,Container)

ซึ่งจะใช้ความสามารถของ VSCode Remote Extension จะกล่าวในหัวข้อถัดไป

### Visual Studio Code Remote — (SSH,Container)

#### VSCode Remote — Container (localhost)

![](https://cdn-images-1.medium.com/max/1024/1*625ZZjfs2QqXnX7GSo8mMg.png)<figcaption>Remote Container Extension</figcaption>

วิธีนี้ไม่จำเป็นต้อง bind port ssh ออกมานะครับ เพราะเราจะใช้ VSCode เข้าไปใช้งาน Container โดยตรงบนเครื่องของเราเอง โดย Click ที่ icon รูป computer บน Side Bar ด้านซ้านมือ

![](https://cdn-images-1.medium.com/max/130/1*BipVfW4Gkz-wc-wIQSUw6g.png)<figcaption>Remote icon</figcaption>

หลังจากนั้นให้ click เลือก Target ของ Remote Extension

![](https://cdn-images-1.medium.com/max/640/1*tCciMRnXwzHq_Yj80P5rfQ.png)

มันจะมีสองแบบคือ

- Containers
- SSH Targets

วิธีนี้ให้เลือก Containers

![](https://cdn-images-1.medium.com/max/872/1*asS8FqSZwgmGfmUY1GWx4A.png)<figcaption>Remote Extension Container</figcaption>

ถ้าเรา start container ไว้ก็ควรจะเห็นเหมือนในภาพตัวอย่างด้านบนให้เรา Click ขวาบนชื่อ container ที่เราต้องการจะเข้าไปใช้งาน

![](https://cdn-images-1.medium.com/max/838/1*8WEYJhcHV8e4suBh7fgj8g.png)<figcaption>Click ขวา</figcaption>

และให้เลือก Attach to Container หลังจากนั้นก็จะมีหน้าต่างใหม่เปิดขึ้นมาพร้อมเข้าไปยัง directory ที่เราได้ทำการ mount ไว้ตอนสั่ง run คือ /root/data นั่นเอง

![](https://cdn-images-1.medium.com/max/1024/1*UpzuZkriWzSfVPnS9ik1jA.png)<figcaption>หน้าต่าง VSCode ที่ Remote ไปยัง Docker Container</figcaption>

#### VSCode Remote — Container (Over SSH)

![](https://cdn-images-1.medium.com/max/989/1*278diKD__g7TGSs-vUSeTw.jpeg)<figcaption>VSCode Remote — Container</figcaption>

สำหรับการใช้ Remote — Container สามารถใช้งานข้ามเครื่องได้โดยการใช้ความสามารถของ Docker ผ่าน DOKCER\_CONTEXT หมายความว่า

- เราต้องเปิด Docker ทั้งฝั่ง Client และ Server
- เราต้องสามารถ SSH เข้าไปยัง Server ได้
- มีสิทธิใช้งาน Docker ได้

วิธีการง่ายๆ คือ เราสั่ง docker run texlive image ไว้ที่ฝั่ง Server แล้วเลือก DOCKER\_CONTEXT ขี้ไปที่เครื่อง Server หลังจากนั้น ตัว Extension ก็จะสามารถ attach มาใช้งานเปรียบเสมือนอยู่บนเครื่องเราเอง

#### Create Docker Context

สร้าง Docker Context สำหรับการเชื่อมต่อไปยัง Server ผ่านทาง SSH

```
docker context create texlive --docker "host=ssh://mrchoke@192.168.1.17"
```

- texlive คือชื่อของ context ที่สร้างขึ้นมาจะใช้ชื่ออะไรก็ได้
- — docker บอก option สำหรับการเชื่อมต่อซึ่งตัวอย่างจะเป็น ssh:// ตามด้วย user และ hostname/IP ถ้า port ไม่ใช้ 22 ก็ให้ใส่เพิ่มหลัง IP ได้ เช่น "host=ssh://mrchoke@192.168.1.17:2222"

ลองตรวจสอบดูครับว่าตอนนี้มี context อะไรอยู่บ้าง

```
docker context ls
NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
default * moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
texlive moby ssh://mrchoke@192.168.1.17
```

จะเห็นรานการทั้งหมดของ context ซึ่งตัวปัจจุบันที่ใช้อยู่จะมีเครื่องหมาย \* อยู่หลังชื่อปกติจะเป็น defualt

**การเลือกใช้ context**

ทำได้สองแบบคือ

1. แบบชั่วคราว

ให้ใช้ตัวแปร DOCKER\_CONTEXT เลือก context ที่ต้องการ วิธีนี้ต้องพิมพ์แบบนี้ทุกครั้งหน้าคำสั่ง docker ซึ่งจะยุ่งยากแต่เหมาะกับการใช้แบบครั้งคราว

```
DOCKER_CONTEXT=texlive docker ps
```

2. แบบ Global

วิธีนี้สามารถสั่งด้วย command โดยตรงก็ได้ หรือ จะใช้ docker extension ของ VSCode เลือกก็ได้ หลังจากเลือกแล้วทุกครั้งที่สั่งคำสั่ง docker สิ่งที่เห็นคือทางฝั่ง server ที่ context ชี้ไป

```
docker context use texlive
docker ps
```

![](https://cdn-images-1.medium.com/max/870/1*qCZQjK2k86ci284LWm28MQ.png)<figcaption>ใช้ VSCode Docker Extension</figcaption>

\*\*\* สำหรับเครื่อง Server ที่ติดตั้ง docker ไว้ใน path อื่นนอกเหนือจาก /usr/bin ฝั่ง client จะไม่สามารถหาคำสั่ง docker ได้ต้องตั้งค่า sshd เพิ่มเติมคือให้แก้ไข

```
/etc/ssh/sshd_config
```

โดยเพิ่ม หรือ แก้ PermitUserEnvironment ให้เป็น yes

```
PermitUserEnvironment yes
```

แล้วกำหนด PATH ใน

```
~/.ssh/environment
```

เช่นใน macOS docker จะอยู่ใน /usr/local/bin/docker ก็ให้ตั้ง

```
PATH=/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin
```

![](https://cdn-images-1.medium.com/max/882/1*UDiiPHREamsIXjyyYJf7VA.png)<figcaption>Docker Extension get ข้อมูลไม่ได้</figcaption>

จากที่ทดลองเล่นตัว Docker Extension มันจะดึงข้อมูลทางฝั่ง Server มาไม่ค่อยได้ จะ error เหมือนรูปด้านบน แต่ตัว Remote — Container จะเห็นปกติ แต่ก็มีเอ๋อบ้างบางครั้งนะครับ

![](https://cdn-images-1.medium.com/max/882/1*EzjHwmak5y-Q9RWzOMWACA.png)<figcaption>VSCode Remote — Container Extension</figcaption>

ถ้าได้แบบรูปด้านบนก็สามารถใช้งานเหมือน container อยู่บนเครื่องตัวเองได้เลยครับ

#### Visual Studio Code Remote — SSH

![](https://cdn-images-1.medium.com/max/989/1*nuXFLw0md4pHhPscMQvT1w.jpeg)<figcaption>VSCode Remote — SSH</figcaption>

![](https://cdn-images-1.medium.com/max/1024/1*5kuHhsDt2ULrnu45-GUZkQ.png)<figcaption>Remote SSH</figcaption>

ส่วน Remote — SSH นั้นเราต้องสั่ง run พร้อมกับ bind port ออกมาด้วยนะครับตัวอย่างของผมจะ bind ไว้ที่ 2222 ซึ่งสมมติว่าผมจะ remote ไปยังเครื่อง server ละกันจริงๆ เครื่องตัวเองนั้นแหละ ฮาๆ

![](https://cdn-images-1.medium.com/max/896/1*h7wVr1QH3kRY-P1A0GYCaw.png)<figcaption>SSH Targets</figcaption>

ให้เลือกการเชื่อมต่อแบบ SSH ด้านบนก่อนนะครับ หลังจากนั้นให้กดเครื่องหมาย +

![](https://cdn-images-1.medium.com/max/1024/1*vsw2DjECAG8NOjokyFqHqw.png)<figcaption>ssh command</figcaption>

ให้ใส่คำสั่งเหมือนกับที่เราสั่งบน terminal ปกติได้เลยจากตัวอย่างเช่น

```
ssh -p2222 root@localhost
```

ตรงนี้ถ้าเป็นเครื่อง server ก็ให้ใส่ IP หรือชื่อ Host แทน localhost

![](https://cdn-images-1.medium.com/max/1024/1*u6vITQ5oCspo0mglOTx7iw.png)<figcaption>เก็บ config ไว้ที่ไหน</figcaption>

หลังจากนั้นก็จะถามว่าจะให้ save config นี้ไว้ที่ไหนวิธีที่ง่ายที่สุดคือตัวเลือกแรกคือให้เก็บไว้ใน .ssh/config ใน HOME ของเราเอง

![](https://cdn-images-1.medium.com/max/872/1*ywhtRLy5DJRiOf2fkjrVOQ.png)<figcaption>รายชื่อ SSH Targets</figcaption>

หลังจากที่เราป้อนคำสั่งแล้วจะมีรายชื่อเพิ่มขึ้นมาคือ localhost นั่นเอง รายชื่อตรงนี้เราสามารถเข้าไปจัดการได้โดยตรงใน file .ssh/config สามารถตั้งชื่อให้ได้ หรือจะเพิ่มรายการเข้าไปเองโดยตรงก็ได้เช่นกัน

![](https://cdn-images-1.medium.com/max/1024/1*7pH5JxyLqHgR2gKs_bLKHg.png)<figcaption>Connect to Host</figcaption>

หลังจากนั้นให้ Click ขวาบนชื่อ SSH Targets ที่เราต้องการจะ Connect เลือกว่าจะเปิดในหน้าต่างปัจจุบันหรือหน้าต่างใหม่

![](https://cdn-images-1.medium.com/max/1024/1*795umqev-6TWzPezRJa-fA.png)<figcaption>Confirm การเข้าครั้งแรก</figcaption>

ถ้าเราเข้าครั้งแรกจะมีการให้ confirm ก่อนโดยเลือก Continue

![](https://cdn-images-1.medium.com/max/1024/1*DWI8cqPKGuCy33P15ySYjQ.png)<figcaption>Password</figcaption>

ถ้าไม่ได้ใช้ ssh-key ก็ให้ใส่รหัสผ่าน ถ้า default ก็ใส่ 123456 ถ้าเปลี่ยนรหัสผ่านไปแล้วก็ให้ใส่ที่ตั้งไว้ แต่ถ้าตั้ง ssh-key ก็จะไม่มีหน้าต่างนี้

![](https://cdn-images-1.medium.com/max/494/1*E6D4hRq_iHnMwg828X7LMg.png)<figcaption>สถานะมุมขวาล่าง</figcaption>

การ Connect ไปยัง SSH Server ครั้งแรกจะช้าหน่อยเพราะมีการติดตั้ง VSCode Server ก่อน แต่ถ้าครั้งต่อไปก็จะเร็วกว่า นอกจากจะมีการ Upgrade Version ของ VSCode

![](https://cdn-images-1.medium.com/max/1024/1*BCUVDmmf6J8_cS4J2UQx7w.png)<figcaption>Connect สำเร็จ</figcaption>

ถ้า Connect สำเร็จก็จะขึ้นหน้าต่างดังรูปด้านบนซึ่งจะมีหน้าต่าง Terminal ด้านล่างให้ด้วยเราสามารถพิมพ์คำสั่งของ Linux ในนี้ได้เลย

### Visual Studio Code LaTeX Workshop Extension

หลังจากนี้ให้ติดตั้ง Visual Studio Code LaTeX Workshop Extension เพิ่มทางฝั่ง Remote ทำเหมือนกันทั้ง SSH และ Container

![](https://cdn-images-1.medium.com/max/1024/1*3972Su0XQg99I0bwowmFlw.png)<figcaption>Visual Studio Code LaTeX Workshop Extension</figcaption>

### Open Folder

เมื่อติดตั้ง Extension เสร็จพร้อมใช้งานแล้วถ้าเป็น Remote SSH เราต้องเปิด Folder ก่อนส่วน Remote Container จะเปิดให้แล้วตั้งแต่แรก วิธีเปิดก็ Click ที่ icon files บน Side Bar ด้านซ้าย

![](https://cdn-images-1.medium.com/max/672/1*2MehhzYfRS8CPCIoPv65jQ.png)<figcaption>Open Folder</figcaption>

![](https://cdn-images-1.medium.com/max/1024/1*pLpwUmrSUNixx77_rDg7fQ.png)<figcaption>ช่องเลือก</figcaption>

โดยปกติแล้วจะมีช่องให้เลือกโดยเริ่มใน Home Directory ของ root ตอนสั่ง run ผมได้ mount ไว้ที่ /root/data ก็ให้ click ที่ Folder data ได้เลยครับ

![](https://cdn-images-1.medium.com/max/1024/1*EjF_LLzK7bPKWCVKJmzxdg.png)<figcaption>เลือก</figcaption>

![](https://cdn-images-1.medium.com/max/1024/1*vXiW6dwLUOwSO8v00FVeBw.png)<figcaption>Work Space</figcaption>

หลังจากนั้นก็จะปรากฎหน้าต่าง Work Space สำหรับการทำงานขึ้นมาโดยชื่อในช่อง Explore ด้านซ้ายจะเป็น Folder ที่เราเลือกไว้เมื่อตะกี้

EP2 จะแนะนำการใช้งาน pdfLaTeX และ XeLaTeX เบื้องต้นต่อไปครับ

[เขียน LaTeX ด้วย VSCode และ TeX Live Docker Image — EP2](https://dev.to/mrchoke/latex-vscode-tex-live-docker-image-ep2-2cgo)

### TeX Live Docker Image

[Docker Hub](https://hub.docker.com/r/mrchoke/texlive)

เป็น Image ที่ผม Build ไว้ใช้เองสำหรับการเขียนเอกสารซึ่งจะมี Python พ่วงเข้าไปด้วย สามารถดู Dockerfile ได้ที่

[mrchoke/texlive](https://github.com/mrchoke/texlive)

วิธี Build ที่ publish ไว้ใน docker hub ผมใช้ buildx โดยให้ใช้ได้ทั้ง amd64 และ arm64 หมายถึงสามารถใช้บน Docker บนเครื่อง Apple M1 ได้ด้วย

```
docker buildx build --platform linux/arm64,linux/amd64 -t mrchoke/texlive:2021 -t mrchoke/texlive:2021.1 -t mrchoke/texlive:latest --push .
```

ปกติการติดตั้ง TeX Live ฉบับเต็มจะใช้เนื้อที่ราวๆ 8 GB ในตัว Image ข้างบนผมจะตัดพวก Doc กับ Src ออกเนื้อที่จะลดลงมาเกือบๆ 50% อยู่ที่ราวๆ 4.5 GB