-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add an official dockerfile #887
Conversation
Adds support for custom process classes in the docker image. Makes the scripts more robust against some variations in the environment.
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 apologize for the slow review.
I am all for any amount of incremental progress in this area, and having a docker image available for local testing sounds like a great improvement. #355 seemed to have a broader goal of supplying a docker image that could be used to run FDB in "production". Did you have a solid enough understanding of #355 to be able to describe what features existed in that PR that aren't present in this one (if any)? Is there any plan as to what will or will not be supported?
packaging/docker/Dockerfile
Outdated
RUN chmod u+x fdb* | ||
RUN mv fdb* /usr/bin | ||
WORKDIR /var/fdb | ||
RUN rm -r tmp |
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.
Are these sorts of chains of commands supposed to be in one RUN line and chained with && ? I honestly don't understand dockerfile best practices.
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.
Yes. That's the case because every RUN or any other command creates a new layer, which usually results in bigger overall image size. Just to illustrate:
...
ADD $FDB_WEBSITE/downloads/$FDB_VERSION/linux/fdb_$FDB_VERSION.tar.gz .
RUN tar -xzf fdb_$FDB_VERSION.tar.gz --strip-components=1
RUN rm fdb_$FDB_VERSION.tar.gz
RUN chmod u+x fdb*
RUN mv fdb* /usr/bin
WORKDIR /var/fdb
RUN rm -r tmp
...
Every line creates a new layer, meaning that even if have done rm fdb_$FDB_VERSION.tar.gz
and rm -r tmp
, the intermediate layers would still keep this files. This is effectively just a junk, because no one can access this file in the final image. Hence it's recommended to produce fewer number of layers by chaining commands:
RUN wget $FDB_WEBSITE/downloads/$FDB_VERSION/linux/fdb_$FDB_VERSION.tar.gz \
&& tar -xzf fdb_$FDB_VERSION.tar.gz --strip-components=1 \
&& rm fdb_$FDB_VERSION.tar.gz \
&& chmod u+x fdb* \
&& mv fdb* /usr/bin \
&& cd /var/fdb \
&& rm -r tmp
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've restructured the dockerfile a bit to reduce the number of layers.
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'm also thinking that in a future enhancement we may want to use a multistage build and just copy the binaries and libraries from an earlier stage into the final stage to reduce layering.
packaging/docker/fdb.bash
Outdated
# limitations under the License. | ||
# | ||
|
||
source $(/var/fdb/scripts/create_server_environment.bash) |
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'm finding this a little weird for a couple reasons:
- The failure handling here seems a little questionable.
create_server_environment.bash
will fail by outputting an error message, and thenexit 1
. This line will then try to execute that error message and source it. create_server_environment.bash
has a lot more side-effects than things that I generally see used in this form.
I'd suggest outputting to stderr in your scripts, which should just be tacking on a 1>&2
to the end of your echo lines for error messages.
However, reading through the PR further, I see why you preferred to have them as separate files instead of a library of code to source, as then it's easy to copy a single script to re-use and run in the client. However, calling it as a process and not as a library means that the exit 1
doesn't kill the current process as well, as it probably should.
You can either solve this via running set -e
beforehand, which I've generally found to be brittle, or stealing a trick to be able to distinguish sourced vs directly run files, similar to python's if __name__ == '__main__'
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
so that you can use the scripts either as callable standalone, or source-able and callable as a function.
Does that seem any better to you?
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.
That makes sense. I've moved the cluster file creation logic into a function and redirected more outputs to standard error.
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.
Ah, I had actually meant this line though. I see that you've moved create_cluster_file
into a source-able function, but if /var/fdb/scripts/create_server_environment.bash
does exit 1
, we'll end up running source
, which errors, and then continue onto starting up fdbserver below. I think it'd be clearer if we could just exit here. Could you do the same transformation to create_server_environment
?
Add more copyright headers to the docker sample files. Make the cluster file creation logic in the docker image into a function.
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.
Tried out this branch to attempt some automation. Hope you don't mind the random comments.
packaging/docker/README.md
Outdated
|
||
The port that FoundationDB should bind to. The default is 4500. | ||
|
||
### FDB_NETWORKING |
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 seems to have changed from FDB_NETWORKING
to FDB_NETWORKING_MODE
.
### FDB_NETWORKING | |
### FDB_NETWORKING_MODE |
packaging/docker/README.md
Outdated
|
||
This directory provides a Docker image for running FoundationDB. | ||
|
||
The image in this directory is based on Ubuntu 18.0.4, but the commands and |
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.
Minor nitpick.
The image in this directory is based on Ubuntu 18.0.4, but the commands and | |
The image in this directory is based on Ubuntu 18.04, but the commands and |
public_ip=127.0.0.1 | ||
FDB_CLUSTER_FILE_CONTENTS="docker:docker@$public_ip:4500" | ||
elif [[ "$FDB_NETWORKING_MODE" == "container" ]]; then | ||
public_ip=$(grep `hostname` /etc/hosts | sed -e "s/\s *`hostname`.*//") |
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.
Should the FDB_CLUSTER_FILE_CONTENTS
be set here as well? I tried:
docker build . -t fdb:latest --build-arg FDB_VERSION=5.2.5
docker run -ti --rm -e "FDB_NETWORKING_MODE=container" -e "FDB_PORT=4500" fdb:latest
I got:
Starting FDB server on 172.17.0.2:4500
Invalid cluster file `/var/fdb/fdb.cluster': 2104 Connection string invalid
Error: Connection string invalid
Adding the FDB_CLUSTER_FILE_CONTENTS
line 32 in this elsif block seemed to make things better but I'm not too familiar with FDB to know if this should have been written out by default and should "just work" or my setup is just wrong.
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.
Yes, good catch! I think I was trying to accomplish this through the FDB_COORDINATOR option, but the DNS resolution wasn't working properly, so I've tweaked this to use FDB_CLUSTER_FILE_CONTENTS in both networking modes.
ARG FDB_WEBSITE=https://www.foundationdb.org | ||
|
||
WORKDIR /var/fdb/tmp | ||
RUN wget $FDB_WEBSITE/downloads/$FDB_VERSION/linux/fdb_$FDB_VERSION.tar.gz && \ |
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.
You may want to consider adding a SHA256 checksum check here. Adding another argument after line 31 like:
ARG FDB_VERSION_SHA256SUM
and then running the check in the RUN block on line 35.
RUN wget $FDB_WEBSITE/downloads/$FDB_VERSION/linux/fdb_$FDB_VERSION.tar.gz && \
echo "${FDB_VERSION_SHA256SUM} fdb_${FDB_VERSION}.tar.gz" > checksum && sha256sum -c checksum && \
tar -xzf fdb_$FDB_VERSION.tar.gz --strip-components=1 && \
Then running:
docker build . -t fdb:latest --build-arg FDB_VERSION=5.2.5 --build-arg FDB_VERSION_SHA256SUM=275b9f541590d145136061cee6427103b347e1ff0e851b6556671e46102c1ad9
Just a "maybe nice to have".
@brownleej Thanks so much for doing this! Do you think you'll have time this week to address the final review comments? |
I'd love to see that. |
…the docker image for the two different networking options. Fixes some inaccurate text in the docker image README.
…urceable function. Adds an explicit coordinator container in the docker-compose sample to support recent changes in the name generation in docker-compose. Bump a dependency version in the dockerfile. Improves handling of coordinator lookup failures in the docker scripts.
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.
Did you still want @AlvinMooreSr to approve, or are we good to merge?
This is very exciting! Will an image be released soon after merging as well? |
Not only an image, but if there were instructions on how to start a production-ready multi-node FoundationDB cluster with Docker, that would be great. Given the lack of an existing AMI/Cloudformation/Terraform set up, at least with this Docker image, a docker-compose, Docker Swarm, or Kubernetes example template could be set up. |
@jdotjdot There was an example of terraform scripts posted on the forums. |
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.
LGTM
@jdotjdot We're definitely interested in building out more examples on how you would run this image in production on something like Kubernetes. I'm hoping to be able to put something like that together this month; it will probably go along with more work on the image itself. |
Looking forward to it! |
Add an official dockerfile
We've had previous discussions and PRs about this, but I wanted to give it a fresh start. This image is taken from my local testing setup, and I think it is suitable for general testing use. I've tried to keep it pretty simple so that we can iterate on it and get it to something that we can commit to as a stable image.