Open bitwalker opened 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.
@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)
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!
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.
@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.
My thoughts:
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.Thoughts @saulecabrera?
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.
@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.
@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 :)
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"?
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:
{:system, "FOO"}
like here and others using System.get_env("BAR")
like here to use runtime vars. Is there a difference?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.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?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!
I just want tolearn.if you can use a dummy.smiles...
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 :)