brand-ing / study-group-finder

0 stars 0 forks source link

Development Environment w/ DevContainers #2

Open jjketten opened 20 hours ago

jjketten commented 20 hours ago

Here are the notes I have so far on this topic. The basic proposal atm is to use VSCode DevContainers w/ Docker Compose. Customizations should be able to be done locally (hopefully) and not get overwritten when we update the environment.

Stack

Probable stack -front end: react; JS -back end: springboot; java -DB: firebase; NoSQL

Containerizing/Declaring a Dev environment

Why?

Reproduceability & consistency. Avoiding the "works on my machine" issue. Configurations are portable as well as isolatable (i.e. with multiple different environments using different versions for testing purposes).

Why not?

Going too far in the wrong direction with containerization may cause interop issues and not give devs the flexibility they desire with their accessory toolchain and choices of extensions. As such, we want to avoid putting the whole environment in a container; instead, it may be better to leverage containers for things like dependencies.

What about a standard VM image?

A VM containing all the necessary dependencies and development tools could be specified. This simplifies the environment somewhat, but we need the flexibility to swap things in or out or do updates as needed. We can't just issue a new image every time our environment changes, especially because Devs might need to re-do their customizations every time, or they might simply not want to use that specific Operating System/ Distro.

Nix

NixOS is a Linux distro that has been gaining some traction in recent years. Nix (or Nixpkg) is a deterministic & "purely functional" package manager that NixOS is based on which has features such as atomic changes, rollbacks, package isolation & multiple versions, etc. It is focused on reproducibility and reliability.
The one feature that really shines in Nix/NixOS, however, is the declarative configuration model. This makes it possible to reproduce a complete system configuration just by sharing a configuration.nix file.

Needs more research: it may be possible to create a non-global instance of Nixpkg on any Linux distribution that contains just the dev environment dependencies we need. Updating this for everyone would hopefully be a as simple as a git pull. Possible solutions: -Throwaway development environments with Nix https://monospacedmonologues.com/2022/06/throwaway-development-environments-with-nix/ -Fast, Declarative, Reproducible and Composable Developer Environments using Nix https://devenv.sh/

Docker Compose is a tool for defining and running multi-container applications. It is the key to unlocking a streamlined and efficient development and deployment experience. Compose simplifies the control of your entire application stack, making it easy to manage services, networks, and volumes in a single, comprehensible YAML configuration file. Then, with a single command, you create and start all the services from your configuration file.

Docker Vs K8s

Kubernetes is often thought of as a competitor to docker. However, the use case and advantages may be slightly different. For instance, K8s has tools for deploying and scaling containers with clusters of nodes, load balancing, and self healing (reliability) that make it well suited for production environments. On the other hand, Docker Compose is used heavily for local environment development, testing, and CI/CD.

What’s the difference between Docker Compose and Kubernetes? The Ultimate Guide to Integration Testing With Docker-Compose and SQL Artifacts for testing or bug reproduction https://stackoverflow.com/questions/42479620/what-does-build-artifact-mean-in-the-context-of-a-dockerized-development-envir https://docs.docker.com/docker-hub/oci-artifacts/

Dev Containers

Devfile & devcontainer vs. Dockerfile & Docker-Compose

The Devfile/devcontainer system allows for adding an additional layer of development-specific configurations on top of container images. -IDE plugins, source code repositories, and commands that should be run in the development environment after its creation. -Port mappings & commands to run inside container after creation -Scripts

![[Pasted image 20240921130831.png | 300]]

VSCode dev containers ![[Pasted image 20240921134521.png]]

Devfiles

https://www.daytona.io/dotfiles/devfiles-development-containers-understanding-differences

Suppose developers are working on a project that is being developed using various IDEs or CDE platforms. In that case, Devfiles offer a consistent way to define development environments across all platforms. Suppose some developers use Visual Studio Code while others use JetBrains' IntelliJ IDEA. In that case, a single Devfile can ensure that all developers have similar development environments regardless of the IDE used. https://cloudomation.com/en/cloudomation-blog/devfile-and-devcontainer-as-standards-for-configuring-cloud-development-environments-cdes/

 Without IDE customisation, the added value of devfile and devcontainer is limited.

Big picture opinions

https://www.reddit.com/r/docker/comments/tv7sqs/comment/i37v3zt/

I’m saying keep source code and interpreter/compilers outside of docker. Install your Python/Java/whatever interpreter and your IDE locally. Run your source code on your host machine. Set it up with all the tooling you need to be productive in your favorite stacks and don’t worry about it being 100% portable. Nothing beats running it natively on your host with as few layers as possible between you and the running code. Besides, different devs prefer different tooling anyway, there is no sense in forcing everyone to use the same setup. Then deploy in a container.

During development, use docker for your external dependencies: Kafka broker, database, service registry, all that extra stuff. This + deployment is what you need docker for. You don’t need it to avoid installing a JDK in your IDE if you write Java every day, just install the damn compiler. If you write legacy Java and need JDK 1.6 then you just install both and configure it in your project settings, it’s not a problem that needs solving yet people often over-complicate this and introduce docker for no reason.

When it comes to linters or whatever that you want to integrate in your project, yes this is where a containerized setup would help. But it would hurt in a lot more ways. Instead, I’d suggest you put that in a git hook, CI pipeline or some other toolchain (like your project build tool) instead of trying to pass around a pre-configured containerized IDE to everyone in the project or something like that. You can also dockerize those components individually and bundle it with a shell script that runs it against your local file system.

https://12factor.net/dev-prod-parity

jjketten commented 19 hours ago

Here's an actual look at what we're possibly dealing with. https://www.youtube.com/watch?v=p9L7YFqHGk4 Workspace customizations for stuff like linters can go under customizations. image I imagine that everything else (e.g. Firebase Local Emulator Suite?) would stay the same between devs and it could be derived from the docker-compose and devcontainer files that are updated and tracked with the github repository, unless secrets are involved -- those should not be uploaded to github.