iT邦幫忙

0

docker 前後端分離問題

  • 分享至 

  • xImage

各位大大好
目前我嘗試用docker做前後端分離的練習
架構是這樣的
總共三個container (frontend(Vue), backend(Laravel), database)

重點擺在frontend和backend的溝通
由於我要跟外部的網站做oauth 需要填入redirect url
所以我用ngrok把frontend的port expose
我嘗試用nginx(跟frontend在同一個container上)做reserve透過docker設定的network去打到backend的api url 可是在ngrok會傳回503
我猜是ngrok在碰到nginx轉換的時候沒辦法認得
想請問解決方法或有沒有其他方式能達成我要的需求?

P.S:如果單純更改vue.config.js中的url是可以達成的

以下檔案供參考
/frontend/Dockerfile

FROM node:16 AS build
WORKDIR /app
COPY package*.json ./

RUN npm install -g @vue/cli-service \
    && npm install -g @vue/cli \
    && npm install 

RUN apt-get update \
    && apt-get install nginx -y

CMD ["npm", "run", "dev"]

/backend/Dockerfile

FROM php:7.2-fpm
WORKDIR /var/www/html/dns
COPY . /var/www/html/dns

RUN apt-get update \ 
    && apt-get install -y \
    && apt-get install libpng-dev -y \
    && apt-get install supervisor -y \
    && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer \
    && docker-php-ext-install sockets \
    && docker-php-ext-install zip \
    && docker-php-ext-install gd \
    && composer install 

CMD ["php", "artisan", "serve", "--host", "0.0.0.0"] \
    && ["php", "artisan", "queue:work", "--daemon", "--quiet", "--queue=default", "--delay=3", "--sleep=3", "--tries=3"]        

/docker-compose.yml

version: "3"

networks:
  connect:


services:
  frontend:
    build: ./frontend
    volumes:
      - ./frontend:/app
      - ./frontend/config/default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - 8080:9528
    networks:
      - connect
    tty: true
  backend:
    build: ./backend/
    ports:
      - 8000:8000
    expose:
      - 8000
    networks:
      - connect
    volumes:
      - ./backend/:/var/www/html/dns # 將專案掛載進容器裡面
    restart: always

/config/default.conf

server {
      listen  8000;
      server_name localhost;
      location /api {
        proxy_pass http://backend:8000/api;
      }
}

其餘小問題
docker有時候我更改DockerFile都還是沒變,我都要砍掉image重啟才有用,請問原因(cache?)

看更多先前的討論...收起先前的討論...
黃彥儒 iT邦高手 1 級 ‧ 2022-10-06 09:26:27 檢舉
> docker有時候我更改DockerFile都還是沒變,我都要砍掉image重啟才有用

你的猜想是對的,解法是重新 build
st474ddr iT邦新手 2 級 ‧ 2022-10-06 11:15:03 檢舉
@黃彥儒 我好懶QQ
obarisk iT邦研究生 1 級 ‧ 2022-10-06 15:23:44 檢舉
看起來你沒有啟動 nginx ?
前端是用 npm 的 web server。
st474ddr iT邦新手 2 級 ‧ 2022-10-06 22:03:40 檢舉
@obarisk 大大你對Orz
我以為裝了就會開 忘記下指令開nginx...
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

2
Han
iT邦研究生 1 級 ‧ 2022-10-06 15:29:08
最佳解答

根據測試環境或是正式環境,會有不同的容器配置
測試環境的情況下,是使用 npm run dev 來跑前端
正式環境的情況下,會將前端打包後,放到 nginx 底下直接作為靜態檔案來服務
這段看你自己使用什麼 web server 應該都大同小異

兩種,我都建議使用 nginx 來統一你對外服務的 port
flow

詳細大概是這樣配置

nginx 可以透過 docker 內部的 network 進行反向代理
這樣整個服務就會只有 nginx 是對外,而不需要開啟過多的服務

先將這個流程部署完之後,應該可以解決你大部分的問題!


每次有更動 Dockerfile 都要重新 docker compose build 並且再次啟動 docker compose up -d
才會確實生效哦!
或是你也可以直接輸入 docker compose up -d --build
這個就會在啟動之前幫你去打包相對應的 image
參考:https://docs.docker.com/engine/reference/commandline/compose_up/#options

st474ddr iT邦新手 2 級 ‧ 2022-10-06 16:56:50 檢舉

感謝大大回答 很詳細
我也是看到網路上很多方法都是用nginx當作對外
但這樣在開發時 不就用不到hot reload的方便嗎
畢竟前端打包完就放著,如果有一點小改就要下指令再重打包

這也是我用node image然後再把nginx裝進去的原因

Han iT邦研究生 1 級 ‧ 2022-10-06 17:49:19 檢舉

一樣可以哦 只要在 nginx 加入 websocket 的條件就可以了
不過我不清楚 vue 的機制 他也是用 webpack 的 hot reload 嗎
一樣的話可以參考以下設定

  location /ws{
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;

    proxy_pass http://frontend:3000;

    proxy_redirect off;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
st474ddr iT邦新手 2 級 ‧ 2022-10-06 22:04:37 檢舉

好的大大 我來試試

我要發表回答

立即登入回答