簡體   English   中英

在 AWS 中部署並運行 Docker

[英]Deploy and run Docker in AWS

我剛剛完成我的 React 和 NodeJS 項目並為每個項目創建一個 Dockerfile,然后創建一個 docker-compose 文件為每個項目創建 docker 圖像(前端和后端)。

我還將圖像推送到 Docker 集線器中的存儲庫。 我現在該怎么辦? 我想在 AWS EC2 中運行我的 docker 項目,所以我在我的 AWS 儀表板中創建了一個新的 EC2 實例並在那里安裝 docker 並設法從我的 docker 下載我的圖像...

但是現在我很困惑,我需要創建一個容器來運行它們嗎? 我需要單獨運行每一個嗎?

另外,我使用 Nginx 來使用端口 80 而不是默認的 3000。

我現在真的迷路了(第一次使用 Docker 和 AWS)謝謝!

編輯 1

我用於 React 的 dockerfile 是:

# build environment
FROM node:13.12.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm ci --silent
RUN npm install react-scripts@3.4.1 -g --silent
COPY . ./
RUN npm run build

# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
# new
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

我的 Nodejs 的 dockerfile 是:

FROM node:8

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./

RUN npm install

# Bundle app source
COPY . .

EXPOSE 5000

CMD [ "npm", "start" ]

我的 Nginx 配置文件是:

server {

  listen 80;

  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  error_page   500 502 503 504  /50x.html;

  location = /50x.html {
    root   /usr/share/nginx/html;
  }

}

我的 docker-compose.yml 文件是:

version: "2"
services:
  frontend:
    image: itaik/test-docker:frontend
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
  backend:
    image: itaik/test-docker:backend
    build: ./backend
    ports:
      - "5000:5000"

在我的計算機(Windows)上,我下載了 Docker 桌面應用程序,並使用 docker 組合命令,它用我的兩個圖像創建了一個容器,一切都很棒,這就是我試圖在我的 AWS EC2 上實現的目標( Linux)。 希望現在事情更清楚了。

編輯 2

好的,所以我設法用不同的容器運行我的兩個圖像,並且它們現在都在線,就像我想要的那樣我使用命令:

docker run -d -p 5000:5000 itaik/test-docker:backend

docker run -d -p 80:80 itaik/test-docker:frontend

但是現在,由於某種原因,我對“localhost:5000”的所有 API 調用都出現錯誤:

GET http://localhost:5000/user/ net::ERR_CONNECTION_REFUSED

這與我的 React/Nodejs 代碼或我設置 docker 圖像的方式有關嗎?

謝謝!

編輯 3

即使在我使用 docker-compose 並且兩個圖像都在同一個網橋上運行之后,我仍然遇到該錯誤。

我能想到的唯一解決方案是手動編輯我的代碼並將“localhost”更改為 AWS public IP,但我想我只是錯過了一些需要做的事情......也許我的網橋對公共 IP 不可見? 因為當我進入公共 IP(端口 80)和端口 5000 時,我確實得到了響應。

但是對 localhost:5000 的 API 調用出現錯誤。

可能使這項工作的最短路徑是

  • 將前端與后端合並到同一個 docker 映像中(因為您必須從某個地方提供您的捆綁包,而后端是最近的已經准備好的地方)

  • 確保主機和端口設置以及容器在您的機器上正常工作

  • 將圖像推送到 DockerHub(或例如 AWS ECR)

  • 在 AWS EC2 上獲取機器並在那里安裝 docker(並且,如果需要,Docker 編寫)

  • 確保您機器的控制組允許傳入端口的流量(右鍵單擊 AWS 控制台上的實例),您的應用程序將在其上運行(對於您的示例,您應該打開端口:80

  • 拉取鏡像並啟動容器(或通過 docker-compose 啟動 2 個),端口設置為80:3000 (假設您的應用程序服務於:容器上的 3000)

  • 在同一個 AWS EC2 控制台上單擊您的實例,您將看到您機器的公共地址(例如ec2-203-0-113-25.compute-1.amazonaws.com

  • 我認為這些是最常見的陷阱

我建議將您的應用程序部署在單個映像中(例如,在您將其構建到 static 包中后,Express 可以輕松地為您的前端應用程序提供服務),因為使容器相互通信可能需要一些時間。

但是,如果您仍然希望使用 2 個組件為您的應用程序提供服務——前端來自 Nginx,后端來自 NodeJS,那么您可以使用 docker-compose。 只需確保每個組件的主機設置正確(它們不會在本地主機上看到對方)


更新 2

實際上有兩種方法可以使前端與后端通信(我想您可能正在使用 axios 或類似的 API 調用):

1st way - is to explicitly set up http://<host>:<port> as axios baseURL so all your api calls become interpolated into http://ec2-203-....amazonaws.com:3000/api/some-data 但是您應該知道確切的主機,您的后端正在服務。 也許這是最明確和最簡單的方法:)

第二種方法 - 是讓瀏覽器找到您的服務器 我並不十分熟悉它是如何工作的,但在高層次上它是這樣工作的:用戶從yousite.com獲取您的應用程序作為捆綁包。 並且應用程序需要從后端獲取數據,但在代碼中,這些調用是“相對的”——只聲明了/api/some-data

由於沒有設置后端主機,應用程序要求瀏覽器找到它的“家”,我想location.hostname成為此類調用的主機,所以完整的 url 變成http://yousite.com/api/some-data .

但是,正如您所看到的,如果用戶進行此調用,它將命中 Nginx 而不是實際的后端,因為 Nginx 是服務於前端的那個。

所以接下來你必須做的事情 - 將此類調用從 Nginx 代理到 NodeJs。 還有另一件事 - 只有 API 調用應該被代理。 其他調用應該像往常一樣返回你的包。 所以你必須以這種方式設置代理:

location /api/ {
  proxy_pass http://backend:5000;
}
  • 請注意,NodeJs 應用程序位於backend:5000上,而不是localhost:5000 - 這就是 docker-compose 設置 DNS 的方式

所以現在 Nginx 做了兩件事:

  • 提供 static 內容
  • 反向代理 api 調用您的后端

您可能已經注意到,要讓您的應用程序在 2 個容器中工作,它有很多棘手的部分。 這就是您可以使用 express 提供 static 內容(來自目錄build )的方式,因此您不需要使用 Nginx:

const app = express();
app.use('/', express.static(path.join(__dirname, 'build')));

我建議嘗試第一種方式 - 明確設置主機:端口 - 並啟用所有日志記錄,以便您知道發生了什么。 完成第一部分后,更新 Nginx 以使其正常工作

祝你好運!

首先,要與在同一個 ec2 實例上運行的另一個 docker 服務進行交互,您不需要通過公共互聯網 go。

其次,您的 React 應用程序無法通過http://localhost:5000訪問后端服務,因為后端服務不在同一個 docker 實例中運行。

您應該能夠通過http://backend:5000從反應 docker 訪問后端服務。 請檢查並回復我。

與您的問題無關,但建議,

您的反應應用程序是面向公眾還是內部應用程序,如果它是面向公眾的,您可以輕松地從亞馬遜 S3 本身運行您的反應應用程序,因為亞馬遜 s3 支持 static 網站托管。 您可以簡單地將 react 應用程序復制到 s3 存儲桶中,並將其作為 static 網站運行。 這也允許您通過雲端設置 SSL。

希望這可以幫助。

參考: 如何設置 s3 static 網站

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM