Docker Web 上用于 Flutter 的 Dart 服务器

Dart Server for Flutter on Web in Docker

我正在尝试构建一个可以为 flutter web 应用程序提供服务的 dart 服务器。我尝试了几种不同的方法,构建 from scratch, using shelf (and shelf_static),最后是 GetX,但我无法将它们放入 docker 容器中 运行。例如,我目前有一个简单的结构:

-myApp/
  -web/
  -Dockerfile
  -pubspec.yaml
  -server.dart

我使用了基本的 Flutter 演示应用程序(带有浮动按钮和计数器),添加了 Web 支持,然后 $ flutter build web,并使用 build/web 文件夹并将其复制到此处作为 Web。 Pubspec 仅包含 get_server 和 build_runner,server.dart 文件仅:

import 'package:get_server/get_server.dart';
void main() => runApp(GetServer(home: FolderWidget('web')));

然后我的 Dockerfile 看起来像这样(基于 this github repo):

################
FROM google/dart:2.10

RUN apt -y update && apt -y upgrade

WORKDIR /app
COPY pubspec.yaml /app/pubspec.yaml
RUN dart pub get
COPY . .
RUN dart pub get --offline

RUN dart pub run build_runner build --delete-conflicting-outputs
RUN dart compile exe /app/server.dart -o /app/server

########################
FROM subfuzion/dart:slim
COPY --from=0 /app /app
EXPOSE 8080
ENTRYPOINT ["/app/server"]

如果我从命令行 运行 服务器:

$ dart server.dart

它 运行 非常完美。但是如果我构建 docker 和 运行 它:

$ docker build -t myApp .
$ docker run -d -p 8080:8080 myapp

就是说找不到页面。有谁知道我做错了什么?或者对如何使用 Dart 服务器(不必是 GetX)托管 Flutter Web 应用程序有建议。

我要更新它,因为这是我唯一的 post 获得任何流量。第一个答案是我是一个白痴,试图从我计算机上与 docker 容器中相同的目录中为网站提供服务(惊奇!那没有用)。其次,我创建了一些自动化脚本来加速这个过程,并允许它很容易 pushed to Google's CloudRun 以防有人感兴趣。我还将更改为显示 Shelf 服务器,因为现在这似乎是默认设置。

我的 Flutter 项目的完整目录设置是这样的:

directory_to_flutter_project/
simple_server/
scripts/

simple_server 中,我有一个包含 2 个文件夹的 dart 项目,binwebbin 仅包含 server.dart:

import 'package:functions_framework/serve.dart';
import 'package:shelf_static/shelf_static.dart';

Future<void> main(List<String> args) async {
  await serve(args, _nameToFunctionTarget);
}

FunctionTarget? _nameToFunctionTarget(String name) {
  switch (name) {
    case 'function':
      return FunctionTarget.http(
        createStaticHandler('app/web', defaultDocument: 'index.html'),
      );
    default:
      return null;
  }
}

web 目录是我们构建 Flutter PWA 的地方。如果您需要任何类型的授权,您可能希望在其中包含一个 redirect.html 文件。

然后,当你准备好后,你可以像这样创建一个 bash 脚本(我把它放在 scripts 目录中):

#!/bin/bash

projectId="gcp-project-id"
projectName="gcp-project-name"
version="3"

# only needed the first time
gcloud config set project $projectId
gcloud auth login

# change to primary app directory & build flutter web & go back to main level

cd directory_to_flutter_project && flutter build web && cd ..

# if you're having issues with rendering, which we were, you can try the following instead
cd directory_to_flutter_project && flutter build web --web-renderer canvaskit --release && cd ..

# clear web directory from server
rm simple_server/web -r

# copy the built web folder to the server directory
cp directory_to_flutter_project/build/web simple_server/web -r

# change to the server directory
cd simple_server &&

# Create docker container
docker build -t $projectName .

#
# The rest is for pushing to GCP
#

#push it to GCP Cloud Repository
docker build -t gcr.io/$projectId/$projectName:v$version .
docker push gcr.io/$projectId/$projectName:v$version

# return back to root directory
cd ..

# deploy on google cloud
gcloud run deploy $projectName --image gcr.io/$projectId/$projectName:v$version