Skip to content

jerryq27/dev-environments

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Portable Dev Environments

I enjoy playing around with a variety of tools and languages. Installing packages on multiple machines became a pain, so I learned Docker to utilize containers and create images with the those packages. This keeps my machines clean and gives me a portable setup for development.

So now I just follow these steps with every project:

  1. Create/Use a Dockerfile to create an image with all the necessary packages
  2. Create a docker-compose.yml file in the project directory that uses the image
  3. Add project-specific settings in the compose file (ports, volumes, etc.)

Creating a Dockerfile & Building the Image

These are just rules and naming conventions I set for myself to follow

The Dockerfiles are meant to be generic for a development environment. That's why I start from an Ubuntu image, and install the appropriate packages there. Why not start from something like node:latest? Maybe I want to use Yarn, Bun, etc. or all of them at the same time. It's just much easier to start from a bare bones Ubuntu image.

Things to keep in mind with writing the Dockerfile:

  1. All commands are ran as root and files created will be owned by root
  2. Note where packages install things and which envnironment variables they use
  3. Create a new user with a $UID:$GID that matches the host system user's $UID:$GID
  4. Add any folders that will be used in the compose file's volume binds (they will be owned by root if created in compose)
  5. Update $PATH or link package binaries to /bin
  6. Copy any user-specific configuration files (like .bashrc) into the new user's Home
  7. Make sure the new user is the owner of their Home directory
  8. Switch from root to the new user

The image name follows the format env_$ENVIRONMENT, for example env_webdev.

Building the image:

docker build -t $ENV_NAME:$VERSION -f $DOCKERFILE .

# Get more detailed logs during a build.
docker build -t $ENV_NAME:$VERSION -f $DOCKERFILE . --progress=plain

Creating the Compose file

Each project will have a docker-compose.yml file for project-specifc settings.

Things to keep in mind with writing the compose file:

  1. Container name is prefixed with project_ or work_
  2. Use locally built image with pull_policy: missing
  3. Ensure I can drop into a bash session with stdin_open: true and tty: true
  4. Copy project files into the user's Home folder
  5. Volume binds to non-existent folders (like ~/.cache) will be created and owned by root, so ensure they are already created during the image build

Bare minimum compose file:

services:
  $PROJECT:
    container_name: project_$PROJECT
    image: env_$IMAGE
    pull_policy: missing
    stdin_open: true
    tty: true
    volumes:
      - ./:/home/$USER/app/

Running the container:

docker compose up -d
docker exec -it $CONTAINER_NAME bash --login 

Running bash --login in the container ensures that something like .bashrc gets sourced.

About

Dockfiles I use for development.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published