Add a containerfile

This commit is contained in:
Nikolai Rodionov 2024-04-04 18:15:30 +02:00
parent a94ca276ba
commit 316f5d17d5
Signed by: allanger
GPG Key ID: 0AA46A90E25592AD
8 changed files with 119 additions and 93 deletions

34
Containerfile Normal file
View 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;"]

View File

@ -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 'dart:html';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:softplayer_web/components/sign_in_form.dart'; import 'package:softplayer_web/components/sign_in_form.dart';
/// Flutter code sample for [AppBar].
class MenuPanel extends StatefulWidget implements PreferredSizeWidget { class MenuPanel extends StatefulWidget implements PreferredSizeWidget {
final TabName tab; final TabName tab;
const MenuPanel({super.key, required this.tab}) const MenuPanel({super.key, required this.tab})
: preferredSize = const Size.fromHeight(kToolbarHeight); : preferredSize = const Size.fromHeight(kToolbarHeight);
@override @override
final Size preferredSize; // default is 56.0 final Size preferredSize;
@override @override
State<StatefulWidget> createState() => _MenuPanel(); State<StatefulWidget> createState() => _MenuPanel();
} }
@ -21,6 +22,7 @@ class _MenuPanel extends State<MenuPanel> {
bool isSignedIn() { bool isSignedIn() {
return window.localStorage.containsKey("token"); return window.localStorage.containsKey("token");
} }
List<Widget> accountActions() { List<Widget> accountActions() {
if (isSignedIn()) { if (isSignedIn()) {
return [ return [
@ -37,7 +39,8 @@ class _MenuPanel extends State<MenuPanel> {
builder: (BuildContext context) => const SignInForm()); builder: (BuildContext context) => const SignInForm());
}, },
child: const Text("sign in")), 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")),
]; ];
} }
} }

View File

@ -1,14 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:softplayer_web/components/menubar.dart'; import 'package:softplayer_web/components/menubar.dart';
class PageWrapper extends StatelessWidget{ class PageWrapper extends StatelessWidget {
final Widget child; final Widget child;
final MenuPanel appBar; final MenuPanel appBar;
const PageWrapper({ const PageWrapper({super.key, required this.child, required this.appBar});
super.key,
required this.child,
required this.appBar
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -17,5 +13,4 @@ class PageWrapper extends StatelessWidget{
body: child, body: child,
); );
} }
} }

View File

@ -11,7 +11,8 @@ void main() async {
'SOFTPLAYER_BACKEND_URL', 'SOFTPLAYER_BACKEND_URL',
defaultValue: 'http://softplayer.badhouseplants.net:8080', defaultValue: 'http://softplayer.badhouseplants.net:8080',
); );
GrpcWebClientChannel grpcChannel = GrpcWebClientChannel.xhr(Uri.parse(backendURL)); GrpcWebClientChannel grpcChannel =
GrpcWebClientChannel.xhr(Uri.parse(backendURL));
runApp(MyApp(channel: grpcChannel)); runApp(MyApp(channel: grpcChannel));
} }
@ -28,10 +29,18 @@ class MyApp extends StatelessWidget {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Softplayer', title: 'Softplayer',
routes: { routes: {
'/': (context) => PageWrapper( '/': (context) => const PageWrapper(
child: HomePage(), appBar: MenuPanel(tab: TabName.home),
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( theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:softplayer_web/components/menubar.dart';
class AboutPage extends StatefulWidget { class AboutPage extends StatefulWidget {
const AboutPage({super.key}); const AboutPage({super.key});
@ -12,21 +11,18 @@ class AboutPage extends StatefulWidget {
class _AboutPage extends State<AboutPage> { class _AboutPage extends State<AboutPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Center(
appBar: const MenuPanel(tab: TabName.about), child: Column(
body: Center( mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: <Widget>[
mainAxisAlignment: MainAxisAlignment.center, const Text(
children: <Widget>[ 'You have pushed the button this many times:',
const Text( ),
'You have pushed the button this many times:', Text(
), 'test',
Text( style: Theme.of(context).textTheme.headlineMedium,
'test', ),
style: Theme.of(context).textTheme.headlineMedium, ],
),
],
),
), ),
); );
} }

View File

@ -1,15 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:grpc/grpc_web.dart';
import 'package:softplayer_web/api/third_party/chartmuseum.dart'; import 'package:softplayer_web/api/third_party/chartmuseum.dart';
import 'package:softplayer_web/components/catalog_card.dart'; import 'package:softplayer_web/components/catalog_card.dart';
import 'package:softplayer_web/components/menubar.dart';
import 'package:softplayer_web/models/catalog_entry.dart'; import 'package:softplayer_web/models/catalog_entry.dart';
class CatalogPage extends StatefulWidget { class CatalogPage extends StatefulWidget {
final GrpcWebClientChannel grpcChannel;
const CatalogPage({ const CatalogPage({
super.key, super.key,
required this.grpcChannel,
}); });
final String title = "catalog"; final String title = "catalog";
@ -40,46 +36,42 @@ class _CatalogPage extends State<CatalogPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
print(helmChart); print(helmChart);
return SelectionArea( return Container(
child: Scaffold( margin: const EdgeInsets.all(14),
appBar: const MenuPanel(tab: TabName.catalog), child: Container(
body: Container( child: Row(children: <Widget>[
margin: const EdgeInsets.all(14), const SizedBox(
child: Container( width: 200,
child: Row(children: <Widget>[ child: Card(
const SizedBox( child: Column(
width: 200, children: <Widget>[Text("Filter")],
child: Card( ))),
child: Column( Flexible(
children: <Widget>[Text("Filter")], child: Column(
))), children: <Widget>[
Flexible( const TextField(
child: Column( decoration: InputDecoration(
children: <Widget>[ icon: Icon(Icons.search),
const TextField( labelText: "Search",
decoration: InputDecoration(
icon: Icon(Icons.search),
labelText: "Search",
),
autofocus: true,
), ),
CatalogCard(data: catalog), autofocus: true,
FutureBuilder( ),
future: helmChart, CatalogCard(data: catalog),
builder: (context, snapshot) { FutureBuilder(
print(snapshot); future: helmChart,
if (snapshot.hasData) { builder: (context, snapshot) {
return Text(snapshot.data!.first.name); print(snapshot);
} else if (snapshot.hasError) { if (snapshot.hasData) {
return SelectableText('${snapshot.error}'); return Text(snapshot.data!.first.name);
} } else if (snapshot.hasError) {
return const CircularProgressIndicator(); return SelectableText('${snapshot.error}');
}), }
], return const CircularProgressIndicator();
), }),
) ],
])), ),
), )
)); ])),
);
} }
} }

View File

@ -11,15 +11,14 @@ class HomePage extends StatefulWidget {
class _HomePage extends State<HomePage> { class _HomePage extends State<HomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Center( return const Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text( Text(
'You have pushed the button this many times:', 'You have pushed the button this many times:',
), ),
], ],
) ));
);
} }
} }

View File

@ -1,5 +1,6 @@
name: softplayer_web 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 publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1 version: 1.0.0+1
@ -13,8 +14,6 @@ dependencies:
git: git:
url: https://git.badhouseplants.net/softplayer/softplayer-dart-proto.git url: https://git.badhouseplants.net/softplayer/softplayer-dart-proto.git
ref: main ref: main
cupertino_icons: ^1.0.6 cupertino_icons: ^1.0.6
grpc: ^3.2.4 grpc: ^3.2.4
http: ^1.2.1 http: ^1.2.1
@ -23,7 +22,6 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^3.0.0 flutter_lints: ^3.0.0
flutter: flutter: