feat(train): the instance's own map tiles, drawn by Train's style (ADR 0030, D50)

Protomaps' basemap cut for Europe and served by pmtiles beside Train's server
(compose.maps.yaml), drawn by Train's own style, light and dark, which the
server serves. Only people signed in get tiles: map.source hands a key that
Caddy has the server check before each tile; nothing logs a tile.

Also fixes .dockerignore, which left apps/train/ out of the build context, so
Train's server's and BRouter's images couldn't have been built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-29 16:04:05 +01:00
commit 190c3872f4
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -10,8 +10,14 @@ import 'package:yaml/yaml.dart';
const _dockerfiles = [
'apps/learn/halkyon_learn_server/Dockerfile',
'apps/learn/halkyon_learn_curator/Dockerfile',
'apps/train/halkyon_train_server/Dockerfile',
];
/// The sidecars' images, which copy single files of the repository's: kept
/// out of the build's context, they failed it (29 Oct 2026, Train's running
/// profile, `apps/train/` left out whole).
const _sidecars = ['deploy/brouter/Dockerfile', 'deploy/maps/Dockerfile'];
/// The packages [package] takes by path, and theirs, with itself: pub
/// resolves every workspace member's dev dependencies too, so an image
/// needs those as well.
@ -91,4 +97,28 @@ void main() {
});
});
}
for (final path in _sidecars) {
test("$path copies files that are in the build's context", () {
final ignored = _ignored();
final sources = [
for (final match in RegExp(
r'^COPY (?:--\S+ )*(\S+) \S+$',
multiLine: true,
).allMatches(File(path).readAsStringSync()))
match[1]!,
];
expect(sources, isNotEmpty);
for (final source in sources) {
expect(File(source).existsSync(), isTrue, reason: source);
expect(
ignored.where(
(folder) => source == folder || p.isWithin(folder, source),
),
isEmpty,
reason: '.dockerignore leaves $source out',
);
}
});
}
}