Add a containerfile
This commit is contained in:
		
							
								
								
									
										34
									
								
								Containerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Containerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
# Environemnt to install flutter and build web
 | 
			
		||||
FROM debian:latest AS build-env
 | 
			
		||||
 | 
			
		||||
# install all needed stuff
 | 
			
		||||
RUN apt-get update
 | 
			
		||||
RUN apt-get install -y curl tar xz-utils git
 | 
			
		||||
 | 
			
		||||
# define variables
 | 
			
		||||
ARG FLUTTER_SDK=/usr/local/flutter
 | 
			
		||||
RUN mkdir -p ${FLUTTER_SDK}
 | 
			
		||||
ARG FLUTTER_VERSION=3.19.5
 | 
			
		||||
ARG APP=/app/
 | 
			
		||||
 | 
			
		||||
RUN curl -l -o /tmp/flutter.tar.xz https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz
 | 
			
		||||
RUN tar -xf /tmp/flutter.tar.xz -C /usr/local
 | 
			
		||||
 | 
			
		||||
ENV PATH="$FLUTTER_SDK/bin:$FLUTTER_SDK/bin/cache/dart-sdk/bin:${PATH}"
 | 
			
		||||
 | 
			
		||||
RUN mkdir $APP
 | 
			
		||||
COPY . $APP
 | 
			
		||||
WORKDIR $APP
 | 
			
		||||
RUN flutter build web
 | 
			
		||||
 | 
			
		||||
# once heare the app will be compiled and ready to deploy
 | 
			
		||||
 | 
			
		||||
# use nginx to deploy
 | 
			
		||||
FROM nginx
 | 
			
		||||
 | 
			
		||||
# copy the info of the builded web app to nginx
 | 
			
		||||
COPY --from=build-env /app/build/web /usr/share/nginx/html
 | 
			
		||||
 | 
			
		||||
# Expose and run nginx
 | 
			
		||||
EXPOSE 80
 | 
			
		||||
CMD ["nginx", "-g", "daemon off;"]
 | 
			
		||||
@@ -1,16 +1,17 @@
 | 
			
		||||
// This project is not supposed to be cross-platform, 
 | 
			
		||||
// so we don't care about this warning
 | 
			
		||||
// ignore: avoid_web_libraries_in_flutter
 | 
			
		||||
import 'dart:html';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:softplayer_web/components/sign_in_form.dart';
 | 
			
		||||
 | 
			
		||||
/// Flutter code sample for [AppBar].
 | 
			
		||||
 | 
			
		||||
class MenuPanel extends StatefulWidget implements PreferredSizeWidget {
 | 
			
		||||
  final TabName tab;
 | 
			
		||||
  const MenuPanel({super.key, required this.tab})
 | 
			
		||||
      : preferredSize = const Size.fromHeight(kToolbarHeight);
 | 
			
		||||
  @override
 | 
			
		||||
  final Size preferredSize; // default is 56.0
 | 
			
		||||
  final Size preferredSize;
 | 
			
		||||
  @override
 | 
			
		||||
  State<StatefulWidget> createState() => _MenuPanel();
 | 
			
		||||
}
 | 
			
		||||
