# Docker 在 NAS 架設 Vue、Angular、.NET Core、MSSQL
###### tags: `Docker`
## 環境建置
### 本機 ( Windows )
1. 安裝 WSL ( [下載](https://docs.microsoft.com/zh-tw/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package) )
2. 在 WSL 上裝 Ubuntu 系統
`wsl --install -d Ubuntu`
3. 透過設定啟用 Hyper-V ( 虛擬機器 )
3-1. 以滑鼠右鍵按一下 Windows 鍵,然後選取 \[應用程式與功能\]。
3-2 在 [相關設定] 下,選取右側的 [ 程式和功能 ]。
3-3 選取 [開啟或關閉 Windows 功能]。
3-4 選取 [Hyper-V] or [虛擬機器平台],然後按一下 [確定]。

4. [下載 Docker Desktop](https://hub.docker.com/editions/community/docker-ce-desktop-windows/)
### NAS ( 群暉 )
* 安裝 Docker 即可準備使用
* Tip: 善用反向代理 ( 類似 nginx ) 來使用憑證認證

* Tip: 善用路由轉發配置 Port 號
* 建立容器的時候進階選項 > 網路都配置一個 bridge

## Docker 建置到推送至 Hub
※ Docker Hub 要用網址抓取 Image 時要注意:
原網址為`https://hub.docker.com/repository/docker/moirahan/dataapi`
抓取時為`https://hub.docker.com/r/moirahan/dataapi`
## 前端 ( 使用 VSCode )
### 1. 建立 DockerFile
#### Angular
```
### STAGE 1: Build ###
#設定一個基本的映象,FROM 後面是映象的名字,這個映象是 Docker 官方提供的,這個映象裡面包含了 Node.js,可以在node後跟冒號 申明東映象版本。as builder 是給它起了個別名
FROM node:16.14.2-alpine as builder
#WORKDIR 指令設定了工作目錄的位置,意思就是進入到 /app 這個目錄,然後要在這個目錄裡去做一些事情。這裡的目錄是在映象裡的一個位置。
WORKDIR /app
ENV BACKEND_BASE_URL='http://192.168.3.131:49165/api'
#COPY 指令可以複製本地主機上的檔案到映象裡,第一個點指的是 Dockerfile 檔案所在的目錄,這個目錄是本地主機上的位置。第二個點指的是映象裡的當前目錄,因為之前用 WORKDIR 設定了工作目錄的位置,所以第二個點在這裡指的就是映象裡的 /app 這個目錄。
COPY package.json package-lock.json .
#這一步做的事情就是把在本地上的 Angular 應用複製到映象裡面。
RUN npm install @angular/cli -g
#執行了一下 npm install 命令,也就是安裝 Angular 專案需要的所有的東西
RUN npm install
COPY . .
#它執行的是 ng build --prod,作用就是構建一個適合在生產環境上執行的 Angular 應用
RUN ng build beetle_community_web --configuration production
### STAGE 2: Run ###
#這裡的nginx版本可以去掉 就會下載 latest
FROM nginx:1.17.1-alpine
#你需要將這裡的換成你執行ng build在dist下生成的目錄 一般是你的專案名稱
COPY --from=builder /app/dist/beetle_community_web /usr/share/nginx/html
#這是將你配置好的nginx配置替換docker裡預設的nginx 建議學習nginx
COPY ./nginx-angular.conf /etc/nginx/conf.d/default.conf
# When the container starts, replace the env.js with values from environment variables
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/assets/env.sample.js > /usr/share/nginx/html/assets/env.js && exec nginx -g 'daemon off;'"]
EXPOSE 4200
```
#### Vue
```
FROM node:lts-alpine
# install simple http server for serving static content
RUN npm install -g http-server
# make the 'beetle_community_web' folder the current working directory
WORKDIR /beetle_community_web
# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./
# install project dependencies
RUN npm install
# copy project files and folders to the current working directory (i.e. 'beetle_community_web' folder)
COPY . .
# build app for production with minification
RUN npm run build
EXPOSE 8080
CMD [ "http-server", "dist" ]
```
### 2. Build Docker Image
`docker build [OPTIONS] PATH | URL | -`
`docker build -t [docker hub 帳號]/[專案名]:[tag, 當版本號使用] [Path, 通常用 .]`
Example:
`docker build -t moirahan/beetle_community_web:1.0 .`
### 3. Push Image To Docker Hub
`docker push [docker hub 帳號]/[專案名]:[tag, 當版本號使用]`
`docker push moirahan/beetle_community_web:1.0`
### 4. NAS 上的配置
#### Port 配置

## .Net Core ( 使用 Visual Studio )
### 1. 若一開始建立專案沒勾選 Docker 這樣加入 Docker 支援

### 2. 選擇 Docker 建置/發佈時就會跑出 DockerFile 檔案,但也可以自己建立
DockerFile內容
```
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
# ENV 為設置環境變數
ENV ASPNETCORE_ENVIRONMENT="Development"
ENV ASPNETCORE_URLS="http://+:49165"
# 因為 DB Server 也是 Docker 容器之一,Data Source 為 link 的 Container Name
# 但是因為這段字串在 NAS 判斷會變成
# 變數名稱: DBConnectionString=Data Source=datagrip-mssql-server-linux;Initial Catalog=BeetleCommunity;User Id=BeetleAdmin;Password
# 值: beetleadmin;
# 導致每次部署都要調整
# 於是改給 DBContainerName 就好 或是也可以直接給 Domain 的連線字串
#ENV DBContainerName="datagrip-mssql-server-linux"
# 輸出的 Port ( 只有一個因為沒有 Https )
EXPOSE 49165
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["dataApi/dataApi.csproj", "dataApi/"]
COPY ["DataDomain/DataDomain.csproj", "DataDomain/"]
COPY ["BasicCore/BasicCore.csproj", "BasicCore/"]
RUN dotnet restore "dataApi/dataApi.csproj"
COPY . .
WORKDIR "/src/dataApi"
RUN dotnet build "dataApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "dataApi.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "dataApi.dll"]
```
### 3. 先取消 Https / SSL 憑證,等部署好再設憑證,避免部署至 NAS 時,輸入 Http 網址一直導向至 Https 網址造成的錯誤
#### 3-1. Startup.cs 中,移除 app.UseHttpsRedirection(); 避免自動導向 ( 建置專案勾選 Https 的話會有 )
#### 3-2. Properties > launchSettings.json 中的 Docker 底下關於 SSL 的設置移除 or useSSL 設為 false
純參考: launchSettings.json 中的 Docker( 好像也不完全是吃這邊的設定值 )
```
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "Http://localhost:{ServicePort}/swagger",
"environmentVariables": {
"ASPNETCORE_URLS": "http://+:49165",
"ASPNETCORE_ENVIRONMENT": "Development",
"DBConnectionString": "Data Source=datagrip-mssql-server-linux;Initial Catalog=BeetleCommunity;User Id=BeetleAdmin;Password=beetleadmin;"
},
"publishAllPorts": true,
"httpPort": "49165"
}
```
### 4. NAS 上的配置
#### Port 配置

#### Log File 掛載

#### 如果使用容器間連結 (link)
* 程式 DB 連線字串的 IP 部分改為 DB 的容器名稱: datagrip-mssql-server-linux

#### 環境配置
