v4: the devcontainer starts several gerbeur instances side by side, so that signing in from one to another can be tried on one machine — the dev environment ran a single instance. dev/instances.ts lists them (gerbeur on :3000 and :8000, musique on :3001 and :8001), and dev/start.ts starts an API server, restarted on change, and a Vite server for each instance it's given, by one rule: instance <name> keeps api/sql/<name>.db and api/uploads/<name>/, reads .env, and takes its ports and what sets it apart from its entry, with federation allowed over http on localhost. It prefixes each line of output with the instance's name, and stops every server when one stops, such as a Vite server whose port is taken. The devcontainer is now a compose project (.devcontainer/compose.yaml): the workspace, a one-shot install that runs deno install and draws the icons once, and a service per instance running dev/start.ts for it, all on the host's network as before and sharing Deno's cache through a volume. ffmpeg moves from a feature into the Dockerfile, since the instances' services get no features, and docker-outside-of-docker gives the workspace's terminal their logs and restarts. Outside the devcontainer, deno task dev starts them all, or those named. Each Vite server keeps its own dependency cache. The existing dev uploads move to api/uploads/gerbeur/.
dev/start.ts was checked by hand: musique starting alone on a fresh database, an unknown name refused, a taken port stopping both servers, and Ctrl+C or SIGTERM leaving no server behind. The compose project couldn't be run here (no Docker in the workspace): its YAML parses and resolves as intended, but it is untested; tsc, eslint, deno check, deno fmt, deno lint and doc:lint, which now covers dev/, are clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
FROM denoland/deno:bin-2.9.0 AS deno
|
||||
FROM mcr.microsoft.com/devcontainers/typescript-node:20
|
||||
COPY --from=deno /deno /usr/local/bin/deno
|
||||
# The API draws thumbnails and waveforms with ffmpeg, in the workspace and in
|
||||
# the instances' services alike (compose.yaml), which don't get the features.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ffmpeg \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
# The services share Deno's cache through a volume (compose.yaml), which Docker
|
||||
# creates owned as this directory is, so it must exist and be node's.
|
||||
RUN mkdir -p /home/node/.cache/deno && chown -R node:node /home/node/.cache
|
||||
|
||||
58
.devcontainer/compose.yaml
Normal file
58
.devcontainer/compose.yaml
Normal file
@@ -0,0 +1,58 @@
|
||||
# The dev environment: the workspace VS Code attaches to (`dev`), and one
|
||||
# service per dev instance of gerbeur (dev/instances.ts), which start with it.
|
||||
# Each instance service runs dev/start.ts for its own instance, which derives
|
||||
# its ports, URLs, database and uploads from its entry there; a new instance is
|
||||
# an entry there and a service here.
|
||||
#
|
||||
# Every service shares the host's network, as the workspace always did: an
|
||||
# instance's URLs are localhost ones, which the browser and the other
|
||||
# instances' servers must both reach.
|
||||
#
|
||||
# From the workspace's terminal (docker-outside-of-docker):
|
||||
# docker compose -p gerbeur-dev logs -f musique
|
||||
# docker compose -p gerbeur-dev restart gerbeur
|
||||
# docker compose -p gerbeur-dev stop gerbeur musique # then `deno task dev`
|
||||
name: gerbeur-dev
|
||||
|
||||
x-workspace: &workspace
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: gerbeur-dev
|
||||
network_mode: host
|
||||
user: node
|
||||
working_dir: /workspaces/gerbeur
|
||||
volumes:
|
||||
- ..:/workspaces/gerbeur:cached
|
||||
# Shared, so that each service doesn't download the jsr and npm packages
|
||||
# again.
|
||||
- deno-cache:/home/node/.cache/deno
|
||||
|
||||
x-instance: &instance
|
||||
<<: *workspace
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
install:
|
||||
condition: service_completed_successfully
|
||||
|
||||
services:
|
||||
dev:
|
||||
<<: *workspace
|
||||
command: sleep infinity
|
||||
|
||||
# Installs the packages and draws the icons once, before any instance
|
||||
# starts, so that the instances don't do it at the same time.
|
||||
install:
|
||||
<<: *workspace
|
||||
command: sh -c "deno install && deno task icons public"
|
||||
|
||||
gerbeur:
|
||||
<<: *instance
|
||||
command: deno run --env-file -A dev/start.ts gerbeur
|
||||
|
||||
musique:
|
||||
<<: *instance
|
||||
command: deno run --env-file -A dev/start.ts musique
|
||||
|
||||
volumes:
|
||||
deno-cache:
|
||||
@@ -1,10 +1,5 @@
|
||||
{
|
||||
"features": {
|
||||
"ghcr.io/devcontainers-extra/features/ffmpeg-apt-get:1": {
|
||||
"version": "1.0.17",
|
||||
"resolved": "ghcr.io/devcontainers-extra/features/ffmpeg-apt-get@sha256:735491c8e9b2236cae727d6d4904663f6a58eb131d8c4b6b18fd0eea3d8c5b71",
|
||||
"integrity": "sha256:735491c8e9b2236cae727d6d4904663f6a58eb131d8c4b6b18fd0eea3d8c5b71"
|
||||
},
|
||||
"ghcr.io/khannurien/devcontainer-features/claude-code:1": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "ghcr.io/khannurien/devcontainer-features/claude-code@sha256:17eb69bfd15ff5206c0bff2945935a4349f7423cabee461a0ba2681d52205db9",
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
{
|
||||
"name": "Deno",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"name": "gerbeur",
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
"runArgs": ["--network=host"],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "yarn install",
|
||||
// The workspace and the dev instances of gerbeur, one service each: see
|
||||
// compose.yaml. The instances start with the container.
|
||||
"dockerComposeFile": "compose.yaml",
|
||||
"service": "dev",
|
||||
"workspaceFolder": "/workspaces/gerbeur",
|
||||
"shutdownAction": "stopCompose",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
@@ -26,9 +19,8 @@
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/warrenbuckley/codespace-features/sqlite:1": {},
|
||||
"ghcr.io/devcontainers-extra/features/ffmpeg-apt-get:1": {}
|
||||
// The docker CLI, on the host's daemon, for the instances' logs and
|
||||
// restarts (compose.yaml).
|
||||
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
|
||||
}
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user