Containers are everywhere these days. They’re the de-facto deployment method in the industry, and they’re often used for local development as well to ensure that every developer gets the same environment. Flox gives you these same benefits without many of the papercuts, but the workflow is slightly different so it’s worth exploring.Documentation Index
Fetch the complete documentation index at: https://flox.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
Create a new development environment
Let’s say you’ve created a new directory for your project,myproject,
and entered it:
- Flox
- Containers
Create a Flox environment for the project via This creates a
flox init:.flox directory in myproject.
At this point you can enter the environment,
but it doesn’t provide any new packages or functionality.Add packages
Now let’s install some packages. In a typical project there’s usually different subsets of packages:- Packages you don’t care about too much, so the latest version will suffice.
- Packages whose versions you want pinned to a recent version.
- Packages that you’re behind on updating because upgrading requires significant effort.
- Latest is fine:
curl - Specific version:
yarn 1.22 - Behind:
python3.10
- Flox
- Containers
This is pretty straightforward:Adding another package at a later date is as simple as running
flox install <package> again.Configuration
What does it look like to configure your Flox environment compared to a container? A Flox environment is configured via a declarative TOML file called a “manifest”. The manifest for the environment created above looks like this:Dockerfile,
which is an imperative sequence of commands.
Dockerfile is that the commands are familiar
(e.g. apt install),
but the order of commands matters and you end up stuffing a lot of commands
into a single RUN command to avoid creating extra layers.
Use the development environment
Let’s say you want to do some work in the development environment. With Flox you’re put inside a subshell. With containers you can use a shell inside the container or connect to the running container via SSH. However, with containers you also need to mount in your source code, etc.- Flox
- Containers
Activate the environment:Notice that there wasn’t a separate “build” step.
When you install, uninstall, or edit a Flox environment it’s transactionally
built to ensure that it’s always working.
Tear down the development environment
- Flox
- Containers
This is pretty straightforward:
Perform initialization
Let’s say you need to move some files around, ensure a directory exists, or some other kind of initialization before doing work inside the development environment. We’ll do a pretend version of this by simply creating a directoryfoo.
- Flox
- Containers
This would be performed in the
hook.on-activate script that’s run when
activating your environment.
You’ll add this by first running flox edit and
then modifying the hook section of your manifest to look like this:Share the environment with your team
Suppose you work on a team and you’ve just set up the development environment. Now you want to share it with your team so you can ensure that everyone has the same environment.- Flox
- Containers
Since Anyone with Flox installed can now work on this project with two commands:Any packages not locally cached would be downloaded.
Since the Flox environment produces a lockfile each time it is built,
every developer that does a
flox init creates a .flox directory inside your project,
you can simply check this directory into source control.flox activate with the same
lockfile will get the same exact software down to the git revisions of the
upstream source repositories.If your environment doesn’t need to be tied to this specific project you
could also push the environment to FloxHub with flox push.
Then your team would activate the environment as a “remote” environment:Development-time services
In order to mimic the production environment you may want some services running during development (e.g. a web server, a database, etc). For this example let’s say you want a minimal Caddy server running with some environment variables set.- Flox
- Containers
First install Caddy:Then edit your manifest to create a new service:Since Flox environments aren’t isolated from the host machine’s network
you don’t need to map any ports.You can start this service from inside the environment with
flox services start,
or you can have it start automatically when entering the environment via
flox activate --start-services.Run tests in CI
Say you’ve done some development and now want to run your changes through CI.- Flox
- Containers
A CI system would activate the Flox environment for the repository and then
run a specified command inside the environment for each step of the CI job.Since a Flox environment contains a lockfile,
a CI system that runs
flox activate will get exactly the same software
as the developer pushing the changes.
This greatly reduces the number of “it works on my machine” instances.Flox provides a number of plugins for CI providers,
including GitHub Actions, CircleCI, and GitLab.
See the CI/CD tutorial for more information.Send artifacts to production
Now that you have a working development environment, you need to build a container so that it can be deployed.- Flox
- Containers
You can create a container from an environment via the
flox containerize command,
and this image will contain the same exact software
(again, down to the git revisions of the upstream source repositories)
that you used for both local development and CI.
If your environment already contains the programs you want to run in
production, you’re in good shape.You can also produce build artifacts from a Flox environment.
See the builds documentation for more information.