Code Monkey home page Code Monkey logo

chalet's Introduction

chalet

Start apps from your browser and use local domains/https automatically

Note: This is a maintained fork of hotel, which seems to have grown stale.

Tip: if you don't enable local domains, chalet can still be used as a catalog of local servers.

Chalet works great on any OS (macOS, Linux, Windows) and with all servers ❤️

  • Node (Express, Webpack)
  • PHP (Laravel, Symfony)
  • Ruby (Rails, Sinatra, Jekyll)
  • Python (Django)
  • Docker
  • Go
  • Apache, Nginx
  • ...

v0.8.0 upgrade

.localhost replaces .dev local domain and is the new default. See https://ma.ttias.be/chrome-force-dev-domains-https-via-preloaded-hsts/ for context.

If you're upgrading, please be sure to:

  1. Remove "tld": "dev" from your ~/.chalet/conf.json file
  2. Run chalet stop && chalet start
  3. Refresh your network settings

Features

  • Local domains - http://project.test
  • HTTPS via local self-signed SSL certificate - https://project.test
  • Wildcard subdomains - http://*.project.test
  • Works everywhere - macOS, Linux and Windows
  • Works with any server - Node, Ruby, PHP, ...
  • Proxy - Map local domains to remote servers
  • System-friendly - No messing with port 80, /etc/hosts, sudo or additional software
  • Fallback URL - http://localhost:2000/project
  • Servers are only started when you access them
  • Plays nice with other servers (Apache, Nginx, ...)
  • Random or fixed ports

Install

npm install -g chalet && chalet start

Chalet requires Node to be installed, if you don't have it, you can simply install it using one of the following method:

You can also visit https://nodejs.org.

Quick start

Local domains (optional)

To use local .test domains, you need to configure your network or browser to use chalet's proxy auto-config file or you can skip this step for the moment and go directly to http://localhost:2000

See instructions here.

Add your servers

# Add your server to chalet
~/projects/one$ chalet add 'npm start'
# Or start your server in the terminal as usual and get a temporary local domain
~/projects/two$ chalet run 'npm start'

Visit localhost:2000 or http(s)://chalet.test.

Alternatively you can directly go to

http://localhost:2000/one
http://localhost:2000/two
http(s)://one.test
http(s)://two.test

Popular servers examples

Using other servers? Here are some examples to get you started :)

chalet add 'ember server'                               # Ember
chalet add 'jekyll serve --port $PORT'                  # Jekyll
chalet add 'rails server -p $PORT -b 127.0.0.1'         # Rails
chalet add 'python -m SimpleHTTPServer $PORT'           # static file server (Python)
chalet add 'php -S 127.0.0.1:$PORT'                     # PHP
chalet add 'docker-compose up'                          # docker-compose
chalet add 'python manage.py runserver 127.0.0.1:$PORT' # Django
chalet add 'npm run dev -- --port $PORT'                # Vite Dev Server
# ...

On Windows use "%PORT%" instead of '$PORT'

See a Docker example here..

Proxy requests to remote servers

Add your remote servers

~$ chalet add http://192.168.1.12:1337 --name aliased-address
~$ chalet add http://google.com --name aliased-domain

You can now access them using

http://aliased-address.test # will proxy requests to http://192.168.1.12:1337
http://aliased-domain.test # will proxy requests to http://google.com

CLI usage and options

chalet add <cmd|url> [opts]
chalet run <cmd> [opts]

# Examples

chalet add 'nodemon app.js' --out dev.log  # Set output file (default: none)
chalet add 'nodemon app.js' --name name    # Set custom name (default: current dir name)
chalet add 'nodemon app.js' --port 3000    # Set a fixed port (default: random port)
chalet add 'nodemon app.js' --env PATH     # Store PATH environment variable in server config
chalet add http://192.168.1.10 --name app  # map local domain to URL

chalet run 'nodemon app.js'                # Run server and get a temporary local domain

# Other commands

chalet ls     # List servers
chalet rm     # Remove server
chalet start  # Start chalet daemon
chalet stop   # Stop chalet daemon

To get help

chalet --help
chalet --help <cmd>

Port

For chalet to work, your servers need to listen on the PORT environment variable. Here are some examples showing how you can do it from your code or the command-line:

var port = process.env.PORT || 3000;
server.listen(port);
chalet add 'cmd -p $PORT'  # OS X, Linux
chalet add "cmd -p %PORT%" # Windows

Fallback URL

If you're offline or can't configure your browser to use .test domains, you can always access your local servers by going to localhost:2000.

Configurations, logs and self-signed SSL certificate

You can find chalet related files in ~/.chalet :

~/.chalet/conf.json
~/.chalet/daemon.log
~/.chalet/daemon.pid
~/.chalet/key.pem
~/.chalet/cert.pem
~/.chalet/servers/<app-name>.json

