
Show HN: Easy Webserver for Node.js, Python, PHP, with Free SSL - kasra85
https://github.com/githubsaturn/captainduckduck/blob/master/README.md
======
joepie91_
I'm surprised that Caddy
([https://caddyserver.com/](https://caddyserver.com/)) hasn't been mentioned
yet. While I'm not entirely happy with the business direction it's been moving
in, it's arguably much easier to use than nginx, doesn't require a container,
and also automatically sets up TLS ("SSL") out of the box.

It doesn't provide a panel, but arguably once you reach a scale where you want
to run >1 instances, you're probably going to want to go beyond a default
configuration anyway, and use some configuration that's more tailored towards
your usecase.

As a point of criticism towards this project in particular: the README makes
it sound like it'll magically scale up your application, but it makes
absolutely no mention of how to handle state (eg. your database) in that
scenario. Spawning new instances (which this project does) is the _easy_ part
of scaling, the difficult part is state management and it doesn't address that
at all.

As a completely unrelated piece of advice, just because this is mentioned in
the README: _do not_ under any circumstances make use of domain registration
deals that drop the price for a common TLD like .com below $7 or so. There's a
certain fee that the registrar has to pay to the TLD registry per domain, and
if the registrar is charging you less than that, that means they're getting
the money from somewhere else - often through hidden upsells, exorbitant
renewal fees, convoluted transfer systems that try to lock you in, or other
customer-hostile schemes.

~~~
kasra85
Thanks for your detailed review.

Caddy is a server which is equivalent of nginx part in Captain. It's orange
and apple. Arguably, I can replace the nginx part with Caddy. But captain has
more to offer, like building pipeline and scaling.

Great point about customization! I'll add more hooks in the future to account
for non-standard nginx configurations.

Finally, Captain doesn't support persistent data, i.e. database. Therefore,
scaling up apps is much easier. But my plan is to support this in the future.

PS: Thanks for the heads up about the domain deals. I might have got scammed
badly then :/

~~~
joepie91_
> Caddy is a server which is equivalent of nginx part in Captain. It's orange
> and apple. Arguably, I can replace the nginx part with Caddy. But captain
> has more to offer, like building pipeline and scaling.

The problem is that these aren't generalizable problems. Scaling requirements
are going to vary depending on the project, also because of the state
management issue I mentioned. This, in turn, means that the only projects you
can scale with an out-of-the-box approach like this, are those that don't
_need_ to scale (horizontally) in the first place. You therefore get little to
no added real-world value from these 'scaling' features.

I should point out that this isn't a problem just with your project; I've
noticed a general tendency around Hacker News circles to overengineer for
'scaling' (which usually refers specifically to _horizontal_ scaling), trying
to invent magic scaling solutions that work for everybody (which don't exist),
and completely ignoring that distributed systems are _hard_ and you usually
want to scale vertically first.

This problem is compounded by the fact that most applications don't actually
_need_ to scale horizontally, since they never get big enough to require it.
This means that reviews of such 'magical scaling' tools are almost universally
positive, because everybody is reviewing them based on the claimed benefits,
not based on real-world experience with scaling requirements. This results in
a feedback loop of recommendations for completely ineffective scaling
strategies by people who never actually needed them.

> Great point about customization! I'll add more hooks in the future to
> account for non-standard nginx configurations.

While this would seem to improve the project when viewed in isolation, it's
important to realize that you're very likely to fall into the trap of non-
generalizable problems.

A lot of monolithic frameworks actually have this issue; they try to provide
generic implementations for problems that just aren't generalizable (because
they vary too much by project, such as "content management"), and in the
process they end up providing hundreds or thousands of different configuration
options and hooks... to a point of complexity where it would've been easier
and more reliable to just not use the framework at all. A typical example of
this are general-purpose CMSes, which are almost inevitably unreliable, messy
and insecure.

There's a serious risk of that happening here as well, if you start adding
support for more customized setups; at some point, you're going to reach the
stage where the complexity of your configuration options _exceeds_ that of the
tools you're using behind the scenes (nginx, Docker, etc.). I suppose that'd
be a form of the inner-platform effect, too.

I don't mean to discourage you here, but your current approach is very likely
to result in something that tries to do a lot of things and none of them
particularly well; not because you're implementing it wrong, but because this
particular set of features just isn't generalizable as such. You'd probably
get better results by providing a _collection_ of tools (and documentation!)
for different tasks, that 1) can be used independently, and 2) don't require
full control over the infrastructure configuration.

