bitwalker / distillery

Simplify deployments in Elixir with OTP releases!
MIT License
2.97k stars 398 forks source link

Improve Documentation #441

Open bitwalker opened 6 years ago

bitwalker commented 6 years ago

This issue is to track the work for improving the documentation:

I'm open to suggestions for other guides/topics we should cover or address. I would prefer if you check with me first before opening PRs for documentation, as I'm going to be doing a lot of moving around and rewriting up front, and I would hate to conflict with anything you may want to help contribute. If we talk it out first, I can make sure we don't step on each others toes :)

happysalada commented 6 years ago

I have written this guide on deploying with docker before. I'm thinking a lot can be re-used, since that's what I use to deploy to Digital Ocean. The only thing I couldn't solve was how to get the -heart option working to restart automatically in case of crash. Are you looking for something different in terms of docker/digital ocean documentation? Or is the direction generally good? Let me know.

bitwalker commented 6 years ago

@happysalada There is some information there that will need to be updated, but it's definitely a solid guide for Docker. If you are interested in making that part of the official documentation, a PR would be welcome! We can work through any modifications necessary to update it for 2.x, but they should be mostly minimal.

If you want to maintain that guide separately from Distillery's docs, I can write one up based on my own experience as well when I get some time.

The only thing I couldn't solve was how to get the -heart option working to restart automatically in case of crash.

In Docker you mean? That would always be doomed to fail, because if the VM crashes and heart restarts it, it will have a new pid - but regardless, the original command to start the VM would have exited on the original crash, so the container would die anyway. In a Docker environment you are better off letting the container die and have your orchestration layer deal with restarting it, I don't think heart is a good fit there - it is better suited for running a release as a daemon on a system with no supervision (i.e. without something like systemd or supervisord)

happysalada commented 6 years ago

If it's not urgent, I'll make a PR this weekend with a couple of questions, on things I wasn't so sure of. I don't mind having the information here, as I think it will help a lot more people!

The way I am currently handling things on DO, is with docker-compose. I have added a systemctl primitive to restart the docker-compose process in case it crashes. However the problem is, when the VM crashes, the docker-compose process is still fine, and so the VM doesn't get restarted. (maybe it's just a matter of adding a restart: always in my docker-compose file)

I'll put everything I know and the problems I have encountered with my approach in a PR and we can take it from there.

