TheLartians / ModernCppStarter

🚀 Kick-start your C++! A template for modern C++ projects using CMake, CI, code coverage, clang-format, reproducible dependency management and much more.
https://thelartians.github.io/ModernCppStarter
The Unlicense
4.45k stars 388 forks source link

Implemented Docker and Docker Compose support #63

Closed leozz37 closed 2 years ago

leozz37 commented 4 years ago

Docker Support

Implemented support to build, running, and testing with Docker containers and docker-compose.

All instructions are included in README.md.

leozz37 commented 4 years ago

Btw I have some plans to create a Docker workflow, and let the GCC and CMake version up to the user to decide.

Maybe create a deploy image, with a smaller size and non-root user.

TheLartians commented 4 years ago

Hey, thanks for the PR, I see how adding Docker support can simplify deployment!

However, I wonder if it's such a common use case for new C++ projects to be worth maintaining in the starter project. Another thing is that running and building in the Docker container should be tested in CI.

Also, for building, running and testing with a pre-defined environment, we already use GitHub Workflows, which can be run locally as well.

leozz37 commented 4 years ago

Hey, I just implemented a GitHub Actions workflow for Docker, for building and running the Docker container!

A common use case for C++ is uploading an image to Docker Hub when sharing it, since setting up third-party libraries can be a headache. Also for deploying to cloud services like ECS and Cloud Run.

omertarikkoc commented 3 years ago

Docker support would be great!

TheLartians commented 3 years ago

Also we should add

- Built-in [Docker support](#docker)

to the # Features section.

TheLartians commented 3 years ago

I wonder if it would make sense to copy / install the executables and remove the source and build directories after building in the container? Especially if there are a lot of external dependencies this could dramatically reduce the size of the final image. Or am I missing the use-case for Docker here?

leozz37 commented 3 years ago

I wonder if it would make sense to copy / install the executables and remove the source and build directories after building in the container? Especially if there are a lot of external dependencies this could dramatically reduce the size of the final image. Or am I missing the use-case for Docker here?

Yeah is possible and it's considered a good practice. We will lose the ability to run the unit tests from an outside command, but we can run the tests in the build phase instead.

TheLartians commented 3 years ago

I think it's a good idea to get the Docker template as production ready as possible, including removing build artificers and unneeded resources as it's something most users would probably want / expect from the template. Running the unit tests in the build phase also makes perfect sense to me here.

PolarYair commented 3 years ago

Hello, let me add that the best practices for doing a Dockerfile for a C++ Docker image would follow a multi-stage build: The first image is used to build the binary, and the second Docker container will not contain source code and will not have any of the development tools. It should have the bare minimum that would enable running the binary.

leozz37 commented 3 years ago

If we're using multi-staged builds, we must have static libraries linking instead of dynamic. An alternative is what @PolarYair said, we can have two docker images: a base image with all its dependencies and one with just the binary, using the first one as the base image.

TheLartians commented 3 years ago

I actually don't think static linking is required. We could run cmake --build build --target install after building with a custom CMAKE_INSTALL_PREFIX directory to have CMake install all dependencies and executables into a single target directory. We could then copy the full install directory to the new image. This has the additional advantage that any executables and resources added to CMake will also be available in the target image, provided we set $PATH accordingly.

atomheartother commented 3 years ago

Hello folks, it looks like this has been abandoned. I happen to think Docker integration would be awesome to have in the starter, would anyone mind me forking this PR and giving a shot at implementing the changes suggested above?

My main problem is as far as I can see this PR suggests no solution to the problem of how to clone git repositories from within docker, does it? At least this Dockerfile fails on my projects. Nevermind, I was thinking of cloning with ssh, cloning with https works fine.