By default, chalet uses the following configuration values:

{
  "port": 2000,
  "host": '127.0.0.1',

  // Timeout when proxying requests to local domains
  "timeout": 5000,

  // Change this if you want to use another tld than .test
  "tld": 'test',

  // If you're behind a corporate proxy, replace this with your network proxy IP (example: "1.2.3.4:5000")
  "proxy": false
}

To override a value, simply add it to ~/.chalet/conf.json and run chalet stop && chalet start

Third-party tools

FAQ

Problem with self signed certificates

You will want to delete your existing certificates and restart chalet:

chalet stop
rm ~/.chalet/cert.pem ~/.chalet/key.pem
chalet start

Setting a fixed port

chalet add --port 3000 'server-cmd $PORT'

Adding X-Forwarded-* headers to requests

chalet add --xfwd 'server-cmd'

Setting HTTP_PROXY env

Use --http-proxy-env flag when adding your server or edit your server configuration in ~/.chalet/servers

chalet add --http-proxy-env 'server-cmd'

Proxying requests to a remote https server

chalet add --change-origin 'https://jsonplaceholder.typicode.com'

When proxying to a https server, you may get an error because your .test domain doesn't match the host defined in the server certificate. With this flag, host header is changed to match the target URL.

ENOSPC and EACCES errors

If you're seeing one of these errors in ~/.chalet/daemon.log, this usually means that there's some permissions issues. chalet daemon should be started without sudo and ~/.chalet should belong to $USER.

# to fix permissions
sudo chown -R $USER: $HOME/.chalet

See also, https://docs.npmjs.com/getting-started/fixing-npm-permissions

Configuring a network proxy IP

If you're behind a corporate proxy, replace "proxy" with your network proxy IP in ~/.chalet/conf.json. For example:

{
  "proxy": "1.2.3.4:5000"
}

License

MIT

chalet's People

Contributors

claycoleman avatar cobalamin avatar djyde avatar floydwch avatar greenkeeper[bot] avatar houfio avatar ishanray avatar j-f1 avatar james-zinger avatar janstevens avatar jeansaad avatar layerssss avatar leocolomb avatar leoj3n avatar m1guelpf avatar nchudleigh avatar nghuuphuoc avatar olibia avatar pascalpp avatar rhynodesigns avatar rstacruz avatar sonnyp avatar spentacular avatar srph avatar therealklanni avatar thomas-mcdonald avatar typicode avatar umhan35 avatar wtfaremyinitials avatar yeskunall avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

chalet's Issues

Is the redirect slow for anyone else?

I use chalet as a server catalog. I have fixed ports set up for most services. I hit localhost:2000/server-name to get redirected to the port.

It takes 3-4 seconds to redirect sometimes, I'm wondering why it should take any time at all, what happens other than the redirect? Is there anything to configure to make it redirect without checks?

Thanks

Feature Request: start/stop/restart saved servers from CLI

Currently hotel and chalet allow a user/developer to start/stop each saved server from the daemon's web app (localhost:2000).

I would like to be able to start/stop/restart a saved server via the chalet CLI, as shown here:

chalet start --name myapp
chalet stop --name myapp
chalet restart --name myapp

Optionally Tail Server Output

For start and restart, I would like an option (enabled via a new CLI option such as --listen) to output the server's logs to STDOUT, so that I could run these commands from a terminal window (or VS Code terminal) and see the server logs right there. This listening/tailing of the server logs could be terminated by SIGTERM or SIGINT (ctrl-C), ending the CLI process and returning to the shell, but keeping the server running (until stopped in the Chalet daemon web app or via chalet stop --name myapp).

If Server Already Running

Running the start command and specifying a server that is already running should cause an error message to be emitted to STDERR:

"Server '<name>' is already running"

However, if the --listen option is given, then the CLI process should output the server's logs to STDOUT and continue to tail the logs until terminated by SIGTERM or SIGINT (ctrl-C).

Preserve Current Daemon Management via start/stop/restart

If the -n/--name argument is omitted, then start/stop/restart would manage the daemon, as they do now, so current usage of chalet start/stop/restart would not be affected in any way.

Chalet does not work

Hello

I've just installed chalet and then run 'chalet start'.
It's impossible for me to reach the webpage so I've been into the daemon.log and here is what I founded

image

I try to run it with Ubuntu 20 and node v10.19.0

Thanks in advance

word chalet in domain seems to prevent proxying.

We proxy a wildcard domain through to chalet. If we have a project with the word chalet in the subdomain, the proxying doesn't work, it instead just shows the chalet dashboard.

Bit of an odd one, and probably a bit of a rare bug. Just thought I'd mention it. I'm guessing you doing a match against the word for some reason.