@@ -21,6 +22,7 @@ class _MenuPanel extends State<MenuPanel> {
 | 
			
		||||
  bool isSignedIn() {
 | 
			
		||||
    return window.localStorage.containsKey("token");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  List<Widget> accountActions() {
 | 
			
		||||
    if (isSignedIn()) {
 | 
			
		||||
      return [
 | 
			
		||||
@@ -37,7 +39,8 @@ class _MenuPanel extends State<MenuPanel> {
 | 
			
		||||
                  builder: (BuildContext context) => const SignInForm());
 | 
			
		||||
            },
 | 
			
		||||
            child: const Text("sign in")),
 | 
			
		||||
        TextButton(onPressed: () => print("sign up"), child: const Text("sign up")),
 | 
			
		||||
        TextButton(
 | 
			
		||||
            onPressed: () => print("sign up"), child: const Text("sign up")),
 | 
			
		||||
      ];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,10 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:softplayer_web/components/menubar.dart';
 | 
			
		||||
 | 
			
		||||
class PageWrapper extends StatelessWidget{
 | 
			
		||||
class PageWrapper extends StatelessWidget {
 | 
			
		||||
  final Widget child;
 | 
			
		||||
  final MenuPanel appBar;
 | 
			
		||||
  const PageWrapper({
 | 
			
		||||
    super.key,  
 | 
			
		||||
    required this.child,
 | 
			
		||||
    required this.appBar
 | 
			
		||||
  });
 | 
			
		||||
  const PageWrapper({super.key, required this.child, required this.appBar});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
@@ -17,5 +13,4 @@ class PageWrapper extends StatelessWidget{
 | 
			
		||||
      body: child,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,8 @@ void main() async {
 | 
			
		||||
    'SOFTPLAYER_BACKEND_URL',
 | 
			
		||||
    defaultValue: 'http://softplayer.badhouseplants.net:8080',
 | 
			
		||||
  );
 | 
			
		||||
  GrpcWebClientChannel grpcChannel = GrpcWebClientChannel.xhr(Uri.parse(backendURL));
 | 
			
		||||
  GrpcWebClientChannel grpcChannel =
 | 
			
		||||
      GrpcWebClientChannel.xhr(Uri.parse(backendURL));
 | 
			
		||||
 | 
			
		||||
  runApp(MyApp(channel: grpcChannel));
 | 
			
		||||
}
 | 
			
		||||
@@ -28,10 +29,18 @@ class MyApp extends StatelessWidget {
 | 
			
		||||
      debugShowCheckedModeBanner: false,
 | 
			
		||||
      title: 'Softplayer',
 | 
			
		||||
      routes: {
 | 
			
		||||
        '/': (context) => PageWrapper(
 | 
			
		||||
          child: HomePage(), 
 | 
			
		||||
          appBar: MenuPanel(tab: TabName.home),
 | 
			
		||||
          ),
 | 
			
		||||
        '/': (context) => const PageWrapper(
 | 
			
		||||
              appBar: MenuPanel(tab: TabName.home),
 | 
			
		||||
              child: HomePage(),
 | 
			
		||||
            ),
 | 
			
		||||
        '/catalog': (context) => const PageWrapper(
 | 
			
		||||
              appBar: MenuPanel(tab: TabName.catalog),
 | 
			
		||||
              child: CatalogPage(),
 | 
			
		||||
            ),
 | 
			
		||||
        '/about': (context) => const PageWrapper(
 | 
			
		||||
              appBar: MenuPanel(tab: TabName.about),
 | 
			
		||||
              child: AboutPage(),
 | 
			
		||||
            )
 | 
			
		||||
      },
 | 
			
		||||
      theme: ThemeData(
 | 
			
		||||
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:softplayer_web/components/menubar.dart';
 | 
			
		||||
 | 
			
		||||
class AboutPage extends StatefulWidget {
 | 
			
		||||
  const AboutPage({super.key});
 | 
			
		||||
@@ -12,21 +11,18 @@ class AboutPage extends StatefulWidget {
 | 
			
		||||
class _AboutPage extends State<AboutPage> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: const MenuPanel(tab: TabName.about),
 | 
			
		||||
      body: Center(
 | 
			
		||||
        child: Column(
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            const Text(
 | 
			
		||||
              'You have pushed the button this many times:',
 | 
			
		||||
            ),
 | 
			
		||||
            Text(
 | 
			
		||||
              'test',
 | 
			
		||||
              style: Theme.of(context).textTheme.headlineMedium,
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: Column(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
        children: <Widget>[
 | 
			
		||||
          const Text(
 | 
			
		||||
            'You have pushed the button this many times:',
 | 
			
		||||
          ),
 | 
			
		||||
          Text(
 | 
			
		||||
            'test',
 | 
			
		||||
            style: Theme.of(context).textTheme.headlineMedium,
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,11 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:grpc/grpc_web.dart';
 | 
			
		||||
import 'package:softplayer_web/api/third_party/chartmuseum.dart';
 | 
			
		||||
import 'package:softplayer_web/components/catalog_card.dart';
 | 
			
		||||
import 'package:softplayer_web/components/menubar.dart';
 | 
			
		||||
import 'package:softplayer_web/models/catalog_entry.dart';
 | 
			
		||||
 | 
			
		||||
class CatalogPage extends StatefulWidget {
 | 
			
		||||
  final GrpcWebClientChannel grpcChannel;
 | 
			
		||||
  const CatalogPage({
 | 
			
		||||
    super.key,
 | 
			
		||||
    required this.grpcChannel,
 | 
			
		||||
  });
 | 
			
		||||
  final String title = "catalog";
 | 
			
		||||
 | 
			
		||||
@@ -40,46 +36,42 @@ class _CatalogPage extends State<CatalogPage> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    print(helmChart);
 | 
			
		||||
    return SelectionArea(
 | 
			
		||||
        child: Scaffold(
 | 
			
		||||
      appBar: const MenuPanel(tab: TabName.catalog),
 | 
			
		||||
      body: Container(
 | 
			
		||||
        margin: const EdgeInsets.all(14),
 | 
			
		||||
        child: Container(
 | 
			
		||||
            child: Row(children: <Widget>[
 | 
			
		||||
          const SizedBox(
 | 
			
		||||
              width: 200,
 | 
			
		||||
              child: Card(
 | 
			
		||||
                  child: Column(
 | 
			
		||||
                children: <Widget>[Text("Filter")],
 | 
			
		||||
              ))),
 | 
			
		||||
          Flexible(
 | 
			
		||||
            child: Column(
 | 
			
		||||
              children: <Widget>[
 | 
			
		||||
                const TextField(
 | 
			
		||||
                  decoration: InputDecoration(
 | 
			
		||||
                    icon: Icon(Icons.search),
 | 
			
		||||
                    labelText: "Search",
 | 
			
		||||
                  ),
 | 
			
		||||
                  autofocus: true,
 | 
			
		||||
    return Container(
 | 
			
		||||
      margin: const EdgeInsets.all(14),
 | 
			
		||||
      child: Container(
 | 
			
		||||
          child: Row(children: <Widget>[
 | 
			
		||||
        const SizedBox(
 | 
			
		||||
            width: 200,
 | 
			
		||||
            child: Card(
 | 
			
		||||
                child: Column(
 | 
			
		||||
              children: <Widget>[Text("Filter")],
 | 
			
		||||
            ))),
 | 
			
		||||
        Flexible(
 | 
			
		||||
          child: Column(
 | 
			
		||||
            children: <Widget>[
 | 
			
		||||
              const TextField(
 | 
			
		||||
                decoration: InputDecoration(
 | 
			
		||||
                  icon: Icon(Icons.search),
 | 
			
		||||
                  labelText: "Search",
 | 
			
		||||
                ),
 | 
			
		||||
                CatalogCard(data: catalog),
 | 
			
		||||
                FutureBuilder(
 | 
			
		||||
                    future: helmChart,
 | 
			
		||||
                    builder: (context, snapshot) {
 | 
			
		||||
                      print(snapshot);
 | 
			
		||||
                      if (snapshot.hasData) {
 | 
			
		||||
                        return Text(snapshot.data!.first.name);
 | 
			
		||||
                      } else if (snapshot.hasError) {
 | 
			
		||||
                        return SelectableText('${snapshot.error}');
 | 
			
		||||
                      }
 | 
			
		||||
                      return const CircularProgressIndicator();
 | 
			
		||||
                    }),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          )
 | 
			
		||||
        ])),
 | 
			
		||||
      ),
 | 
			
		||||
    ));
 | 
			
		||||
                autofocus: true,
 | 
			
		||||
              ),
 | 
			
		||||
              CatalogCard(data: catalog),
 | 
			
		||||
              FutureBuilder(
 | 
			
		||||
                  future: helmChart,
 | 
			
		||||
                  builder: (context, snapshot) {
 | 
			
		||||
                    print(snapshot);
 | 
			
		||||
                    if (snapshot.hasData) {
 | 
			
		||||
                      return Text(snapshot.data!.first.name);
 | 
			
		||||
                    } else if (snapshot.hasError) {
 | 
			
		||||
                      return SelectableText('${snapshot.error}');
 | 
			
		||||
                    }
 | 
			
		||||
                    return const CircularProgressIndicator();
 | 
			
		||||
                  }),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        )
 | 
			
		||||
      ])),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,15 +11,14 @@ class HomePage extends StatefulWidget {
 | 
			
		||||
class _HomePage extends State<HomePage> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
      return const Center(
 | 
			
		||||
    return const Center(
 | 
			
		||||
        child: Column(
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
          children: <Widget>[
 | 
			
		||||
            Text(
 | 
			
		||||
              'You have pushed the button this many times:',
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        )
 | 
			
		||||
    );
 | 
			
		||||
      mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
      children: <Widget>[
 | 
			
		||||
        Text(
 | 
			
		||||
          'You have pushed the button this many times:',
 | 
			
		||||
        ),
 | 
			
		||||
      ],
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
name: softplayer_web
 | 
			
		||||
description: "A new Flutter project."
 | 
			
		||||
description: | 
 | 
			
		||||
  An web interface for managing softplayer applications and environments
 | 
			
		||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 | 
			
		||||
version: 1.0.0+1
 | 
			
		||||
 | 
			
		||||
@@ -13,8 +14,6 @@ dependencies:
 | 
			
		||||
    git:
 | 
			
		||||
      url: https://git.badhouseplants.net/softplayer/softplayer-dart-proto.git
 | 
			
		||||
      ref: main
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  cupertino_icons: ^1.0.6
 | 
			
		||||
  grpc: ^3.2.4
 | 
			
		||||
  http: ^1.2.1
 | 
			
		||||
@@ -23,7 +22,6 @@ dependencies:
 | 
			
		||||
dev_dependencies:
 | 
			
		||||
  flutter_test:
 | 
			
		||||
    sdk: flutter
 | 
			
		||||
 | 
			
		||||
  flutter_lints: ^3.0.0
 | 
			
		||||
 | 
			
		||||
flutter:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user