98

could someone give me a hint, howto serve the current directory from command line with ruby? it would be great, if i can have some system wide configuration (e.g. mime-types) and simply launch it from every directory.

Sebastian
  • 1,253
  • 1
  • 10
  • 11

8 Answers8

209

Simplest way possible (thanks Aaron Patterson/n0kada):

ruby -run -e httpd . -p 9090

Alternate, more complex way:

ruby -r webrick -e "s = WEBrick::HTTPServer.new(:Port => 9090, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start"

Even the first command is hard to remember, so I just have this in my .bashrc:

function serve {
  port="${1:-3000}"
  ruby -run -e httpd . -p $port
}

It serves the current directory on port 3000 by default, but you can also specify the port:

~ $ cd tmp
~/tmp $ serve      # ~/tmp served on port 3000
~/tmp $ cd ../www
~/www $ serve 5000   # ~/www served on port 5000
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Daniel Perez Alvarez
  • 6,570
  • 5
  • 28
  • 27
  • If you're on windows, is it possible to add this to cmd or powershell as a function? – Caleb Apr 25 '13 at 20:15
  • @Daniel - when I run your one liner on my Mac. I got this error message: uninitialized constant INT (NameError). Are you running it on a different platform? Do you know how I can avoid this? But if I write it into a file say myserver.rb then do "ruby myserver.rb", it works fine. – Tony Jiang Aug 23 '13 at 00:23
  • @TonyJiang I'm also running on a Mac. Tried it with Ruby 1.8.7, 1.9.3 and 2.0.0, and they all work. Weird. – Daniel Perez Alvarez Sep 09 '13 at 09:04
  • 7
    To demistify `ruby -run -e httpd . -p 9090` look at http://ruby-doc.org/stdlib-2.0.0/libdoc/un/rdoc/index.html. It's executing httpd method from `un` ruby standard library, thus require un. – Gee-Bee Sep 03 '14 at 09:45
  • I wrote up a deeper explanation that might be of interest: http://www.benjaminoakes.com/2013/09/13/ruby-simple-http-server-minimalist-rake/ – Benjamin Oakes Dec 11 '14 at 19:14
  • His bash function is not to be confused with the `serve` gem which will serve the current directory but also render ERB, HAML, etc. http://get-serve.com/ – Rob Cameron Feb 04 '15 at 18:38
  • What interface does this bind to? – nurettin Jun 05 '15 at 04:35
  • Hey, I know this it's been a long time since this, but asking in case anybody knows. How would you leave this running in the background? Any special flag for it? – LasagnaAndroid Nov 01 '15 at 08:55
  • 1
    @Deviljho if you are running on Mac or Linux, just add an ampersand at the end of the command to send it to the background: `ruby -run -e httpd . -p 9090 &` If you want to bring it back to the foreground, use `fg`. – Daniel Perez Alvarez Nov 02 '15 at 09:42
  • Cool thanks!, a small question, how do you know this? – LasagnaAndroid Nov 03 '15 at 10:14
  • @Deviljho They are standard UNIX process management operations. – Daniel Perez Alvarez Nov 04 '15 at 11:40
24

As Aaron Patterson tweeted it out today you can do:

ruby -run -e httpd . -p 5000

And you can set the bind address as well by adding -b 127.0.0.1

Works with Ruby 1.9.2 and greater.

KARASZI István
  • 30,900
  • 8
  • 101
  • 128
23

I've never seen anything as compact as

python3 -m http.server

You can optionally add a port number to the end:

python3 -m http.server 9000

See https://docs.python.org/library/http.server.html

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Michael Kohl
  • 66,324
  • 14
  • 138
  • 158
  • There is a list of pretty compact solutions here: https://gist.github.com/willurd/5720255 :) – Felix Aug 03 '17 at 06:20
5

Use ruby gem Serve.

To install on your system, run gem install serve.

To serve a directory, simply cd to the directory and run serve.

Default port is 4000. It can also serve things like ERB, HAML, Slim and SASS.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
danini
  • 365
  • 5
  • 9
5
require 'webrick'
include WEBrick

s = HTTPServer.new(:Port => 9090,  :DocumentRoot => Dir::pwd)
trap("INT"){ s.shutdown }
s.start
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
3

Web Server in 1 line


This may or may not be quite what you want but it's so cool that I just had to share it.

I've used this in the past to serve the file system. Perhaps you could modify it or just accept that it serves everything.

ruby -rsocket -e 's=TCPServer.new(5**5);loop{_=s.accept;_<<"HTTP/1.0 200 OK\r\n\r\n#{File.read(_.gets.split[1])rescue nil}";_.close}'

I found it here

Chris

Chris McCauley
  • 25,824
  • 8
  • 48
  • 65
3

You can use the sinatra gem, though it doesn't do any directory listing for you, it serves files:

require 'sinatra' # gem
set :public_folder, '.'

then run that as a file, if in 1.8 add require 'rubygems' to the top first.

After running it then url's like

http://localhost:4567/file_name

should resolve to "./file_name" file.

http://localhost:4567 won't work however, since it doesn't "do" directory listings. See https://stackoverflow.com/a/12115019/32453 for a workaround there.

Community
  • 1
  • 1
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
1
python3 -m http.server

or if you don't want to use the default port 8000

python3 -m http.server 3333

or if you want to allow connections from localhost only

python3 -m http.server --bind 127.0.0.1

See the docs.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103