Change default tld from '.localhost' to '.test'

Hey,

First thanks for maintaining this fork, its great :) On hotel there's an issue about .localhost domains and Chrome typicode#326. The gist is that Chrome bypasses the proxy for .localhost domains.

Just wondering if you'd accept a PR to change the default tld to '.test' so chalet can work out of the box with Chrome

TypeError: Cannot read properties of undefined (reading 'status')

I'm using chalet to run a local Node dev server, as follows:

chalet run 'npm start' --name myapp

When I press Ctrl-C to kill the dev server, I see this error:

^C/opt/homebrew/lib/node_modules/chalet/lib/cli/run.js:60
          status = _this$_spawnSync.status,
                                    ^

TypeError: Cannot read properties of undefined (reading 'status')
    at startServer (/opt/homebrew/lib/node_modules/chalet/lib/cli/run.js:60:37)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Doesn't run on Ubuntu 19.10

alex@alex-brain ~/c/r/a/t/debug (content-negotiation ⚡↩=)> chalet add "./actix-example-server" --name schemas
Create ~/.chalet/servers/schemas.json
Output No log file specified (use '-o app.log')
Port Random port (use '-p 1337' to set a fixed port)
alex@alex-brain ~/c/r/a/t/debug (content-negotiation ⚡↩=)> ls
actix-example-server*  actix-example-server.d  actix-server*  actix-server.d  build/  deps/  examples/  incremental/  libactix_files.d  libactix_files.rlib  libactix_web.d  libactix_web.rlib
alex@alex-brain ~/c/r/a/t/debug (content-negotiation ⚡↩=)> chalet ls
schemas
~/c2/rust/actix-web/target/debug
./actix-example-server
alex@alex-brain ~/c/r/a/t/debug (content-negotiation ⚡↩=)> chalet run schemas
Create ~/.chalet/servers/debug.json
sh: 1: schemas: not found
(node:8995) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'status' of undefined
    at startServer (/home/alex/.config/yarn/global/node_modules/chalet/lib/cli/run.js:60:37)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:8995) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:8995) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Thought I'd report this here because Hotel isn't really maintained anymore. I'd appreciate any of your thoughts or if you could take a stab at fixing this.

Let me know if you need any more details. Thanks!

Environment

Kernel (uname -a): Linux alex-brain 5.3.0-64-generic #58-Ubuntu SMP Fri Jul 10 19:33:51 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
OS Version (cat /etc/os-release):

NAME="Ubuntu"
VERSION="19.10 (Eoan Ermine)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 19.10"
VERSION_ID="19.10"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=eoan
UBUNTU_CODENAME=eoan

Node environment:

$ node --version
v12.18.2
$ npm --version
6.14.5
$ yarn --version
1.22.0

http://localhost:2000/proxy.pac fails because can't find module 'pug'

Error: Cannot find module 'pug'
Require stack:
- /THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/view.js
- /THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/application.js
- /THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/express.js
- /THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/index.js
- /THEPROJECT/node_modules/.store/chalet-npm-0.10.2-0595cc1a69/node_modules/chalet/lib/daemon/app.js
- /THEPROJECT/node_modules/.store/chalet-npm-0.10.2-0595cc1a69/node_modules/chalet/lib/daemon/index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at new View (/THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/view.js:81:14)
    at Function.render (/THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/application.js:587:12)
    at ServerResponse.render (/THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/response.js:1039:7)
    at pac (/THEPROJECT/node_modules/.store/chalet-npm-0.10.2-0595cc1a69/node_modules/chalet/lib/daemon/routers/index.js:21:11)
    at Layer.handle [as handle_request] (/THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/router/layer.js:95:5)
    at next (/THEPROJECT/node_modules/.store/express-npm-4.18.2-bb15ff679a/node_modules/express/lib/router/route.js:144:13)

crashing on server start

Exiting
Stop daemon
Remove pid file
internal/fs/utils.js:785
  throw new ERR_INVALID_ARG_TYPE(
  ^

TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Error
    at Object.writeFile (fs.js:1487:5)
    at Object.appendFile (fs.js:1550:6)
    at Group._log (/home/k1ng/.nvm/versions/node/v14.17.0/lib/node_modules/chalet/lib/daemon/group.js:134:12)
    at Monitor.<anonymous> (/home/k1ng/.nvm/versions/node/v14.17.0/lib/node_modules/chalet/lib/daemon/group.js:249:23)
    at Monitor.emit (events.js:388:22)
    at ChildProcess.<anonymous> (/home/k1ng/.nvm/versions/node/v14.17.0/lib/node_modules/chalet/node_modules/respawn/index.js:164:12)
    at ChildProcess.emit (events.js:376:20)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
    at onErrorNT (internal/child_process.js:467:16)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  code: 'ERR_INVALID_ARG_TYPE'
}

