Added support for developing in devcontainer (#480)
This commit is contained in:
parent
fd59bc219c
commit
848269a4d4
54
.devcontainer/Caddyfile.dev
Normal file
54
.devcontainer/Caddyfile.dev
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# Like dev/Caddyfile.dev, but LiveKit and Mailpit are referenced by their
|
||||||
|
# Docker Compose hostnames instead of 127.0.0.1.
|
||||||
|
|
||||||
|
{
|
||||||
|
auto_https off
|
||||||
|
admin off
|
||||||
|
}
|
||||||
|
|
||||||
|
:48763 {
|
||||||
|
handle /_caddy_health {
|
||||||
|
respond "OK" 200
|
||||||
|
}
|
||||||
|
|
||||||
|
@gateway path /gateway /gateway/*
|
||||||
|
handle @gateway {
|
||||||
|
uri strip_prefix /gateway
|
||||||
|
reverse_proxy 127.0.0.1:49107
|
||||||
|
}
|
||||||
|
|
||||||
|
@marketing path /marketing /marketing/*
|
||||||
|
handle @marketing {
|
||||||
|
uri strip_prefix /marketing
|
||||||
|
reverse_proxy 127.0.0.1:49531
|
||||||
|
}
|
||||||
|
|
||||||
|
@server path /admin /admin/* /api /api/* /s3 /s3/* /queue /queue/* /media /media/* /_health /_ready /_live /.well-known/fluxer
|
||||||
|
handle @server {
|
||||||
|
reverse_proxy 127.0.0.1:49319
|
||||||
|
}
|
||||||
|
|
||||||
|
@livekit path /livekit /livekit/*
|
||||||
|
handle @livekit {
|
||||||
|
uri strip_prefix /livekit
|
||||||
|
reverse_proxy livekit:7880
|
||||||
|
}
|
||||||
|
|
||||||
|
redir /mailpit /mailpit/
|
||||||
|
handle_path /mailpit/* {
|
||||||
|
rewrite * /mailpit{path}
|
||||||
|
reverse_proxy mailpit:8025
|
||||||
|
}
|
||||||
|
|
||||||
|
handle {
|
||||||
|
reverse_proxy 127.0.0.1:49427 {
|
||||||
|
header_up Connection {http.request.header.Connection}
|
||||||
|
header_up Upgrade {http.request.header.Upgrade}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log {
|
||||||
|
output stdout
|
||||||
|
format console
|
||||||
|
}
|
||||||
|
}
|
||||||
40
.devcontainer/Dockerfile
Normal file
40
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Language runtimes (Node.js, Go, Rust, Python) are installed via devcontainer
|
||||||
|
# features. This Dockerfile handles Erlang/OTP (no feature available) and
|
||||||
|
# tools like Caddy, process-compose, rebar3, uv, ffmpeg, and exiftool.
|
||||||
|
|
||||||
|
FROM erlang:28-slim AS erlang
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/devcontainers/base:debian-13
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
ARG REBAR3_VERSION=3.24.0
|
||||||
|
ARG PROCESS_COMPOSE_VERSION=1.90.0
|
||||||
|
|
||||||
|
# Both erlang:28-slim and debian-13 are Trixie-based, so OpenSSL versions match.
|
||||||
|
COPY --from=erlang /usr/local/lib/erlang /usr/local/lib/erlang
|
||||||
|
RUN ln -sf /usr/local/lib/erlang/bin/* /usr/local/bin/
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libncurses6 libsctp1 \
|
||||||
|
build-essential pkg-config \
|
||||||
|
ffmpeg libimage-exiftool-perl \
|
||||||
|
sqlite3 libsqlite3-dev \
|
||||||
|
libssl-dev openssl \
|
||||||
|
gettext-base lsof iproute2 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN curl -fsSL "https://github.com/erlang/rebar3/releases/download/${REBAR3_VERSION}/rebar3" \
|
||||||
|
-o /usr/local/bin/rebar3 \
|
||||||
|
&& chmod +x /usr/local/bin/rebar3
|
||||||
|
|
||||||
|
RUN curl -fsSL "https://caddyserver.com/api/download?os=linux&arch=amd64" \
|
||||||
|
-o /usr/local/bin/caddy \
|
||||||
|
&& chmod +x /usr/local/bin/caddy
|
||||||
|
|
||||||
|
RUN curl -fsSL "https://github.com/F1bonacc1/process-compose/releases/download/v${PROCESS_COMPOSE_VERSION}/process-compose_linux_amd64.tar.gz" \
|
||||||
|
| tar xz -C /usr/local/bin process-compose \
|
||||||
|
&& chmod +x /usr/local/bin/process-compose
|
||||||
|
|
||||||
|
RUN curl -fsSL "https://github.com/astral-sh/uv/releases/latest/download/uv-x86_64-unknown-linux-gnu.tar.gz" \
|
||||||
|
| tar xz --strip-components=1 -C /usr/local/bin \
|
||||||
|
&& chmod +x /usr/local/bin/uv /usr/local/bin/uvx
|
||||||
75
.devcontainer/devcontainer.json
Normal file
75
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"name": "Fluxer",
|
||||||
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
|
"service": "app",
|
||||||
|
"workspaceFolder": "/workspace",
|
||||||
|
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
|
"version": "24",
|
||||||
|
"pnpmVersion": "10.29.3"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/go:1": {
|
||||||
|
"version": "1.24"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/rust:1": {
|
||||||
|
"version": "1.93.0",
|
||||||
|
"targets": "wasm32-unknown-unknown"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/python:1": {
|
||||||
|
"version": "os-provided",
|
||||||
|
"installTools": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"onCreateCommand": ".devcontainer/on-create.sh",
|
||||||
|
|
||||||
|
"remoteEnv": {
|
||||||
|
"FLUXER_CONFIG": "${containerWorkspaceFolder}/config/config.json",
|
||||||
|
"FLUXER_DATABASE": "sqlite"
|
||||||
|
},
|
||||||
|
|
||||||
|
"forwardPorts": [48763, 6379, 7700, 7880],
|
||||||
|
|
||||||
|
"portsAttributes": {
|
||||||
|
"48763": {
|
||||||
|
"label": "Fluxer (Caddy)",
|
||||||
|
"onAutoForward": "openBrowser",
|
||||||
|
"protocol": "http"
|
||||||
|
},
|
||||||
|
"6379": {
|
||||||
|
"label": "Valkey",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"7700": {
|
||||||
|
"label": "Meilisearch",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"7880": {
|
||||||
|
"label": "LiveKit",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"9229": {
|
||||||
|
"label": "Node.js Debugger",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"TypeScriptTeam.native-preview",
|
||||||
|
"biomejs.biome",
|
||||||
|
"clinyong.vscode-css-modules",
|
||||||
|
"pgourlain.erlang",
|
||||||
|
"golang.go",
|
||||||
|
"rust-lang.rust-analyzer"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"typescript.preferences.includePackageJsonAutoImports": "auto",
|
||||||
|
"typescript.suggest.autoImports": true,
|
||||||
|
"typescript.experimental.useTsgo": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
.devcontainer/docker-compose.yml
Normal file
64
.devcontainer/docker-compose.yml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
volumes:
|
||||||
|
- ..:/workspace:cached
|
||||||
|
command: sleep infinity
|
||||||
|
|
||||||
|
valkey:
|
||||||
|
image: valkey/valkey:8-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ['valkey-server', '--appendonly', 'yes', '--save', '60', '1', '--loglevel', 'warning']
|
||||||
|
volumes:
|
||||||
|
- valkey-data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ['CMD', 'valkey-cli', 'ping']
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.14
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MEILI_NO_ANALYTICS: 'true'
|
||||||
|
MEILI_ENV: development
|
||||||
|
MEILI_MASTER_KEY: fluxer-devcontainer-meili-master-key
|
||||||
|
volumes:
|
||||||
|
- meilisearch-data:/meili_data
|
||||||
|
healthcheck:
|
||||||
|
test: ['CMD', 'curl', '-f', 'http://localhost:7700/health']
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
livekit:
|
||||||
|
image: livekit/livekit-server:v1.9
|
||||||
|
restart: unless-stopped
|
||||||
|
command: --config /etc/livekit.yaml
|
||||||
|
volumes:
|
||||||
|
- ./livekit.yaml:/etc/livekit.yaml:ro
|
||||||
|
|
||||||
|
mailpit:
|
||||||
|
image: axllent/mailpit:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ['--webroot', '/mailpit/']
|
||||||
|
|
||||||
|
nats-core:
|
||||||
|
image: nats:2-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ['--port', '4222']
|
||||||
|
|
||||||
|
nats-jetstream:
|
||||||
|
image: nats:2-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
command: ['--port', '4223', '--jetstream', '--store_dir', '/data']
|
||||||
|
volumes:
|
||||||
|
- nats-jetstream-data:/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
valkey-data:
|
||||||
|
meilisearch-data:
|
||||||
|
nats-jetstream-data:
|
||||||
30
.devcontainer/livekit.yaml
Normal file
30
.devcontainer/livekit.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Credentials here must match the values on-create.sh writes to config.json.
|
||||||
|
|
||||||
|
port: 7880
|
||||||
|
|
||||||
|
keys:
|
||||||
|
fluxer-devcontainer-key: fluxer-devcontainer-secret-key-00000000
|
||||||
|
|
||||||
|
rtc:
|
||||||
|
tcp_port: 7881
|
||||||
|
port_range_start: 50000
|
||||||
|
port_range_end: 50100
|
||||||
|
use_external_ip: false
|
||||||
|
node_ip: 127.0.0.1
|
||||||
|
|
||||||
|
turn:
|
||||||
|
enabled: true
|
||||||
|
domain: localhost
|
||||||
|
udp_port: 3478
|
||||||
|
|
||||||
|
webhook:
|
||||||
|
api_key: fluxer-devcontainer-key
|
||||||
|
urls:
|
||||||
|
- http://app:49319/api/webhooks/livekit
|
||||||
|
|
||||||
|
room:
|
||||||
|
auto_create: true
|
||||||
|
max_participants: 100
|
||||||
|
empty_timeout: 300
|
||||||
|
|
||||||
|
development: true
|
||||||
70
.devcontainer/on-create.sh
Executable file
70
.devcontainer/on-create.sh
Executable file
@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Runs once when the container is first created.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
|
export FLUXER_CONFIG="${FLUXER_CONFIG:-$REPO_ROOT/config/config.json}"
|
||||||
|
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m'
|
||||||
|
info() { printf "%b\n" "${GREEN}[devcontainer]${NC} $1"; }
|
||||||
|
|
||||||
|
info "Installing pnpm dependencies..."
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Codegen outputs (e.g. MasterZodSchema.generated.tsx) are gitignored.
|
||||||
|
info "Generating config schema..."
|
||||||
|
pnpm --filter @fluxer/config generate
|
||||||
|
|
||||||
|
if [ ! -f "$FLUXER_CONFIG" ]; then
|
||||||
|
info "Creating config from development template..."
|
||||||
|
cp "$REPO_ROOT/config/config.dev.template.json" "$FLUXER_CONFIG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Point services at Docker Compose hostnames and adjust settings that differ
|
||||||
|
# from the default dev template.
|
||||||
|
info "Patching config for Docker Compose networking..."
|
||||||
|
jq '
|
||||||
|
# rspack defaults public_scheme to "https" when unset
|
||||||
|
.domain.public_scheme = "http" |
|
||||||
|
# Relative path so the app works on any hostname (localhost, 127.0.0.1, etc.)
|
||||||
|
.app_public.bootstrap_api_endpoint = "/api" |
|
||||||
|
|
||||||
|
.internal.kv = "redis://valkey:6379/0" |
|
||||||
|
|
||||||
|
.integrations.search.url = "http://meilisearch:7700" |
|
||||||
|
.integrations.search.api_key = "fluxer-devcontainer-meili-master-key" |
|
||||||
|
|
||||||
|
# Credentials must match .devcontainer/livekit.yaml
|
||||||
|
.integrations.voice.url = "ws://livekit:7880" |
|
||||||
|
.integrations.voice.webhook_url = "http://app:49319/api/webhooks/livekit" |
|
||||||
|
.integrations.voice.api_key = "fluxer-devcontainer-key" |
|
||||||
|
.integrations.voice.api_secret = "fluxer-devcontainer-secret-key-00000000" |
|
||||||
|
|
||||||
|
.integrations.email.smtp.host = "mailpit" |
|
||||||
|
.integrations.email.smtp.port = 1025 |
|
||||||
|
|
||||||
|
.services.nats.core_url = "nats://nats-core:4222" |
|
||||||
|
.services.nats.jetstream_url = "nats://nats-jetstream:4223" |
|
||||||
|
|
||||||
|
# Bluesky OAuth requires HTTPS + loopback IPs (RFC 8252), incompatible with
|
||||||
|
# the HTTP-only devcontainer setup.
|
||||||
|
.auth.bluesky.enabled = false
|
||||||
|
' "$FLUXER_CONFIG" > "$FLUXER_CONFIG.tmp" && mv "$FLUXER_CONFIG.tmp" "$FLUXER_CONFIG"
|
||||||
|
|
||||||
|
info "Running bootstrap..."
|
||||||
|
"$REPO_ROOT/scripts/dev_bootstrap.sh"
|
||||||
|
|
||||||
|
info "Pre-compiling Erlang gateway dependencies..."
|
||||||
|
(cd "$REPO_ROOT/fluxer_gateway" && rebar3 compile) || {
|
||||||
|
info "Gateway pre-compilation failed (non-fatal, will compile on first start)"
|
||||||
|
}
|
||||||
|
|
||||||
|
info "Devcontainer setup complete."
|
||||||
|
info ""
|
||||||
|
info " Start all dev processes: process-compose -f .devcontainer/process-compose.yml up"
|
||||||
|
info " Open the app: http://127.0.0.1:48763"
|
||||||
|
info " Dev email inbox: http://127.0.0.1:48763/mailpit/"
|
||||||
|
info ""
|
||||||
57
.devcontainer/process-compose.yml
Normal file
57
.devcontainer/process-compose.yml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Application processes only — backing services (Valkey, Meilisearch, LiveKit,
|
||||||
|
# Mailpit, NATS) run via Docker Compose.
|
||||||
|
# process-compose -f .devcontainer/process-compose.yml up
|
||||||
|
|
||||||
|
is_tui_disabled: false
|
||||||
|
log_level: info
|
||||||
|
log_configuration:
|
||||||
|
flush_each_line: true
|
||||||
|
|
||||||
|
processes:
|
||||||
|
caddy:
|
||||||
|
command: caddy run --config .devcontainer/Caddyfile.dev --adapter caddyfile
|
||||||
|
log_location: dev/logs/caddy.log
|
||||||
|
readiness_probe:
|
||||||
|
http_get:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 48763
|
||||||
|
path: /_caddy_health
|
||||||
|
availability:
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
fluxer_server:
|
||||||
|
command: pnpm --filter fluxer_server dev
|
||||||
|
log_location: dev/logs/fluxer_server.log
|
||||||
|
availability:
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
fluxer_app:
|
||||||
|
command: ./scripts/dev_fluxer_app.sh
|
||||||
|
environment:
|
||||||
|
- FORCE_COLOR=1
|
||||||
|
- FLUXER_APP_DEV_PORT=49427
|
||||||
|
log_location: dev/logs/fluxer_app.log
|
||||||
|
availability:
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
fluxer_gateway:
|
||||||
|
command: ./scripts/dev_gateway.sh
|
||||||
|
environment:
|
||||||
|
- FLUXER_GATEWAY_NO_SHELL=1
|
||||||
|
log_location: dev/logs/fluxer_gateway.log
|
||||||
|
availability:
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
marketing_dev:
|
||||||
|
command: pnpm --filter fluxer_marketing dev
|
||||||
|
environment:
|
||||||
|
- FORCE_COLOR=1
|
||||||
|
log_location: dev/logs/marketing_dev.log
|
||||||
|
availability:
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
css_watch:
|
||||||
|
command: ./scripts/dev_css_watch.sh
|
||||||
|
log_location: dev/logs/css_watch.log
|
||||||
|
availability:
|
||||||
|
restart: always
|
||||||
84
.vscode/launch.json
vendored
Normal file
84
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug: fluxer_server",
|
||||||
|
"program": "${workspaceFolder}/fluxer_server/src/startServer.tsx",
|
||||||
|
"runtimeArgs": ["--import", "tsx"],
|
||||||
|
"cwd": "${workspaceFolder}/fluxer_server",
|
||||||
|
"env": {
|
||||||
|
"FLUXER_CONFIG": "${workspaceFolder}/config/config.json",
|
||||||
|
"FLUXER_DATABASE": "sqlite"
|
||||||
|
},
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"skipFiles": ["<node_internals>/**", "**/node_modules/**"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug: fluxer_api (standalone)",
|
||||||
|
"program": "${workspaceFolder}/fluxer_api/src/AppEntrypoint.tsx",
|
||||||
|
"runtimeArgs": ["--import", "tsx"],
|
||||||
|
"cwd": "${workspaceFolder}/fluxer_api",
|
||||||
|
"env": {
|
||||||
|
"FLUXER_CONFIG": "${workspaceFolder}/config/config.json",
|
||||||
|
"FLUXER_DATABASE": "sqlite"
|
||||||
|
},
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"skipFiles": ["<node_internals>/**", "**/node_modules/**"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug: fluxer_marketing",
|
||||||
|
"program": "${workspaceFolder}/fluxer_marketing/src/index.tsx",
|
||||||
|
"runtimeArgs": ["--import", "tsx"],
|
||||||
|
"cwd": "${workspaceFolder}/fluxer_marketing",
|
||||||
|
"env": {
|
||||||
|
"FLUXER_CONFIG": "${workspaceFolder}/config/config.json"
|
||||||
|
},
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"skipFiles": ["<node_internals>/**", "**/node_modules/**"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug: fluxer_app (DevServer)",
|
||||||
|
"program": "${workspaceFolder}/fluxer_app/scripts/DevServer.tsx",
|
||||||
|
"runtimeArgs": ["--import", "tsx"],
|
||||||
|
"cwd": "${workspaceFolder}/fluxer_app",
|
||||||
|
"env": {
|
||||||
|
"FLUXER_APP_DEV_PORT": "49427",
|
||||||
|
"FORCE_COLOR": "1"
|
||||||
|
},
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"skipFiles": ["<node_internals>/**", "**/node_modules/**"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug: Test Current File",
|
||||||
|
"program": "${workspaceFolder}/node_modules/vitest/vitest.mjs",
|
||||||
|
"args": ["run", "--no-coverage", "${relativeFile}"],
|
||||||
|
"autoAttachChildProcesses": true,
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"skipFiles": ["<node_internals>/**", "**/node_modules/**"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Attach to Node Process",
|
||||||
|
"port": 9229,
|
||||||
|
"restart": true,
|
||||||
|
"skipFiles": ["<node_internals>/**", "**/node_modules/**"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"compounds": [
|
||||||
|
{
|
||||||
|
"name": "Debug: Server + App",
|
||||||
|
"configurations": ["Debug: fluxer_server", "Debug: fluxer_app (DevServer)"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
16
README.md
16
README.md
@ -73,7 +73,7 @@ TBD
|
|||||||
|
|
||||||
### Devenv development environment
|
### Devenv development environment
|
||||||
|
|
||||||
Fluxer supports development through **devenv** only. It provides a reproducible Nix environment and a single, declarative process manager for the dev stack. If you need a different setup, it is currently unsupported.
|
Fluxer supports development through **devenv** only. It provides a reproducible Nix environment and a single, declarative process manager for the dev stack.
|
||||||
|
|
||||||
1. Install Nix and devenv using the [devenv getting started guide](https://devenv.sh/getting-started/).
|
1. Install Nix and devenv using the [devenv getting started guide](https://devenv.sh/getting-started/).
|
||||||
2. Enter the environment:
|
2. Enter the environment:
|
||||||
@ -108,6 +108,20 @@ If you develop on a remote VM behind Cloudflare Tunnels (or a similar HTTP-only
|
|||||||
|
|
||||||
The bootstrap script configures LiveKit automatically based on `domain.base_domain` in your `config.json`. When set to a non-localhost domain, it enables external IP discovery so clients can connect directly for media while signaling continues through the tunnel.
|
The bootstrap script configures LiveKit automatically based on `domain.base_domain` in your `config.json`. When set to a non-localhost domain, it enables external IP discovery so clients can connect directly for media while signaling continues through the tunnel.
|
||||||
|
|
||||||
|
### Devcontainer (experimental)
|
||||||
|
|
||||||
|
There is experimental support for developing in a **VS Code Dev Container** / GitHub Codespace without Nix. The `.devcontainer/` directory provides a Docker Compose setup with all required tooling and backing services.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Inside the dev container, start all processes:
|
||||||
|
process-compose -f .devcontainer/process-compose.yml up
|
||||||
|
```
|
||||||
|
|
||||||
|
Open the app at `http://localhost:48763` and the dev email inbox at `http://localhost:48763/mailpit/`. Predefined VS Code debugging targets are available in `.vscode/launch.json`.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Bluesky OAuth is disabled in the devcontainer because it requires HTTPS. All other features work normally.
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
To develop the documentation site with live preview:
|
To develop the documentation site with live preview:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user