---
# System prepended metadata

title: Docker (六) docker-compose 即時開發網頁
tags: [Docker]

---

###### tags: `Docker`

<style>
.alertText {
  color: red;
  font-weight: 700;
  font-size: 20px;
}
</style>

# Docker (六) docker-compose 即時開發網頁

這次的目標是希望在不重新 build image 的情況下可以執行 docker 並即時開發我們的專案(以前端的開發舉例)，不知道還記不記得之前有提過如果我們有變動到東西，是需要加上 --build 的。
```
docker-compose up -d --build
```

所以接下來會介紹2種情境該怎麼去實作，不過這次是只使用 docker-compose 來開發，而且**不使用到 --build**。

## 情境一，使用 node image 掛載專案並即時開發

我們希望透過使用 docker 配置 node image 掛載我們 vue-cli 的專案，並且可以即時開發，至於該怎麼時做呢?

其實很簡單，是我們在先前就已經使用過的 **volumes**，很神奇吧，當初在使用的時候也沒想到可以做到這種效果，

接下來趕快來看看 docker-compose 是怎麼寫的吧

```yaml=
version: "3.7"

services:
  app:
    image: node
    container_name: vuenode
    ports:
      - 3000:8080
    restart: always
    working_dir: /app
    volumes:
      - /home/andy/vueapp/vue_node:/app
    command: npm run serve
```

這邊有把之前寫在 Dockerfile 的設定搬過來，像是 WORKDIR 跟 CMD，好了之後就可以打開 3000 port 看看了

