-
-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Shipping Apps section #377
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that this only shows publishing options using container tools. It suggests you need docker or snapcraft to run Crystal applications. That's far from the truth and somewhat deviates from the goal to compile to efficient native code when you need third party tools to execute that native code.
The very first step should be to demonstrate publishing a plain executable. For some applications, this is already fine and it doesn't need anything else. Docker or snapcraft would just be unnecessary overhead.
Only after discussing the problems that come with publishing a single executable, these tools should be mentioned as possible alternatives. But they're just two of many options and selecting which one to use depends on many factors which are far to complex for covering all of that. I'm pretty sure I most likely wouldn't chose either of the two demonstrated methods for publishing Crystal apps.
This seems far to narrow fetched to be an effective guide on shipping Crystal applications. It doesn't provide a comprehensive overview, but only two arbitrary and opinionated examples.
The guides for shipping with docker and shipping with snapcraft might be good by themselves, but not for filling a guides section in the language reference. I'd rather suggest to publish them as individual posts on the blog. And later they can be referenced from the language reference (or even integrated in a larger section).
|
||
## Compiling our application | ||
|
||
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal knows the target platform because is the same as the one being used to compile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal knows the target platform because is the same as the one being used to compile. | |
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal chooses the target platform by default as the same as the one being used to compile. |
## Compiling our application | ||
|
||
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal knows the target platform because is the same as the one being used to compile. | ||
For example, if we use a Linux OS based computer for compiling, then the executable will be meant to run on a Linux OS (and in some cases we will need to use the same Linux distribution). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and in some cases we will need to use the same Linux distribution)
- I'm not aware of any distribution-specific limitations. Do you have an example for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that without further setting up the environment the binary can't be dropped on any linux distro. We played safe maybe. But on different distros paths of libraries might change and would require the user to set LD_LIBRARY_PATH
before running the executable. I am not sure if on a plain Alpine any binary linked with glibc can run (Ref).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but that's not restricted by the distro, but the specific environment setup. You should be able to run a Linux executable on any Linux system (i.e. not needing to use the same distro), assuming the environment is configured appropriately.
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal knows the target platform because is the same as the one being used to compile. | ||
For example, if we use a Linux OS based computer for compiling, then the executable will be meant to run on a Linux OS (and in some cases we will need to use the same Linux distribution). | ||
|
||
Can we set the target when calling the compiler? Oh, that’s a great idea, but for now it’s not an option (there are a lot of great buccanears [working on a solution](https://forum.crystal-lang.org/t/cross-compiling-automatically-to-osx/1330/12) and remember that Crystal is open source: so you are welcome aboard!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section suggest you can't cross compile Crystal. That is very much possible, though.
Only linking the final executable is not covered for a cross-compile target.
I'd either rephrase this paragraph or maybe even remove it entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree to rephrase it. Cross compiling can be mention as something possible as long as you are aware of the difference between compiling, linking. But I would not aim for an explanation. At most that currently you would need a target environment to perform the linking.
Let’s compile our application: | ||
|
||
```shell-session | ||
$ shards build --production |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not about shards
, so it rather only use crystal build
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that shards create a nicer directory structure.
But either we show the shards.yml and the structure of the whole folder.
Or we use crystal build
(and update the samples below removing the bin
).
But since we are simulating a whole app, using shards makes sense to me. Otherwise, it feels we are not using our own tools.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@straight-shoota The top-level guide aims for an intro and to explain the underlying challenges of distributing a native binary. The audience is people with no background in compiling and linking. Someone with advanced knowledge can scan that and double-check his assumptions.
Maybe we could add a paragraph so the reader can seek for resources for building packages (deb/rpm/apk) that will solve the dependencies requirement.
But Docker and Snapcraft although more have than a plain binary have enough momentum to be included. If you build micro-services or web apps having a guide for Docker is good. Snapcraft is easier to pick up and deal for distributing applications. oq
for example was the first to choose to deliver a snap instead of a native package since it gives a lot of benefits with little burden.
There will always be a chance for things to improve and get better, but we want to offer at least one entry guide for how to complete the whole development cycle and don't send the users in the wild for the seek of answers.
Does this help to frame better the intention of this guide?
Audience: Crystal users with possible no compile/linking experience.
Goals: Intro to the challenges of distributing native apps. Offer a couple of simple solutions and suggest how to look for deeper/more advance information.
Non-Goals: Explain how linking works.
## Compiling our application | ||
|
||
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal knows the target platform because is the same as the one being used to compile. | ||
For example, if we use a Linux OS based computer for compiling, then the executable will be meant to run on a Linux OS (and in some cases we will need to use the same Linux distribution). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that without further setting up the environment the binary can't be dropped on any linux distro. We played safe maybe. But on different distros paths of libraries might change and would require the user to set LD_LIBRARY_PATH
before running the executable. I am not sure if on a plain Alpine any binary linked with glibc can run (Ref).
Let’s go over Crystal’s [introduction](https://crystal-lang.org/reference/). One of the main goals of the language is to _Compile to efficient native code_. That means that each time that we compile our code then an executable is built, but with an important property: it has a target platform (architecture and operating system), which is where the application will run. Crystal knows the target platform because is the same as the one being used to compile. | ||
For example, if we use a Linux OS based computer for compiling, then the executable will be meant to run on a Linux OS (and in some cases we will need to use the same Linux distribution). | ||
|
||
Can we set the target when calling the compiler? Oh, that’s a great idea, but for now it’s not an option (there are a lot of great buccanears [working on a solution](https://forum.crystal-lang.org/t/cross-compiling-automatically-to-osx/1330/12) and remember that Crystal is open source: so you are welcome aboard!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree to rephrase it. Cross compiling can be mention as something possible as long as you are aware of the difference between compiling, linking. But I would not aim for an explanation. At most that currently you would need a target environment to perform the linking.
Let’s compile our application: | ||
|
||
```shell-session | ||
$ shards build --production |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that shards create a nicer directory structure.
But either we show the shards.yml and the structure of the whole folder.
Or we use crystal build
(and update the samples below removing the bin
).
But since we are simulating a whole app, using shards makes sense to me. Otherwise, it feels we are not using our own tools.
I think I already understood the intention before, but I still think we should not have a shipping guide that's only about two arbitrary shipping methods.
I'm not doubting that they can't be included, I'm just saying they shouldn't be the first and only options to be mentioned. They're still useful guides, that's why I suggested to publish them on the blog for now.
That's good. But when we start a section about shipping apps, it should not consist of only two arbitrary options for a similar mechanism. |
The description in the top-level aims to describe the needs. Even if we add some other distribution method it will still be arbitrary N methods to me, and there needs to be a start.
What other content you think is a minimum requirement to add a shipping section? |
The main issue I have is that these particular examples suggest that Crystal applications can only be shipped containerized. And that's far from the truth. So the minimum required alternatives are basic, non-containerized shipping methods like shipping a single binary, covering both dynamically linked and statically linked examples. For many applications, including the example static file server, shipping a statically linked binary should work pretty well without much hassle. You don't need to reach for complex containerization tools for that. |
I am happy to include a couple of paragraphs in the main file to mitigate the confusion you suggest and explain there are lots of other possibilities. My main experience is using the approaches included in this PR: Docker & snapcraft. But further complete guides can be written added once these are in place. Talking about specific additional guides:
The efforts are to help the user discover the current possibilities. Not to develop something and write a short guide about it. |
How about showing how to produce a basic binary, then talk about static vs dynamic linking and the problems you have with shipping the binary, mention musl and alpine as an ideal option but it's not ready yet, then go into snap/docker. |
with using docker and using snapcraft subsections