> Finally, Captain doesn't support persistent data, i.e. database. Therefore,
> scaling up apps is much easier.

I don't agree that "scaling up apps is much easier" \- state isn't something
that's optional, pretty much any real-world project (especially those that
have to scale beyond one instance!) _has_ to persist state of some sort.
There's only the choice of whether the tooling supports it, or doesn't. I'd
consider it dangerous to present something as magically scalable without
addressing this issue; it's bound to result in people having state consistency
issues.

------
photonios
I like the idea. It’s great that it makes deploying small side projects
easier. However, I am very wary of the fact that it seems to use a Node based
HTTP server. Wouldn’t it be far more performant and secure to build this kind
of tooling on a wide spread HTTP server such as Nginx or Apache?

Don’t get me wrong. I don’t have anything against Node. Hell, I use it on a
daily basis. But I wouldn’t run a Node based server and expose it to the
internet. That’s a bit too high risk for me.

~~~
kasra85
It's using nginx for routing :) nodejs is just an API to populate nginx
configuration, creating new apps and other admin operations. When a request
comes in for your app, the nodejs part is completely out of the equation. You
can potentially kill the nodejs part and your cluster still work. You just
won't be able to deploy apps, and make modifications. \----- Good point
though! I never thought it will be preceived that way.

~~~
photonios
My apologies, I didn’t look closely enough to figure that out. Forgive my
ignorance :-)

Well done then!

------
joosters
Why doesn't the installation prompt you to set up a password? Firing up a
server with a default password has been a really bad choice for over a
decade...

~~~
kasra85
Ah. Forgot to add it to docs. Thanks for reminding. I'll add it :)

------
waytogo
Wondering how this container with the included Letsencrypt will update the SSL
cert after three months when deployed on multiple machines (which is a tricky
task).

~~~
kasra85
Great question! Nginx, Let's Encrypt and Captain always sit on the leader node
:)

~~~
waytogo
1\. I don't use Nginx on my Docker clusters because Docker Swarm does the load
balancing already and I use bare Node containers without any Nginx. Reduces
complexity and I can do all my low-level server config in Node as well and as
good. Caching is done through CloudFlare or similar anyways.

2\. Even with Nginx, you would have two different Docker containers (one with
Nginx and one without).

3\. And even if I had different container files: For a ideal cluster you need
min. 3 managers (and in a perfect world another external load balancer before
them or just a DNS with multiple A records to all managers (in case one
manager drops)). Then, even if they run Nginx you need to sync the Letsencrypt
stuff somehow.

Regarding the Letsencrypt (LE) and Certbot SSL renewal and why it's not
simple: LE makes a know-well request to check your credentials every three
months and because every node could and should be able to answer this request
you have to make sure that all nodes have the same knowledge (either through
secrets or through filesync or the underlying host OS of the front-facing
server takes care of this).

------
antihero
Honestly the writing style of the readme really doesn't inspire confidence,
and "easy" seems like a really bad metric to measure how good something that
should be performant, reliable and secure.

~~~
brianzelip
As someone with limited dev experience, I actually appreciated the writing
style. Especially the inclusion of meta support in the Need More Help
section[0].

[0]
[https://github.com/githubsaturn/captainduckduck/blob/master/...](https://github.com/githubsaturn/captainduckduck/blob/master/README.md#need-
more-help)

~~~
kasra85
This was actually the very sole purpose of this project. There are numerous
similar products out there. Oh god, it took me hours and maybe days to learn
them. So I made Captain for people how do not need super advance configs, to
be able to deploy apps easily.

I am so glad that someone actually found it useful :)

------
kasra85
Moved to Show HN: I opened sourced the platform that I made to serve my
personal side projects. It's basically an open source version of Heroku.
Similar to Dokku, except it comes with Free SSL certificate support, clusing
support, web interface and etc. Let me know what you think :)

~~~
vittore
So more like flynn and deis?

