-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(starter): starter improvements to avoid port clashes (#505)
This PR improves the starter to enable several (independent) Electric applications to run on the same machine and thus fixes #497 and #489. Also addressed VAX-1114. The changes are as follows: - Avoid volume clashes by putting project name on the app name - Avoid web server port clashes by supporting a custom port to be used and fix it everywhere in the template - Avoid Electric port clashes by supporting a custom port to be used and fix it everywhere in the template - Introduced 2 modes for the starter: fast mode and interactive mode - Fast mode: app name and ports (optional) are provided as command line arguments - Interactive mode: no arguments to the script, app name and ports are asked via prompts - Changed start to check that the chosen port for Electric is free. If not, prompt user if they want to change the port - Script to change the project’s configuration with other Electric and web server ports. Exposed as a new `ports:configure` command. - Changed `backend:start` to check for port clashes and if there is a port clash suggest to run `ports:configure`. - Changed `yarn start` and `client:generate` to check that the Electric port the app is configured to use is the app's own Electric service (e.g. catches problem where project 1 is running Electric on port 5133 and another project is accidentally configured to also connect to port 5133). - Modified build script to use forward requests to right esbuild server. This fixes a bug where if an esbuild server was already running, the new app would forward its requests to the esbuild server of the other app. tldr: it should now be possible to run several Electric applications. Port clashes should always be detected and reported with a suggestion to reconfigure the app with other ports. --------- Co-authored-by: Oleksii Sholik <[email protected]>
- Loading branch information
Showing
16 changed files
with
591 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
"create-electric-app": patch | ||
--- | ||
|
||
Improved starter such that several (independent) Electric projects can run concurrently. | ||
The starter now has 2 modes: fast mode and interactive mode. | ||
In fast mode, you can provide the app name and optional ports for Electric and the webserver as arguments. | ||
In interactive mode, the script will prompt for an app name and ports (suggesting defaults). | ||
Port clashes are now detected and reported to the user. | ||
The user can change the ports the app uses by invoking 'yarn ports:configure'. | ||
Also fixes the bug where all Electric applications would forward requests to the esbuild server that is running on port 8000 instead of their own esbuild server. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
declare module 'prompt' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const exec = require('shelljs-live') | ||
const path = require('path') | ||
|
||
const envrcFile = path.join(__dirname, 'compose', '.envrc') | ||
const composeFile = path.join(__dirname, 'compose', 'docker-compose.yaml') | ||
|
||
const cliArguments = process.argv.slice(2).join(' ') | ||
|
||
const res = exec(`docker compose --env-file ${envrcFile} -f ${composeFile} up ${cliArguments}`) | ||
|
||
if (res.code !== 0 && res.stderr.includes('port is already allocated')) { | ||
// inform the user that they should change ports | ||
console.error( | ||
'\x1b[31m', | ||
'Could not start Electric because the port seems to be taken.\n' + | ||
'To run Electric on another port execute `yarn ports:configure`' | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,74 @@ | ||
const shell = require('shelljs') | ||
const exec = require('shelljs-live') | ||
|
||
let db = process.env.DATABASE_URL | ||
let electricPort = process.env.ELECTRIC_PORT ?? 5133 | ||
|
||
if (process.argv.length === 4) { | ||
const command = process.argv[2] | ||
let args = process.argv.slice(2) | ||
|
||
if (command !== '-db') { | ||
console.error(`Unsupported option ${command}. Only '-db' option is supported.`) | ||
while (args.length > 0) { | ||
// There are arguments to parse | ||
const flag = args[0] | ||
const value = args[1] | ||
|
||
process.exit(1) | ||
args = args.slice(2) | ||
|
||
const checkValue = () => { | ||
if (typeof value === 'undefined') { | ||
error(`Missing value for option '${flag}'.`) | ||
} | ||
} | ||
|
||
db = process.argv[3] | ||
switch (flag) { | ||
case '-db': | ||
checkValue() | ||
db = value | ||
break | ||
case '--electric-port': | ||
checkValue() | ||
parseElectricPort(value) | ||
break | ||
default: | ||
error(`Unrecognized option: '${flag}'.`) | ||
} | ||
} | ||
else if (process.argv.length !== 2) { | ||
console.log('Wrong number of arguments provided. Only one optional argument `-db <Postgres connection url>` is supported.') | ||
|
||
function parseElectricPort(port) { | ||
// checks that the number is between 0 and 65535 | ||
const portRegex = /^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/ | ||
if (!portRegex.test(port)) { | ||
error(`Invalid port '${port}. Port should be between 0 and 65535.'`) | ||
} | ||
electricPort = port | ||
} | ||
|
||
if (db === undefined) { | ||
console.error(`Database URL is not provided. Please provide one using the DATABASE_URL environment variable.`) | ||
|
||
process.exit(1) | ||
} | ||
|
||
const electric = process.env.ELECTRIC_IMAGE ?? "electricsql/electric:latest" | ||
|
||
shell.exec( | ||
// 5433 is the logical publisher port | ||
// it is exposed because PG must be able to connect to Electric | ||
const res = exec( | ||
`docker run \ | ||
-e "DATABASE_URL=${db}" \ | ||
-e "LOGICAL_PUBLISHER_HOST=localhost" \ | ||
-e "AUTH_MODE=insecure" \ | ||
-p 5133:5133 \ | ||
-p ${electricPort}:5133 \ | ||
-p 5433:5433 ${electric}` | ||
) | ||
|
||
if (res.code !== 0 && res.stderr.includes('port is already allocated')) { | ||
// inform the user that they should change ports | ||
console.error( | ||
'\x1b[31m', | ||
'Could not start Electric because the port seems to be taken.\n' + | ||
'To run Electric on another port execute `yarn ports:configure`' | ||
) | ||
} | ||
|
||
function error(err) { | ||
console.error('\x1b[31m', err + '\nyarn electric:start [-db <Postgres connection url>] [-p <Electric port>]') | ||
process.exit(1) | ||
} |
Oops, something went wrong.