(PS: I am know researching Kubernetes, that will clearly take me some time before being fluent enough to write a guide, but it would be a good addition to the docs if there was a kubernetes part as well. Even though, I agree that beyond distillery is just used in the docker image, and beyond that it's just kubernetes stuff)

Thanks for a great package!

bitwalker commented 6 years ago

While docker-compose works fine for small projects, it's really intended to be a development tool, not a orchestration tool for production (in my opinion). Using restart: on_failure or restart: always would probably address the issue you were having though. For a small setup on Digital Ocean though, you may want to consider running Docker Swarm on a host, it's pretty easy to get going from what I've heard, and is significantly less complex than Kubernetes, and I believe builds on the compose file stuff for defining builds/deploys. Swarm is an actual orchestrator, and would be more flexible for this kind of thing.

Generally if I was trying to run with as little stuff as possible, and still use Docker, I'd write systemd service units which build on docker run, and rely on systemd to make sure dependencies are started in the correct order, that they are available, that logs are aggregated, and that services are restarted when necessary. You get a lot of nice tooling for free in this setup, but it does require that you are running on a host with systemd (which is typically the case these days, but not always).

I prefer Kubernetes personally, but that's because I'm typically working in environments with many applications, with different languages and requirements, and managing them with one set of operational tools is worth the additional complexity, initial effort to set up, and ongoing maintenance - the alternative is usually just a different type of complexity and effort; better the beast you know, as the saying goes. I think a simple getting started guide for k8s would be good to have, as an educational tool; but I think in general real-world deployments are going to be handled by someone on the team who is very comfortable with k8s already; most ops teams are not going to have engineering defining k8s resources themselves. For those rare cases where ops and engineering are the same people, the k8s side of things is unlikely to be the part they are needing help with (I hope). In either case, I want a simple getting started guide for all of the common environments, to help people not only get comfortable with Distillery and releases (deploying Elixir in general), but to help people get comfortable with some typical operations tasks too, as it helps illuminate the reasons why some of these tools work the way they do.

saulecabrera commented 6 years ago

@bitwalker As discussed offline and after going over the latest docs, I'm dropping a proposal for the first point of this issue:

Split up guides/pages on topics to provide softer introductions with specific pages for more detailed content

I added in bold the sections that will be affected by this proposal and also a small rationale/description of the changes.

INTRODUCTION

This section ideally will encapsulate everything that's release theory oriented. Basically everything that serves as a pre-requisite to understand releases in practice.

Proposed changes in this section:

GUIDES

This section will ideally encapsulate everything that has a hands-on approach, where how to's and code snippets are shown.

Proposed changes in this section:

EXTENSIBILITY

Proposed changes to this section:

CONFIGURATION No changes

OTHER

Proposed changed to this section:

TROUBLESHOOTING

Proposed changes to this section

Let me know how do you feel about this and if anything seems out of place.

Also do you think it will make sense to separate this issue into smaller chunks? Even though all the points are related to the documentation, they might yield different mixed discussions which in the end might be harder to keep track of.

bitwalker commented 6 years ago

My thoughts:

Thoughts @saulecabrera?

happysalada commented 6 years ago

One potential improvement also would be to have a section on NIFs. There is a great project to make NIFs in rust. It works great with mix, unfortunately there is a weird bug when trying to make a release out of it. I'd be happy to try to write a draft if pointed in the right direction. Perhaps this doesn't belong here? Not sure.

bitwalker commented 6 years ago

@happysalada Definitely, it's a section that does need some treatment, unfortunately it's been pretty low on the priority list. I'd certainly welcome PRs in that direction though.

saulecabrera commented 6 years ago

@bitwalker

I think vm.args should probably be mentioned there, but have it's main document alongside the other runtime configuration documents (in the top-level Configuration section), since it's more likely to be looked for there than in the introductory content.

+1 on this I think that a reference to vm args in this section will be enough; in this section mentioning vm.args might be just a way to make people aware that it exists without deep diving, and we could definitely have it in the top level Configuration section instead of the current Files section.

I'm +1 on renaming "Plugins" to "Extensibility", but I want to keep Custom Commands in that section, because that is one of the main extension points. A better "guide" which covers custom commands is dealing with migrations, which is a guide.

I agree on this point, after giving both sections a second look I can understand the difference in their approach.

Rather than merging Walkthrough and Phoenix Walkthrough (the latter is intended as a guide, while the former is meant to be a first introduction for building a release and deploying it end-to-end, in a simpler format); I'd identify how best to keep the initial Walkthrough simple and good introductory content which gives someone new to releases a good idea of how the deployment process works.

Agreed. I think that most of my confusion came due to:

In any case I feel that the approach you mentioned of curating the Walkthrough to be as simple and straightforward as possible and focusing on strengthening the Phoenix guide to highlight how things are done different will help mitigate any confusion.

I can start putting up a PR for all the items that we've discussed :)

jlgeering commented 6 years ago

While not 100% related to this discussion about the documentation, I'd like to mention #466 which is about adding a changelog page to the generated documentation (amongst other changelog related changes).

For now it appears at the top, together with "API Reference", because I haven't included it in a group. But maybe I should include it in "Other"?

Doerge commented 6 years ago

I'm a first time user of Distillery (and sub-1-year-new to Phoenix/Elixir as well) and the Phoenix + Docker guide worked great for me!

I'm not sure where to put this feedback, so pardon me if it's in a wrong location:

  1. I don't fully understand the relationship to Mix.config. It's mentioned that it's bad to mix (pun intended) runtime and compile time config in one file, but I don't fully grasp why? Is it purely from an organizational point of view, or is there some Erlang release voodoo which forbids it?
  2. I'm a little confused by some places using {:system, "FOO"} like here and others using System.get_env("BAR") like here to use runtime vars. Is there a difference?
  3. Priv/repo were not copied into the release for me. I created a copy overlay for it, but I think that should maybe be part of some guide on migrations/Phoenix as well? I've created a PR here
  4. Is there a way to debug the application config in it's entirety? Like IO.puts MyApplication.config to inspect the entire thing? I was at times unsure if my phoenix-mix-config files were used or not, and such a tip might have helped me.
  5. Following the guides I end up with 2 files: rel/config.exs and rel/config/config.exs. Would it make sense to rename the latter to config_runtime.exs or similar to distinguish them, and self document what goes where?
rarguelloF commented 5 years ago

Hello,

I'm having same questions as @Doerge regarding the runtime configuration section: https://github.com/bitwalker/distillery/issues/441#issuecomment-423818715

Specially the part in the docs saying:

You can copy configs straight from config/, but I would avoid doing so.

Could someone tell me what's the issue doing that? I like to avoid using extremely different configs between dev, test and prod in my apps. I prefer adding most of my config in config/config.exs (including runtime configuration) and keep dev.exs, test.exs and prod.exs for dependency injections, different defaults, etc.

The documentation suggests the following:

create a dedicated config which handles fetching runtime configuration only, and place it in rel/config

But that would make me repeat code from config/config.exs (and having to maintain it in two different places).

So, what's the issue with just copying config/config.exs? Am I missing something?

Thanks in advance!

RussellRamos commented 5 years ago

I just want tolearn.if you can use a dummy.smiles...