------
skrebbel
I didn't dive deep, but I like how this is _some_ batteries included, and is
tailored to web apps and nothing else.

It makes me think of how webpack won the builder/packer battle against gulp
and grunt by assuming you're building a _web_ app, and want typical web stuff.

Just like you _could_ use gulp to build a C++ app but nearly everybody uses it
for the web, you _could_ use Docker for hosting an IRC server but nearly
everybody uses it for the web.

~~~
joepie91_
> It makes me think of how webpack won the builder/packer battle against gulp
> and grunt by assuming you're building a web app, and want typical web stuff.

But... it didn't. Webpack and Gulp/Grunt aren't even the same _category_ of
tool; on a real-world project, you're exceedingly likely to use a build runner
like Gulp/Grunt _with_ Webpack (or Browserify).

Webpack is fundamentally a module bundler for non-CommonJS environments; it's
not a general-purpose build tool, and isn't really suitable for glueing
together any tools that don't directly relate to your browser-targeted bundle.
In some projects that's all you need, but that doesn't mean it has somehow
"won" from generic build tools - it just tries to solve a different problem.

~~~
skrebbel
Using gulp with webpack means you can't use webpack incremental builds. Why
would anyone want that?

~~~
joepie91_
Why can't you? Gulp would typically only be responsible for _starting_ the
Webpack task (in watch mode), not for re-running it on every input change.

------
superasn
After seeing the whole video I can see a lot of effort has been put into
creating this. Great work, very useful for web development.

~~~
kasra85
Thanks a lot :)

------
ignorantmonitor
I almost missed the part about it being GUI because I rarely play youtube
videos. I did not expect it being a GUI tool! Nice!

A small suggestion - maybe show a GIF with a few screens from the app instead
of a video? So that when someone opens the repo he gets a little preview of
whats inside?

~~~
kasra85
This is a great suggestion! Thanks!

------
turtlebits
Not a fan of so much GUI interaction, but very nice.

If you want to the slightly harder way (with less moving pieces), I highly
recommend docker-compose + traefik (does the LE and proxying and subdomain)
and a learning how to create a simple dockerfile either of the languages.

------
arkkh
Great job, looks cool!

How does it compare with UCP ?

[https://docs.docker.com/datacenter/ucp/2.2/guides/](https://docs.docker.com/datacenter/ucp/2.2/guides/)

~~~
kasra85
Thanks a lot :)

Captain to UCP is like a Honda Civic to a Ferrari :P Surely I would use UCP
for an Enterprise grade if i have the money for learning investment,
management and all the "enterprisy" cost that comes with it. Captain is
written by a one bored guy on weekends in 3 months. UCP is written by a solid
Enterprise.

~~~
arkkh
I see! I would also add that UCP isn't OSS (one of the only commercial
products of Docker).

------
stephenr
Edit: turns out it's just a little harder to find.

Original text: I'm not the target market at all, but it's hard to trust a
project that relies on Docker but doesn't have the Docker configuration in the
repo.

~~~
kasra85
If by Docker configuration, you mean dockerfile, it's here:
[https://github.com/githubsaturn/captainduckduck/blob/master/...](https://github.com/githubsaturn/captainduckduck/blob/master/app-
backend/dockerfile-captain.release)

------
z3ugma
This is great - you write with accessible and encouraging language. I noticed
a lot of typos in the demo app and in the README - you would be well-served
getting a proofreader to polish it up.

------
ReverseCold
I've used something similar before, gave up on it. I just use Nginx manually
now, so much more room for customization, plus I know where everything is
because I set it up.

------
vincelt
This seems great, will definitely give it a shot. One question: what about
databases ? Can it handle that part too or do I have to manually set them up ?

~~~
kasra85
No :( It doesn't support persistent data yet. My plan is to add that support
in future if people need it.

------
tmikaeld
I love the effort here, I didn't expect the Web GUI here and it really saves a
ton of time to quickly setup a test environment!

Will you also add a database?

~~~
kasra85
Database, in general persistent data, is much trickier to add as container for
production purposes. I'll add some experimental features soon to support
databases at least for testing.

------
52-6F-62
I think everybody else has tackled it well so far -- so before I dive in for a
better look:

Great job on the name!

