(开包即用,不用看代码!)借助Windows共享文件夹在Docker中运行Angular
- 开包即用,不用看代码!
- 使用管理员权限启动PowerShell
- 进入工作文件夹
- 下载代码
- 进入代码文件夹
- 更新子模块代码
- 第1步:共享Windows文件夹到Docker
- 第2步:测试Docker访问Windows共享文件夹
- 第3步:启动
- 第4步:打开浏览器
- 第5步:使用Visual Studio Code打开Angular应用文件夹
- 第6步:停止
- 第7步:清理
- 补充说明
- 代码详细分析
- 第1步:共享Windows文件夹到Docker
- 第2步:测试Docker访问Windows共享文件夹
- 第3步:启动
- Version版本
- Volume卷
- 服务node-npm-9.10.0-5.8.0
- 服务angular.cli-1.7.3
- 保存镜像
- 服务ng-new
- 服务npm-install
- 服务ng-serve
- 第4步:打开浏览器
- 第5步:使用Visual Studio Code打开Angular应用文件夹
- 第6步:停止
- 第7步:清理
开包即用,不用看代码!
使用管理员权限启动PowerShell
Windows共享文件夹需要管理员权限
进入工作文件夹
进入你的工作文件夹,例如我的工作文件夹为
Set-Location C:\Users\huzh\OneDrive\Angular
下载代码
git clone https://github.com/huzhenghui/Angular-in-Docker-by-Windows-share-folder.git
进入代码文件夹
Set-Location .\Angular-in-Docker-by-Windows-share-folder
更新子模块代码
git submodule update --init
第1步:共享Windows文件夹到Docker
.\step.1.share-windows-folder-to-docker.ps1
输出内容很多,略,结果看下面的测试。
第2步:测试Docker访问Windows共享文件夹
.\step.2.share-windows-folder-to-docker.test.ps1
如果从输出结果中看到文件夹的内容,就说明共享设置成功了
Angular-App.vscode.launch.json
LICENSE
angular.cli-1.7.3.Dockerfile
docker-compose.yml
node-npm-9.10.0-5.8.0.Dockerfile
share-windows-folder-to-docker
step.1.share-windows-folder-to-docker.ps1
step.2.share-windows-folder-to-docker.test.ps1
step.3.docker-compose.up.ps1
step.4.open.browser.ps1
step.5.open.code.ps1
step.6.docker-compose.down.ps1
step.7.clean.ps1
......
第3步:启动
.\step.3.docker-compose.up.ps1
首次启动的时间比较久,以后就快了,详见本文后面的代码详解。
第4步:打开浏览器
运行另一个PowerShell窗口,进入到代码文件夹。
.\step.4.open.browser.ps1
将自动打开浏览器访问该页面。
第5步:使用Visual Studio Code打开Angular应用文件夹
在第二个PowerShell窗口中运行。
.\step.5.open.code.ps1
脚本将
- 自动配置
Chrome调试 - 自动启动
Visual Studio Code(需要电脑上安装Visual Studio Code)
等Visual Studio Code启动后测试自动更新
- 按F5快捷键启动调试,
Visual Studio Code将自动打开Chrome浏览器(需要电脑上安装Chrome浏览器) - 观察自动打开的
Chrome浏览器是否自动访问页面 - 修改某个程序文件,例如
src/app/app.component.ts中的标题名称 - 保存
- 观察第一个
PowerShell窗口是否自动更新 - 观察
Chrome浏览器是否自动刷新
第6步:停止
在第二个PowerShell窗口中运行。
.\step.6.docker-compose.down.ps1
观察第一个PowerShell窗口是否停止服务。
第7步:清理
不再使用的时候,可以运行清理脚本
.\step.7.clean.ps1
补充说明
因为步骤较多,第一次建议从第1步到第7步逐步运行一遍,熟悉各步骤。
脚本直接调用docker、docker-machine、docker-compose等命令,
可能在不同安装方式的电脑上有所不同,如果不能使用请反馈。
第7步清理脚本不清理已经设置的共享文件夹,因此清理后再次运行的时候,
可以直接从第3步开始。当然也就不需要使用管理员权限启动PowerShell。
第3步中首次运行过程较长,很有可能受到网络影响而终止,可以重新运行。
如果重新运行失败,建议使用第7步清理后再次运行。
第6步停止后,再次运行第3步将再次启动,再次启动将自动跳过构建的环节。
第4步自动通过环境变量获取Docker主机的IP地址,然后使用浏览器访问,
如果不能正确打开请手工试试。
第5步自动通过环境变量获取Docker主机的IP地址,
然后生成Visual Studio Code的调试配置文件,本例采用简单粗暴的方式生成,
不同的Visual Studio Code版本可能略有不同,
如果不能正确打开调试请手工配置调试试试。
脚本中把node_modules都扔到了Docker中,
这样的好处是Windows上只包含程序相关代码,坏处就是code找不到这些代码了,
如果需要,可以参照后面的代码说明修改。
代码详细分析
下面详细讲解代码。
第1步:共享Windows文件夹到Docker
.\step.1.share-windows-folder-to-docker.ps1
代码如下
.\share-windows-folder-to-docker\share-windows-folder-to-docker.ps1 -volumeName Angular-in-Docker-by-Windows-share-folder -optCache none
这是一个通用的用于共享Windows文件夹到Docker的脚本,参见
https://blog.csdn.net/hu_zhenghui/article/details/79189520
该脚本以git的submodule子模块方式引用,因此需要更新子模块代码。
git submodule update --init
脚本中的Windows共享文件夹需要管理员权限,
因此运行这个脚本的PowerShell需要管理员权限。
脚本中操作Docker的部分直接调用docker、docker-machine命令,
因此需要PowerShell中能直接使用这两个命令。
第2步:测试Docker访问Windows共享文件夹
.\step.2.share-windows-folder-to-docker.test.ps1
代码如下
docker run --rm -v Angular-in-Docker-by-Windows-share-folder:/Angular-in-Docker-by-Windows-share-folder alpine ls /Angular-in-Docker-by-Windows-share-folder
docker volume inspect Angular-in-Docker-by-Windows-share-folder
这里的脚本用于测试之前共享Windows文件夹到Docker的脚本。
第一行是在Docker中访问Windows共享的文件夹。
第二行是查看Docker中Volume卷的设置。
第3步:启动
.\step.3.docker-compose.up.ps1
脚本中的代码很简单
docker-compose up
docker-compose命令将按照docker-compose.yml启动,代码如下:
version: "3.4"
services:node-npm-9.10.0-5.8.0:image: node-npm:9.10.0-5.8.0build:context: .dockerfile: node-npm-9.10.0-5.8.0.Dockerfileangular.cli-1.7.3:depends_on:- node-npm-9.10.0-5.8.0image: angular.cli:1.7.3build:context: .dockerfile: angular.cli-1.7.3.Dockerfileng-new:depends_on:- angular.cli-1.7.3image: angular.cli:1.7.3volumes:- type: volumesource: ApplicationRootVolumetarget: /ApplicationRoot- type: volumesource: AngularAppNodeModulestarget: /ApplicationRoot/Angular-App/node_modules- Docker-Compose-Startup-Order:/Startup-Ordercommand: |bash -c 'echo ng-new start;touch /Startup-Order/ng-new.start;cd /ApplicationRoot;ng new Angular-App;echo ng-new done return code = $$?;touch /Startup-Order/ng-new.done;'npm-install:depends_on:- ng-newimage: angular.cli:1.7.3volumes:- type: volumesource: ApplicationRootVolumetarget: /ApplicationRoot- type: volumesource: AngularAppNodeModulestarget: /ApplicationRoot/Angular-App/node_modules- Docker-Compose-Startup-Order:/Startup-Ordercommand: |bash -c 'echo npm-install start;touch /Startup-Order/npm-install.start;while [[ ! -f /Startup-Order/ng-new.done || /Startup-Order/ng-new.done -ot /Startup-Order/ng-new.start ]]; do sleep 1; done;echo npm-install doing;cd /ApplicationRoot/Angular-App;npm install;echo npm-install done;touch /Startup-Order/npm-install.done;'ng-serve:depends_on:- npm-installimage: angular.cli:1.7.3volumes:- type: volumesource: ApplicationRootVolumetarget: /ApplicationRoot- type: volumesource: AngularAppNodeModulestarget: /ApplicationRoot/Angular-App/node_modules- Docker-Compose-Startup-Order:/Startup-Orderports:- 80:80command: |bash -c 'echo ng-serve start;while [[ ! -f /Startup-Order/npm-install.done || /Startup-Order/npm-install.done -ot /Startup-Order/npm-install.start ]]; do sleep 1; done;echo ng-serve doing;cd /ApplicationRoot/Angular-App;ng serve --verbose --progress --host 0.0.0.0 --port 80 --poll 1;'
volumes:ApplicationRootVolume:external:name: Angular-in-Docker-by-Windows-share-folderAngularAppNodeModules:Docker-Compose-Startup-Order:
下面详细讲解docker-compose.yaml文件。
Version版本
此处使用docker-compose文件的3.4版本,
如果docker-compose不支持这么高的版本可能不能正常运行。
version: "3.4"
Volume卷
volumes:ApplicationRootVolume:external:name: Angular-in-Docker-by-Windows-share-folderAngularAppNodeModules:Docker-Compose-Startup-Order:
其中共包含三个卷。
ApplicationRootVolume为前面使用脚本共享的Windows文件夹AngularAppNodeModules为内部卷,用于node_modules文件夹,
也就是把node安装的模块都放在docker中,
在未来迁移到生产环境的时候,便于隔离项目代码和其他的模块,
缺点就是后面使用Visual Studio Code打开的时候,找不到这些模块,没有代码提示。Docker-Compose-Startup-Order为内部卷,
用于控制docker-compose中服务的启动顺序。
服务node-npm-9.10.0-5.8.0
node-npm-9.10.0-5.8.0:image: node-npm:9.10.0-5.8.0build:context: .dockerfile: node-npm-9.10.0-5.8.0.Dockerfile
这个服务的目的就是用于构建node-npm:9.10.0-5.8.0镜像,
构建文件为node-npm-9.10.0-5.8.0.Dockerfile,代码如下
FROM node:9.10.0LABEL maintainer="hu@daonao.com"RUN node --version && \npm version && \npm -g install npm@5.8.0 && \npm version
很简单,从node:9.10.0升级npm@5.8.0,
这里精确标注版本为了避免经常出现的版本冲突,如果后续遇到版本冲突,
建议按照类似的格式精确构建版本。
本服务的构建过程仅需要运行一次,再次运行不会重复构建镜像。
服务angular.cli-1.7.3
angular.cli-1.7.3:depends_on:- node-npm-9.10.0-5.8.0image: angular.cli:1.7.3build:context: .dockerfile: angular.cli-1.7.3.Dockerfile
这个服务的目的也是用于构建镜像,镜像为angular.cli:1.7.3,
构建文件为angular.cli-1.7.3.Dockerfile,代码如下
FROM node-npm:9.10.0-5.8.0LABEL maintainer="hu@daonao.com"RUN npm install -g --unsafe-perm=true @angular/cli@1.7.3 && \ng version
注意这里使用服务node-npm-9.10.0-5.8.0构建的node-npm:9.10.0-5.8.0镜像,
为了控制构建顺序,需要设置依赖关系。
depends_on:- node-npm-9.10.0-5.8.0
构建内容就是安装@angular/cli@1.7.3,然后显示版本ng version。
本服务的构建过程仅需要运行一次,再次运行不会重复构建镜像。
保存镜像
由于构建镜像不稳定,建议在构建镜像后保存镜像,因为都是开源软件,
所以可以保存在docker的公共镜像库中,在 http://hub.docker.com/ 上注册账号。
在本地登录
docker login
在 http://hub.docker.com/ 上创建镜像仓库,我创建的镜像仓库为
- huzhenghui/node-npm
- huzhenghui/angular.cli
在本地按照镜像仓库的名称给镜像打标签。
docker tag node-npm:9.10.0-5.8.0 huzhenghui/node-npm:9.10.0-5.8.0
docker tag angular.cli:1.7.3 huzhenghui/angular.cli:1.7.3
然后上传镜像。
docker push huzhenghui/node-npm:9.10.0-5.8.0
docker push huzhenghui/angular.cli:1.7.3
上传后即可在 http://hub.docker.com/ 上看到。
https://hub.docker.com/r/huzhenghui/node-npm/
https://hub.docker.com/r/huzhenghui/angular.cli/
未来使用的时候,可以拉取镜像,拉取镜像不需要登录。
docker pull huzhenghui/node-npm:9.10.0-5.8.0
docker pull huzhenghui/angular.cli:1.7.3
然后测试镜像
docker run -it --rm huzhenghui/angular.cli:1.7.3 ng -v
docker run -it --rm huzhenghui/angular.cli:1.7.3 bash
为了和docker-compose.yml中的镜像名称保持一致,给镜像打标签。
docker tag huzhenghui/node-npm:9.10.0-5.8.0 node-npm:9.10.0-5.8.0
docker tag huzhenghui/angular.cli:1.7.3 angular.cli:1.7.3
服务ng-new
ng-new:depends_on:- angular.cli-1.7.3image: angular.cli:1.7.3volumes:- type: volumesource: ApplicationRootVolumetarget: /ApplicationRoot- type: volumesource: AngularAppNodeModulestarget: /ApplicationRoot/Angular-App/node_modules- Docker-Compose-Startup-Order:/Startup-Ordercommand: |bash -c 'echo ng-new start;touch /Startup-Order/ng-new.start;cd /ApplicationRoot;ng new Angular-App;echo ng-new done return code = $$?;touch /Startup-Order/ng-new.done;'
这个服务用于新建angular项目,使用前面构建的angular.cli:1.7.3,
因此设置依赖关系。
depends_on:- angular.cli-1.7.3
挂载了三个卷,其中
ApplicationRootVolume是从Windows共享的文件夹,挂载在/ApplicationRootAngularAppNodeModules是内部卷,
挂载在/ApplicationRoot/Angular-App/node_modules。
注意挂载位置在ApplicationRootVolume挂载位置的内部,
这是docker的强大功能之一,可以灵活的控制文件写入的位置。Docker-Compose-Startup-Order是内部卷,挂载在/Startup-Order
服务的命令直接写脚本,头尾用于控制服务的运行顺序。
touch /Startup-Order/ng-new.start;
touch /Startup-Order/ng-new.done;
中间部分这是新建angular项目。
cd /ApplicationRoot;
ng new Angular-App;
仅在首次运行的时候有较长的运行时间,
再次运行的时候检测到已经创建了项目就会自动结束。
服务npm-install
npm-install:depends_on:- ng-newimage: angular.cli:1.7.3volumes:- type: volumesource: ApplicationRootVolumetarget: /ApplicationRoot- type: volumesource: AngularAppNodeModulestarget: /ApplicationRoot/Angular-App/node_modules- Docker-Compose-Startup-Order:/Startup-Ordercommand: |bash -c 'echo npm-install start;touch /Startup-Order/npm-install.start;while [[ ! -f /Startup-Order/ng-new.done || /Startup-Order/ng-new.done -ot /Startup-Order/ng-new.start ]]; do sleep 1; done;echo npm-install doing;cd /ApplicationRoot/Angular-App;npm install;echo npm-install done;touch /Startup-Order/npm-install.done;'
代码结构和服务ng-new类似,命令的头尾也是用于控制服务的运行顺序。
touch /Startup-Order/npm-install.start;
while [[ ! -f /Startup-Order/ng-new.done || /Startup-Order/ng-new.done -ot /Startup-Order/ng-new.start ]]; do sleep 1; done;
touch /Startup-Order/npm-install.done;'
其中的while循环就是检测服务ng-new是否运行结束,对照服务ng-new即可理解。
中间部分是安装node包。
cd /ApplicationRoot/Angular-App;
npm install;
仅在首次运行的时候有较长的运行时间,
再次运行的时候检测到已经安装了包就会自动结束。
服务ng-serve
ng-serve:depends_on:- npm-install
image: angular.cli:1.7.3volumes:- type: volume
source: ApplicationRootVolumetarget: /ApplicationRoot- type: volume
source: AngularAppNodeModulestarget: /ApplicationRoot/Angular-App/node_modules- Docker-Compose-Startup-Order:/Startup-Order
ports:- 80:80
command: |bash -c 'echo ng-serve start;while [[ ! -f /Startup-Order/npm-install.done || /Startup-Order/npm-install.done -ot /Startup-Order/npm-install.start ]]; do sleep 1; done;echo ng-serve doing;cd /ApplicationRoot/Angular-App;ng serve --verbose --progress --host 0.0.0.0 --port 80 --poll 1;'
代码结构和服务ng-new类似,
区别在于服务ng-serve提供web服务,因此需要打开80端口。
ports:- 80:80
命令头部的while循环就是检测服务npm-install是否运行结束,
对照服务npm-install即可理解。
while [[ ! -f /Startup-Order/npm-install.done || /Startup-Order/npm-install.done -ot /Startup-Order/npm-install.start ]]; do sleep 1; done;
然后启动web服务。
ng serve --verbose --progress --host 0.0.0.0 --port 80 --poll 1;
其中--host 0.0.0.0为绑定全部地址,默认仅绑定localhost,
在docker中运行时外部是访问不到的。
--port 80为绑定80端口,默认绑定4200端口。
--poll 1用于加快检查文件是否有更新,后面Visual Studio Code环节会详细讲解。
第4步:打开浏览器
因为第一个PowerShell窗口中正在显示ng-serve服务,
因此需要运行另一个PowerShell窗口,进入到代码文件夹。
.\step.4.open.browser.ps1
代码如下。
if ($env:DOCKER_HOST -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")
{Start-Process (-Join('http://', $Matches[0], '/'))
}
其中$env:DOCKER_HOST是docker的环境变量,使用如下代码查看。
Write-Output $env:DOCKER_HOST
输出结果类似为
tcp://192.168.1.101:2376
脚本从这个环境变量中解析出IP地址,本例中即为192.168.1.101,
然后拼接成网址,本例中即为http://192.168.1.101/,
再打开浏览器访问,Windows下默认为Edge浏览器。
打开浏览器后应能看到angular项目的初始界面,
如果看不到请按照按照前面的讲解排查。
第5步:使用Visual Studio Code打开Angular应用文件夹
继续在第二个PowerShell窗口中运行。
.\step.5.open.code.ps1
内容如下。
if ($env:DOCKER_HOST -match "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")
{if(!(Test-Path .\Angular-App\.vscode)){New-Item -ItemType "directory" .\Angular-App\.vscode\
}if(!(Test-Path .\Angular-App\.vscode\launch.json)){$launch=Get-Content -Encoding UTF8 .\Angular-App.vscode.launch.json | ConvertFrom-Json$launch.configurations[0].name=-Join("Launch Chrome and Open ", $Matches[0])$launch.configurations[0].url=-Join('http://', $Matches[0], '/')$launch | ConvertTo-Json | Out-File -Encoding UTF8 .\Angular-App\.vscode\launch.json}
}
code .\Angular-App\
脚本的第一部分是自动配置Chrome调试,和前面类似,也是先解析出IP地址。
如果没有.\Angular-App\.vscode文件夹则创建该文件夹。
如果没有.\Angular-App\.vscode\launch.json则从模板创建。创建方式简单粗暴,
直接使用默认生成的launch.json文件创建,
因此如果遇到Visual Studio Code版本升级导致不兼容,
请参照这里介绍的工作原理调试。
读取模板后,修改name名称,和url地址,然后保存到目标位置。
脚本的第二部分自动启动Visual Studio Code,当然需要电脑上安装Visual Studio Code。
等Visual Studio Code启动后可以测试自动更新。
- 按F5快捷键启动调试,
Visual Studio Code将自动打开Chrome浏览器(需要电脑上安装Chrome浏览器) - 观察自动打开的
Chrome浏览器是否自动访问页面 - 修改某个程序文件,例如
src/app/app.component.ts中的标题名称 - 保存
- 观察第一个
PowerShell窗口是否自动更新 - 观察
Chrome浏览器是否自动刷新
第6步:停止
继续在第二个PowerShell窗口中运行。
.\step.6.docker-compose.down.ps1
代码很简单。
docker-compose down
观察第一个PowerShell窗口是否停止服务。
需要注意停止服务时需要在启动服务相同的文件夹。
第7步:清理
不再使用的时候,可以运行清理脚本
.\step.7.clean.ps1
代码如下。
Remove-Item -Recurse -Force .\Angular-App\* -Confirm
Remove-Item .\Angular-App\
docker volume rm angularindockerbywindowssharefolder_AngularAppNodeModules
docker volume rm angularindockerbywindowssharefolder_Docker-Compose-Startup-Order
删除新建的angular项目,删除docker中相关的卷。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
