Add web service worker loader
Build and deploy Flutter Web / build (push) Failing after 4m19s

This commit is contained in:
Ruslan Bakiev
2026-06-21 09:34:40 +07:00
parent c374797484
commit fca8004e8d
6 changed files with 185 additions and 4 deletions
+1
View File
@@ -34,6 +34,7 @@ jobs:
--build-arg MAPBOX_ACCESS_TOKEN="${{ secrets.MAPBOX_ACCESS_TOKEN }}" \
--build-arg MAPBOX_STYLE="mapbox/streets-v12" \
--build-arg TELEGRAM_BOT_USERNAME="carfteebot" \
--build-arg BUILD_VERSION="${GITHUB_SHA}" \
.; then
published_images="$(docker image ls --format '{{.Repository}}:{{.Tag}}' | awk -v sha="$IMAGE_SHA" -v latest="$IMAGE_LATEST" '$0 == sha || $0 == latest')"
if [ -n "$published_images" ]; then
+10 -2
View File
@@ -3,13 +3,21 @@ WORKDIR /app
ARG MAPBOX_ACCESS_TOKEN=""
ARG MAPBOX_STYLE="mapbox/streets-v12"
ARG TELEGRAM_BOT_USERNAME="carfteebot"
ARG BUILD_VERSION="local"
COPY pubspec.* ./
RUN flutter pub get
COPY . .
RUN flutter build web --release \
RUN rm -rf build/web && \
flutter build web --release --base-href=/ -o build/web \
--dart-define=MAPBOX_ACCESS_TOKEN="$MAPBOX_ACCESS_TOKEN" \
--dart-define=MAPBOX_STYLE="$MAPBOX_STYLE" \
--dart-define=TELEGRAM_BOT_USERNAME="$TELEGRAM_BOT_USERNAME"
--dart-define=TELEGRAM_BOT_USERNAME="$TELEGRAM_BOT_USERNAME" && \
cp web/index.prod.html build/web/index.html && \
rm -f build/web/index.prod.html && \
dart run sw:generate \
--input=build/web \
--prefix=mapflow \
--version="$BUILD_VERSION"
FROM nginx:1.27-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
+70 -2
View File
@@ -1,11 +1,52 @@
server {
listen 80;
server_name _;
gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_vary on;
gzip_types
application/javascript
application/json
application/manifest+json
application/wasm
image/svg+xml
text/css
text/plain;
etag on;
root /usr/share/nginx/html;
index index.html;
client_max_body_size 25m;
location / {
try_files $uri $uri/ /index.html;
location = /index.html {
add_header Cache-Control "no-cache" always;
add_header Pragma "no-cache" always;
add_header Expires "0" always;
try_files /index.html =404;
}
location ~* ^/(bootstrap\.js|sw\.js)$ {
add_header Cache-Control "no-cache" always;
add_header Pragma "no-cache" always;
add_header Expires "0" always;
try_files $uri =404;
}
location ~* ^/(manifest\.json|version\.json)$ {
add_header Cache-Control "no-cache" always;
add_header Pragma "no-cache" always;
add_header Expires "0" always;
try_files $uri =404;
}
location ~* ^/(flutter_service_worker\.js|flutter_bootstrap\.js|flutter\.js)$ {
add_header Cache-Control "no-cache" always;
add_header Pragma "no-cache" always;
add_header Expires "0" always;
return 410;
}
location = /graphql {
@@ -25,4 +66,31 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location ~* ^/assets/.*\.(otf|ttf|woff|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
add_header Access-Control-Allow-Origin "*" always;
types {
font/otf otf;
font/ttf ttf;
font/woff woff;
font/woff2 woff2;
}
try_files $uri =404;
}
location ~* ^/(assets|canvaskit|icons)/ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
try_files $uri =404;
}
location ~* \.(js|mjs|wasm|json|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
try_files $uri =404;
}
location / {
add_header Cache-Control "no-cache" always;
try_files $uri $uri/ /index.html;
}
}
+8
View File
@@ -1037,6 +1037,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.1"
sw:
dependency: "direct dev"
description:
name: sw
sha256: c3c7cb2e728ce068d79e61b7c2e8944de67567acc06a3594ae303f3884089ac4
url: "https://pub.dev"
source: hosted
version: "0.1.5"
term_glyph:
dependency: transitive
description:
+1
View File
@@ -62,6 +62,7 @@ dev_dependencies:
flutter_lints: ^6.0.0
ferry_generator: ^0.12.0+5
build_runner: ^2.15.0
sw: ^0.1.5
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
+95
View File
@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="MapFlow">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#0d1b2a">
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="MapFlow">
<link rel="apple-touch-icon" href="icons/Icon-192.png?v={{sw_version}}">
<link rel="icon" type="image/png" href="favicon.png?v={{sw_version}}"/>
<title>MapFlow</title>
<link rel="manifest" href="manifest.json">
<style>
#sw-loading .sw-title,
#sw-loading .sw-status,
#sw-loading .sw-percentage {
display: none !important;
}
#sw-loading {
background: #0d1b2a !important;
gap: 0 !important;
}
</style>
</head>
<body>
<script>
if ('serviceWorker' in navigator) {
var refreshing = false;
navigator.serviceWorker.addEventListener('controllerchange', function () {
if (refreshing) {
return;
}
refreshing = true;
window.location.reload();
});
window.addEventListener('sw-update-available', function () {
navigator.serviceWorker.getRegistration().then(function (registration) {
if (registration && registration.waiting) {
registration.waiting.postMessage({ type: 'skipWaiting' });
}
});
});
window.addEventListener('load', function () {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
registrations.forEach(function (registration) {
var worker = registration.active || registration.waiting || registration.installing;
var workerPath = worker ? new URL(worker.scriptURL).pathname : '';
if (worker && !workerPath.endsWith('/sw.js')) {
registration.unregister();
}
});
});
if (window.caches) {
caches.keys().then(function (keys) {
keys.forEach(function (key) {
if (
key === 'flutter-app-cache' ||
key === 'flutter-temp-cache' ||
key === 'flutter-app-manifest'
) {
caches.delete(key);
}
});
});
}
});
}
</script>
<script
defer
data-sw-bootstrap
src="bootstrap.js"
data-config='{
"logo": "icons/Icon-192.png?v={{sw_version}}",
"theme": "dark",
"color": "#46d3b1",
"showPercentage": false
}'
></script>
</body>
</html>