Flutter随笔(二)——使用Flutter Web + Docker + Nginx打造一个简单的Web项目
欢迎前往个人博客阅读
前言
Flutter作为一个跨平台UI框架,功能十分强大,仅用一套代码便能编译出Android、iOS、Web、windows、macOS、Windows、Linux等平台上的应用,各平台应用体验高度一致,目测前途一片光明,形势一片大好。
Flutter支持Android和iOS已经很长一段时间了,相信很多同学对使用Flutter开发Android和iOS应用都已经驾轻就熟了,今天我们就来体验一把Flutter Web。目标是创建一个简单的Flutter Web项目,然后打包部署到服务器,通过浏览器进行访问。
1.创建Flutter工程
首先我们需要创建一个Flutter工程。我使用了Android Studio来创建工程,如下:
上图中需要注意的地方是Platforms,在Platforms栏中我们要选择程序运行的平台,因为我们最终要打包出Web项目,所以我们务必勾选Web选项。
工程创建好之后的目录结果如下:
除了我们熟悉的Android和iOS目录外,还多了Web目录,Web目录下存放了Web项目所需要的全部文件。
2.编写flutter代码
接下来,我们编写flutter代码,代码非常简单,仅实现了在主页点击按钮跳转到对应子页面的功能。
主页 main.dart 的代码如下:
import 'package:flutter/material.dart'; import 'ChildPage.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'xy_flutter', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'xy_flutter'), ); } } class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; final List<HomeMenu> menus = [ HomeMenu('page1', '页面1'), HomeMenu('page2', '页面2'), HomeMenu('page3', '页面3'), ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: ListView.builder( itemCount: menus.length, itemBuilder: (context, index) { return ListTile( title: Text(menus[index].title), onTap: () { HomeMenu homeMenu = menus[index]; String id = homeMenu.id; String title = homeMenu.title; if (id == 'page1') { Navigator.push( context, MaterialPageRoute( builder: (context) => ChildPage(title: title))); } else if (id == 'page2') { Navigator.push( context, MaterialPageRoute( builder: (context) => ChildPage(title: title))); } else if (id == 'page3') { Navigator.push( context, MaterialPageRoute( builder: (context) => ChildPage(title: title))); } }, ); }), ); } } class HomeMenu { String id; String title; HomeMenu(this.id, this.title); }
子页面 child_page.dart 的代码如下:
import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; class ChildPage extends StatefulWidget { final String title; const ChildPage({Key key, this.title}) : super(key: key); @override State<StatefulWidget> createState() { return _ChildPageState(); } } class _ChildPageState extends State<ChildPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: Text(widget.title)); } }
3.打包Web工程
在工程根目录下执行以下命令进行编译打包:
flutter build web
命令执行成功之后,编译生成的文件被输出到了 工程根目录/build/web/ 目录下,如下:
4.上传Web工程到服务器
通过文件传输工具(例如FileZilla等)将编译后生成的所有文件上传到服务器。我上传到服务器的路径为 home/ubuntu/docker/xy_flutter/web/ , home/ubuntu/docker/xy_flutter/web/ 目录和工程编译出来的web目录对应,即 home/ubuntu/docker/xy_flutter/web/ 目录下的文件和工程编译出来的web目录下的文件完全一致。
5.创建Nginx Docker容器
接下来,我们在服务器中创建一个Nginx的Docker容器,用来运行Web项目。
如果服务器还没有安装Docker,需要先安装Docker,关于如何安装Docker可以参考我之前整理的资料 Docker游记1——安装Docker
如果已经安装好了Docker,但还没有拉取Nginx的Docker镜像,需要先拉取一下镜像,可以通过如下命令拉取最新的Nginx Docker镜像:
docker pull nginx:latest
镜像拉取下来之后,可以通过如下命令查看当前所有已拉取下来的镜像:
docker images
得到的结果如下:
REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 87a94228f133 2 days ago 133MB
我们可以看到已经有Nginx的镜像了。
接着我们利用拉取下来的镜像创建一个容器,执行以下命令:
docker run --name xy_flutter -p 8088:80 -d nginx
这行命令表示使用Nginx镜像创建并持续运行一个名为xy_flutter的容器,并将服务器的8088端口映射到容器的80端口。创建好之后,可以通过以下命令查看创建好的容器:
docker ps
结果如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0c6f697a8e0c nginx "/docker-entrypoint.…" 5 seconds ago Up 3 seconds 0.0.0.0:8088->80/tcp, :::8088->80/tcp xy_flutter
容器创建好之后,我们就可以通过浏览器访问容器对应的Nginx服务了,因为我的服务器地址IP地址是 http://49.234.163.66/ ,容器映射的服务器端口是8088,所以访问地址是 http://49.234.163.66:8088/ ,访问后跳转的页面如下:
已经看到Nginx在欢迎我们了!
6.部署Web工程
我们通过浏览器访问Nginx服务时,跳转的页面其实是容器中的 /usr/share/nginx/html/index.html 文件,我们可以进入容器查看。
执行以下命令进入容器:
docker exec -it {容器ID} /bin/bash
进入容器后,我们通过`cd`命名访问 /usr/share/nginx/html/ 目录,目录中的文件如下:
要部署Web工程,把Web工程中的所有文件复制到容器的 /usr/share/nginx/html/ 目录就可以了,Web工程中的index.html会覆盖 /usr/share/nginx/html/index.html 文件。我们通过如下命令把服务器本地的文件复制到容器中:
docker cp {服务器中Web工程目录下的所有子文件} {容器ID}:/usr/share/nginx/html
我的服务器中Web工程目录下的所有子文件是 home/ubuntu/docker/xy_flutter/web/. ,容器ID是 0c6f697a8e0c ,所以我执行的命令是:
docker cp home/ubuntu/docker/xy_flutter/web/. 0c6f697a8e0c:/usr/share/nginx/html
7.部署完成
在上述步骤中,我们已经将Web工程拷贝到容器中的指定位置了,到这里部署工作其实也就完成了,我们再次在浏览器中输入 http://49.234.163.66:8088/ 访问,可以看到已经可以打开我们的Web工程了,如下:
至此,我们就完成了从创建Flutter Web项目到部署至服务器的整个流程!