![](https://i.imgur.com/jTBWo6I.png)

那麼我們再到 App.vue 更改一些內容，再跑回去看網頁~

![](https://i.imgur.com/4xNvim3.png)

🙉 怎麼剛剛沒有，現在有~ 哈哈 ( 古老梗...) ，是不是有點神奇，當初都沒發現~

## 情境二，使用 nginx image 掛載 build 出來的靜態文件並即時開發

這部份是我覺得這篇中最複雜的地方，其中會再介紹到關於 nginx 的配置

首先我們已經會了上面的部份，所以我們可以開開心心的寫出 docker-compose

```yaml=
version: "3.7"

services:
  app:
    image: nginx
    container_name: nginx_dist2
    ports:
      - 5000:80
    restart: always
    volumes:
      - /home/andy/vueapp/nginx_dist_copy/dist:/usr/share/nginx/html
```
然後因為我們要掛載的是 dist 資料夾的東西，所以如果沒有這個資料夾可以先在專案執行 **npm run build**

![](https://i.imgur.com/rEDoxy5.png)

好了之後可以到網頁上去看 

![](https://i.imgur.com/gsUQQNf.png)

開開心心的看到了我們的畫面了

<span class="alertText">但是 !!!</span>，還記得我們要做甚麼嗎? 沒錯，我們還需要可以即時開發啊~

那我們一樣改一下內容再 build 一次總可以了吧~

![](https://i.imgur.com/PydNfI4.png)

😨😨😨 這...怎麼會是這樣，我太天真的了~


### 接下來，一步一步地來修正吧 ~
:::danger
重點一， 當我們執行 npm run build 時，會將舊有的 dist 資料夾刪除並重新建立
:::

仔細去看左邊的檔案目錄就可以發現了~ 是不是在那一瞬間消失不見了

![](https://i.imgur.com/eDKiDtI.jpg)
![](https://i.imgur.com/4W0jqVi.jpg)

我們同時進去 container 內查看

![](https://i.imgur.com/1e0Svph.png)

@@   我們掛載上去的 /usr/share/nginx/html 裡面怎麼甚麼東西都沒有 !!!


:::info
原因是我們的 **volumes 配置**，因為我們綁定的資料夾路徑是 dist，所以當重新 build 文檔時，container 內的東西會同時被刪除，但我們專案自己有執行 build 的動作所以會重新建立，不過 container 並沒有
:::


於是我們就不能將 volumes 綁在 dist 資料夾上了，先退到專案的資料夾再來想辦法。

```yaml=
version: "3.7"

services:
  app:
    image: nginx
    container_name: nginx_dist
    ports:
      - 5000:80
    restart: always
    volumes:
      - /home/andy/vueapp/nginx_dist_copy:/usr/share/nginx/html
```
改完 docker-compose 後再執行一次 ***docker-compose up -d*** 結果，還是網頁錯誤

![](https://i.imgur.com/5gg5mjF.png)

但是我們如果透過網址加上 /dist/index.html ，可以看到網頁了，但還不是我們要的，vue 的那個大大的 logo 還沒有出現

![](https://i.imgur.com/RAlTotK.png)


:::danger
重點二， nginx 的相關配置
:::

根據上面 /dist/index.html 是可以找到東西的，但是我們配置的是 5000 port ，所以網址只會是 http://127.0.0.1:5000/ ，也不可能做出去的網站總是要用戶幫我們再自行加上 /dist/index.html 之類的吧

所以這邊對我來說又是新的東西呢，如果沒有朋友的教學還真不知道這一塊，接下來就好好筆記一下囉

#### (1) 找到 nginx 配置的設定檔

預設路徑會是在 **/etc/nginx/conf.d/** ， 所以我們進去 container 後進去看看吧~

![](https://i.imgur.com/jNwpAmc.png)

進去後可以看到有一個檔案，把他打印出來後複製下來，是我們需要的範本 !!

![](https://i.imgur.com/NXgU6Gd.png)

#### (2) 寫自己的 nginx 配置

因為我們 volumes 綁定的是專案的資料夾，所以直接在專案的資料夾創建一個 .conf 檔案

可以看到 location 的地方，是不是很熟悉? 沒錯，就是我們 volumes 掛載 container 的地方，所以我們把 /dist 加上後就可以自動幫我們進入到 dist 資料夾，檔案修改如下 :

**ann.conf**
```conf=
server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html/dist;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

:::warning
:warning: 這邊稍微介紹一下，可以再上網搜尋更多詳細的解釋~
1. 關於 location 的配置， root 也可以換成 alias，但是兩者之間有些不同
     root : 結尾 **不需要** 加上 /
     alias : 結尾 **需要** 加上 /


2. location 路徑也可以有些配置
    像是， location ^~ /help
    表示說 只要路徑中有符合到 help 就會被導到指定的網址路徑了
:::

:::danger
重點三，把自己寫的 .conf 也配置進去吧 ~
:::

所以我們必須把 .conf檔 也透過 volumes 配置到 container 上，修改後最終 docker-compose 會是下面這樣 :

```yaml=
version: "3.7"

services:
  app:
    image: nginx
    container_name: nginx_dist
    ports:
      - 5000:80
    restart: always
    volumes:
      - /home/andy/vueapp/nginx_dist_copy:/usr/share/nginx/html
      - /home/andy/vueapp/nginx_dist_copy/ann.conf:/etc/nginx/conf.d/ann.conf
```

:::warning
**記得** .conf 讀取的預設路徑是 **/etc/nginx/conf.d/**

**記得** 這次的 volumes 配置，**完整的檔案名稱** 一併寫上
:::

最後我們 ***docker-compose up -d*** 後先來看一下

![](https://i.imgur.com/OaBoyil.png)

感動~ 終於成功出現了~ 🤗🤗，而且不需要再手動編輯網址了

接著再來重 build 看看吧

![](https://i.imgur.com/ucj2E5J.png)


:::info
哈~ 終於完成了這次的練習了~
不過還有可以優化的部分，像是 .conf 檔在 container 內總共會有兩份，因為我們的  
- /home/andy/vueapp/nginx_dist_copy:/usr/share/nginx/html
複製了一次
- /home/andy/vueapp/nginx_dist_copy/ann.conf:/etc/nginx/conf.d/ann.conf
又複製了一次

但是今天就先完成到這邊，優化的部份就等下次吧~
:::