Issue with Node v17

Hi,

I upgrade node locally yesterday and seems theres an issue with proxying (maybe) on node 17.

I downgraded to node 16 and its working fine again.

This issue is so if anyone else comes along and is seeing the Chalet error page when proxying.

FYI - the localhost connection was working fine. It was the proxying to the .test domain that was failing.

Cheers
Lee

Bug: `run` command removes saved servers (without --force)

If there is already a saved server config for myapp, and a user runs the run command for another server named myapp, chalet will correctly report the name conflict:

Configuration already exists with name 'fp2' (use -f to force creation)

However, it then proceeds to run the specified command anyway, and when that command exits, it proceeds to remove the config file for the previously saved myapp server — thereby removing the myapp server from chalet.

This result is very destructive and unexpected — especially since chalet is already detecting the name collision. A previously saved server should never be modified or removed by the run command unless the --force option is given.

Even worse, this can happen even if the run command does not specify a -n/--name option — because it will use the current directory name as the default server name and will proceed to remove any saved server matching that name.

Unless the --force option is given, then there currently is no clean way to run a server (specified or derived from cwd) with the same name as an existing server, since the run command currently works by writing to a temporary config file (and thus would overwrite the existing server's config file). Therefore, if such a name collision is detected, then the run command should display the name-collision error message (as shown above) and then exit immediately.

What would cause chalet to show a server as off?

I tried adding colima to chalet (added the command colima start.

When I turn it on, it starts the process and looks normal, but the switch shows it as "off".

Is it because something is getting forked or switching pids or something? or could it be a simpler explanation?

Thanks

Trouble getting chalet to work with svelte-kit/vite

Trying to figure out how to get a svelte-kit app (https://kit.svelte.dev) working in chalet. I can get the app running, but it keeps reloading. Svelte-kit apps use vite (https://vitejs.dev) for hot-module-reloading in development, and vite is trying to connect to wss://my-app.localhost:3000 and failing, so it tries reloading, infinitely. Not sure how to get this working so that chalet will forward those web socket connections through to the vite server. Here's my app config:

{
  "cwd": "/Users/pascal/Projects/my-svelte-app",
  "cmd": "npm run dev",
  "xfwd": true,
  "out": "app.log",
  "env": {
    "PATH": "[omitted]",
    "PORT": 3000
  }
}

I have self-signed SSL working, so the app loads at https://my-app.localhost, but it can't reach wss:my-app.localhost:3000

Will keep trying and report what I find but if anyone has any guidance I'd appreciate it.

Team shared servers config

Thank you for keeping this alive @jeansaad. It's hard to find some nice GUI for development on Windows.

I understand the utility is meant to be used locally, but there is also a nice opportunity to set up a dev environment for a new team member. They could simply configure their chalet to use servers from a folder that's versioned in the VCS.

Probably the easiest approach would be to add a configuration option with a list of additional folders with servers and it merges it all together. I could work on the PR if you think this is a good idea.

Maybe there is a viable approach through Docker, but I am mostly a front-end guy, so I am not sure.

Prevent Sites Autostart on domain visit

First, thanks for maintaining this tool. Been using hotel for years and your battle against code rot is very much appreciated.

I expose my chalet setup via a reverse proxy, so clients can see work in progress. However I sometimes find they've restarted their dev site just by going to the provided domain. I obviously want to keep my dev machine running as few sites as possible, so it'd be good to disable this behaviour.

Is this something you would implement, or accept a pull request for? (unless this is already possible, but I missed it from the docs).

Thanks.

Monitors not starting with node 18

I'm working on a project and when updating to node 18 the monitors no longer seems to start correctly and its logs are not appearing to show correctly. Has anyone else run into this problem?

.localhost domains do not work on Windows

The TLDs do not work on Windows. localhost:2000/app works but app.localhost does not. I have setup the proxy according to the instructions.
image

I have restarted my browser and tried different browsers.

Feature Request: Reuse random port number when using `run` command

The chalet CLI has a run command, which sets up and runs a temporary server, outputs the server's logs to STDOUT, and removes the server config (to clean up) when the server process has stopped.

However, if I need to stop the server and restart it for some reason, then it will run under a different port number the second time (typically the next number in some sequence). If I switch to the browser tab where I had loaded the app in its first run, it will have the first port number in its URL, but that port number is no longer being used — therefore reloading that tab will fail with a server-not-found error.

It would be great if the chalet daemon would remember servers previously run and their assigned port numbers, so that if another server is run with the same name, the previously used port number could be reused. This could simply be an in-memory hash that would persist only while the chalet daemon is running. The run command would still clear the server's temporary config file when the run command exits, but just keep the port number in an entry for that server name in the daemon's memory.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.