Skip to content

Commit

Permalink
提供便捷的Docker部署方案 (#84)
Browse files Browse the repository at this point in the history
* 分离前后端的配置文件,便于实现docker部署

* 限制numpy版本

* 修改代码以兼容docker

* 便于Docker部署

* 添加部署说明

* 更新文档

* 更新文档
  • Loading branch information
jscslld authored Dec 27, 2023
1 parent f95e3c4 commit ff5af71
Show file tree
Hide file tree
Showing 22 changed files with 195 additions and 75 deletions.
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,39 @@ GeoView支持5大遥感影像解译任务:

## 安装说明

### 前置依赖安装
### Docker部署(推荐)

#### 运行环境安装

在执行后续步骤之前,请确保您安装了Docker和Docker compose。

#### 项目下载

上述环境安装完毕后,首先从GitHub将GeoView项目克隆到本地:

```shell
git clone --recursive https://github.com/PaddleCV-SIG/GeoView.git
```

由于目前docker部署尚未合并到主分支,需要手动切换到对应分支:

```shell
git checkout feature/docker-deploy
```

#### 项目部署

使用Docker compose编排容器并启动各容器:

```shell
docker compose up -d
```

容器启动成功后,可通过`http://127.0.0.1:3000`访问GeoView。

### 手动安装

#### 前置依赖安装

在执行后续步骤之前,请确保您安装了如下依赖库:

Expand All @@ -80,7 +112,7 @@ GeoView支持5大遥感影像解译任务:
pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
```

### 项目下载与安装
#### 项目下载与安装

上述依赖安装完毕后,首先从GitHub将GeoView项目克隆到本地:

Expand Down
14 changes: 14 additions & 0 deletions backend.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM paddlepaddle/paddle:2.4.1
RUN wget https://github.com/girder/large_image_wheels/raw/wheelhouse/GDAL-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
#COPY GDAL-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl .
RUN pip install GDAL-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
RUN rm -rf GDAL-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
RUN mkdir /app
COPY PaddleRS /app/PaddleRS
WORKDIR /app/PaddleRS
RUN pip install -r /app/PaddleRS/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN pip install -e .
COPY backend /app/backend
WORKDIR /app/backend
RUN pip install -r /app/backend/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
ENTRYPOINT ["python", "app.py"]
6 changes: 3 additions & 3 deletions backend/.flaskenv_template → backend/.flaskenv
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ FLASK_DEBUG=1
SYSTEM_NAME=Hippo

# MySql配置信息
MYSQL_HOST=127.0.0.1
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_DATABASE=paddle_rs
MYSQL_USERNAME=paddle_rs
MYSQL_PASSWORD=123456
MYSQL_USERNAME=root
MYSQL_PASSWORD=GeoView2023

# 密钥配置(记得改)
SECRET_KEY='Hippo'
12 changes: 10 additions & 2 deletions backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
instance/*
!instance/.gitignore
.webassets-cache
.flaskenv
#.flaskenv

### Flask.Python Stack ###
# Byte-compiled / optimized / DLL files
Expand Down Expand Up @@ -168,4 +168,12 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/

# End of https://www.toptal.com/developers/gitignore/api/flask
# End of https://www.toptal.com/developers/gitignore/api/flask

# DL Model

model/change_detection/
model/classification/
model/image_restoration/
model/object_detection/
model/semantic_segmentation/
6 changes: 0 additions & 6 deletions backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,4 @@ def error_handler(e):
with open('../config.yaml') as file:
config = yaml.load(file.read(), Loader=yaml.FullLoader)
debug_mode = bool(config.get("debug", False))
with open("../frontend/.env", 'w') as file:
file.write(
"VUE_APP_BACKEND_PORT = {}\nVUE_APP_BACKEND_IP = {}\nVUE_APP_BAIDU_MAP_ACCESS_KEY = {}".
format(config["port"]["backend"], config["host"]["backend"]
if config["host"]["backend"] != "0.0.0.0" else "127.0.0.1",
config["baidu_map"]["access_key"]))
app.run(host=config["host"]["backend"], port=config["port"]["backend"])
6 changes: 3 additions & 3 deletions backend/applications/interface/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def change_detection(model_path,
cv2.imwrite(
os.path.join(out_dir,
os.path.splitext(filenames[i])[0] + "_mask.png"), mask)
res[i]["mask"] = out_dir + os.path.splitext(filenames[i])[
res[i]["mask"] = generate_url + os.path.splitext(filenames[i])[
0] + "_mask.png"
res[i]["count"] = count
res[i]["fractional_variation"] = compute_variation(
Expand All @@ -135,11 +135,11 @@ def change_detection(model_path,
out_dir + "hole/",
os.path.splitext(os.path.basename(after_img))[0] + "_mask.png"),
mask)
res[i]["mask_hole"] = out_dir + "hole/" + os.path.splitext(
res[i]["mask_hole"] = generate_url + "hole/" + os.path.splitext(
os.path.basename(after_img))[0] + "_mask.png"
res[i]["count_hole"] = count
res[i]["fractional_variation_hole"] = compute_variation(
os.path.join(generate_dir + "hole/", os.path.basename(after_img)))
os.path.join(out_dir + "hole/", os.path.basename(after_img)))
data = json.dumps(res[i])
save_analysis(
type_,
Expand Down
Empty file added backend/model/.gitkeep
Empty file.
2 changes: 1 addition & 1 deletion backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Flask_SQLAlchemy>=2.5.1
marshmallow>=3.18.0
marshmallow_sqlalchemy>=0.28.1
matplotlib>=3.5.3
numpy>=1.21.3
numpy>=1.21.3,<1.22
opencv-python>=4.3.0
Pillow>=9.2.0
PyMySQL>=1.0.2
Expand Down
5 changes: 2 additions & 3 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ port:
host:
backend: 0.0.0.0
frontend: 0.0.0.0
baidu_map:
access_key: <ACCESS_KEY>
debug: false
debug: true
docker: true
47 changes: 47 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
version: "3.9"
services:
mysql:
image: mysql:5.7.44
restart: always
environment:
MYSQL_ROOT_PASSWORD: GeoView2023
volumes:
- /etc/localtime:/etc/localtime:ro
networks:
- GeoView
backend:
build:
context: .
dockerfile: backend.dockerfile
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- $PWD/config.yaml:/app/config.yaml
- $PWD/backend/.flaskenv:/app/backend/.flaskenv
- $PWD/backend/model:/app/backend/model
depends_on:
- mysql
links:
- mysql
networks:
- GeoView
frontend:
build:
context: .
dockerfile: frontend.dockerfile
restart: always
ports:
- "3000:3000"
volumes:
- /etc/localtime:/etc/localtime:ro
- $PWD/config.yaml:/app/config.yaml
- $PWD/frontend/.env:/app/frontend/.env
depends_on:
- backend
networks:
- GeoView
networks:
GeoView:
ipam:
config:
- subnet: 172.19.0.0/24
9 changes: 4 additions & 5 deletions docs/dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ GeoView基于PaddleRS导出的预测模型(静态图)进行图像解译。

### 修改 Web 后端配置文件

首先切换到`backend/`目录。`.flaskenv_template`文件重命名为`.flaskenv``.flaskenv`中,修改MySQL配置信息,各配置项含义如下:
首先切换到`backend/`目录。在`.flaskenv`中,修改MySQL配置信息,各配置项含义如下:

```plain
# MySQL配置信息
Expand All @@ -75,11 +75,10 @@ host:
### 百度地图 Access Key 设置
在项目根目录下的`config.yaml`文件中将`<ACCESS_KEY>`替换为百度地图的Access Key。百度地图的Access Key可在[百度地图开放平台](http://lbsyun.baidu.com/apiconsole/key?application=key)申请。
在frontend目录下的`.env`文件中将`<ACCESS_KEY>`替换为百度地图的Access Key。百度地图的Access Key可在[百度地图开放平台](http://lbsyun.baidu.com/apiconsole/key?application=key)申请。

``` yaml
baidu_map:
access_key: <ACCESS_KEY>
``` ini
VUE_APP_BAIDU_MAP_ACCESS_KEY = <ACCESS_KEY>
```

## 3 Web 前后端启动
Expand Down
6 changes: 6 additions & 0 deletions frontend.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM node:20.10.0-alpine
RUN mkdir /app
COPY frontend /app/frontend
WORKDIR /app/frontend
RUN npm install
ENTRYPOINT ["npm", "run", "serve"]
2 changes: 0 additions & 2 deletions frontend/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
VUE_APP_BACKEND_PORT = 5008
VUE_APP_BACKEND_IP = 127.0.0.1
VUE_APP_BAIDU_MAP_ACCESS_KEY = <ACCESS_KEY>
8 changes: 6 additions & 2 deletions frontend/src/components/ImgShow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@

<script>
import { downloadimgWithWords } from "@/utils/download.js";
import global from "@/global.vue";
export default {
name: "Imgshow",
props: {
Expand All @@ -80,7 +80,11 @@ export default {
data() {
return {
fit: "fill",
childImgArr:[]
childImgArr:[],
global: {
BASEURL: global.BASEURL,
BASE_IMAGE_URL:global.BASE_IMAGE_URL
},
};
},
mounted() {
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/global.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script>
const BASEURL = "http://"+process.env.VUE_APP_BACKEND_IP+":"+process.env.VUE_APP_BACKEND_PORT+"/"
const BASEURL = "/"
const BASE_IMAGE_URL = window.location.protocol+"//"+window.location.host+BASEURL
export default {
BASEURL,
BASE_IMAGE_URL
};
</script>

4 changes: 2 additions & 2 deletions frontend/src/utils/getUploadImg.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {showFullScreenLoading} from "@/utils/loading";
function getUploadImg(type) {
historyGetPage(1, 20, type).then((res) => {
this.imgArr = res.data.data.forEach((item)=>{
item['before_img'] = global.BASEURL+item.before_img
item['after_img'] = global.BASEURL+item.after_img
item['before_img'] = global.BASE_IMAGE_URL+item.before_img
item['after_img'] = global.BASE_IMAGE_URL+item.after_img
})
this.imgArr = res.data.data
this.isUpload = this.imgArr.length !== 0;
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/utils/preHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function selectSharpen(type) {
}
createSrc(formData).then((res) => {
this.uploadSrc.list = res.data.data.map((item) => {
return global.BASEURL+item.src;
return global.BASE_IMAGE_URL+item.src;
});
this.before = this.uploadSrc.list.splice(0,3)

Expand All @@ -40,7 +40,7 @@ function selectSharpen(type) {
prePhotoHandle(this.prePhoto).then((res)=>{

this.sharpenImg = res.data.data.map((item)=>{
return global.BASEURL + item
return global.BASE_IMAGE_URL + item
})
}).catch(()=>{})
}).catch((rej)=>{})
Expand Down Expand Up @@ -75,7 +75,7 @@ function selectSharpen(type) {
}
createSrc(formData).then((res) => {
this.uploadSrc.list = res.data.data.map((item) => {
return global.BASEURL+item.src;
return global.BASE_IMAGE_URL+item.src;
});
this.before = this.uploadSrc.list.splice(0,3)

Expand All @@ -85,7 +85,7 @@ function selectSharpen(type) {
prePhotoHandle(this.prePhoto).then((res)=>{

this.claheImg = res.data.data.map((item)=>{
return global.BASEURL + item
return global.BASE_IMAGE_URL + item
})
}).catch((rej)=>{})
}).catch((rej)=>{})
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/utils/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ import global from '@/global'
function previewOnePic(pic) {
this.flag = 1
this.fbflag = 1
this.previewPic1 = global.BASEURL + pic
this.previewPic1 = global.BASE_IMAGE_URL + pic
this.preVisible = true;
}
function previewTwoPic(pic1, pic2) {
this.flag = 2
this.fbflag = 2
this.previewPic1 = global.BASEURL + pic1
this.previewPic2 = global.BASEURL + pic2
this.previewPic1 = global.BASE_IMAGE_URL + pic1
this.previewPic2 = global.BASE_IMAGE_URL + pic2
this.preVisible = true
}
function previewThreePic(pic1, pic2, pic3) {
this.flag = 3
this.fbflag = 3
this.previewPic1 = global.BASEURL + pic1
this.previewPic2 = global.BASEURL + pic2
this.previewPic3 = global.BASEURL + pic3
this.previewPic1 = global.BASE_IMAGE_URL + pic1
this.previewPic2 = global.BASE_IMAGE_URL + pic2
this.previewPic3 = global.BASE_IMAGE_URL + pic3
this.preVisible = true
}

Expand Down
Loading

0 comments on commit ff5af71

Please sign in to comment.