Containerize your Dev environment! Forget about painful project setup. (Beginner friendly)
Tags: docker, java, python, node
Published: 2021-05-29 00:24:31

---
title: Containerize your Dev environment! Forget about painful project setup. (Beginner friendly)
published: true
description: Learn to containerize your dev environment so that you only have to setup once per project.
tags: docker, java, python, nodejs
//cover_image: https://direct_url_to_image.jpg
---

After only a few years of working in the industry I am already tired of having to setup my machine each time something happens to it or I want to work on it on my laptop when visiting someone. Setting up DEV environment has irked me for as long as I have been working in this industry. And after some inspiration from a company that is doing many things right, I decided to make this amazing solution easily available to everyone!

*NOTE: IDE will not work on Windows. Please read windows section.*

### Pre-requisite
 - [Install docker] (https://docs.docker.com/get-docker/)
 - For Windows: [install wsl](https://docs.microsoft.com/en-us/windows/wsl/install-win10)

### Disclaimer
###### Windows
 The display of IDE is done by piggybacking off the X11 server that unix systems use for display. This is not available in windows. However, you should still have full read write access to the "devenv" folder which will be your "home" workspace in your container. So this means that you should still be able to load the files in your favorite IDE, just cannot run it directly from the container. 
(Note: I am still looking to overcome this challenge.)
Edit: I've found that you can use [vcxsrv](https://sourceforge.net/projects/vcxsrv/). Please check the [github repo](https://github.com/ArcticaProject/vcxsrv) for this and download the executable you trust! Once you have this installed, start the X server via XLaunch. I would recommend "Full Screen". Run `ipconfig` and grab your IP, then set your `DISPLAY` environment variable (if you are using mingw64 like me you can run `export DISPLAY=<?IP?>:0.0`). Then you can run the `windocker.sh`. You can then start off `idea` or any other app through this method. (I do understand that this is a lot of workaround, so let's hope Microsoft starts supporting X server natively 😁)

###### Mac
I have not tested this, please try out the `dockerrun.sh` script, and let me know if this does not work.

### Key Concepts
I don't intend to leave behind the many developers that are just getting started. So, here's the general breakdown that you **HAVE TO** know.
 - Container is just as it sounds, a box to separate out resources used by it. This is somewhere between running apps directly in your host vs running in a VM (Virtual Machine). In a VM only the hardware resources are shared. However, in docker the OS kernel is shared. This does mean that the security of your container can be compromised if you let it (That's a whole another beast of its own, so I'll leave that out. Yes, this does mean you should not just pull down some random image and run exactly as the writer tells you to 😭. **PLEASE ONLY USE TRUSTED IMAGES**).
 - Docker runs natively on your machine, and in this tutorial you will learn to mount folders as volumes into your container so that the work is *easily* available (generally, you can access any files the container is using from the host, because of the nature of containerization).
 - **VOLUMES\!\!** Now this is the meat of the entire blog. You will mount your work folders as volumes onto the container which will let you easily work and streamline development. The main idea here is to give the container access to your work environment (for this, I'll assume all of your projects live in a single folder).
 - Image Layers. Docker images use layering. Where each layer is generated by a statement in your "Dockerfile" (think of this as the configuration for your container). This is great for many reasons but the most important of them all is re-usability. We can pretty much build on top of an existing image, create our own "base" image and layer that based on what kind of project we will be working on. *Think of a sandwich. You put the bread down, your partner puts in the meat, then the kids choose the toppings.*

That should cover most of the key questions you have regarding this. Please comment on whatever finer details you need and I will be happy to help.

### Base Module
Lets take a look at the main `Dockerfile` which you will use as the starting point for many of your customized images.
Please go to the [github repo](https://github.com/opiteq/dev-environment) to find the source code! 😊
###### Dockerfile:
 - We will start off with openjdk alpine so that we don't have to install and configure jdk, and set environment variables.
 - Then let's go ahead and setup for the user. Running as root is sadly not recommended. So we will configure a "dev" user. This definitely does mean that you will not be able to run some of the commands you are used to running as root. However, you can always shell into a container as `root`, and run `sudo` commands that way.
 - Now let's go ahead and update our alpine image.
 - Let's create the user we setup.
 - Finally add our base applications and install dev tools.
 - Let's install the browser and IDE.
 - Last thing is to make sure we have proper access to our work env.

###### dockerrun.sh (Shell script)
 - Now we really want to automate the image creation and container start and attach process. This is because very few developers like to do extra manual work 😛.
 - Let's cleanup if there's a stopped container.
 - If there is no container then we create and start a shell session. If there is then we simply start a new shell session within the same container.

That is all! 😊

### Setup the environment
Let's start off by cloning the repo. You will build the image yourself so that you have better control over it.
 - Let's go into where you will be working `cd <workdir>`
 - `git clone https://github.com/opiteq/dev-environment .`
 - `./dockerrun.sh`
 - now if you open up a new terminal you can simply run the same shell script to get inside of your container.
 - I have setup ports 3000-3003 for dev, so you can easily access them from host if needed. Idea is you would run your server and use one of those ports.
 - Now, if you are on linux, go ahead and run `idea` or `firefox` or `geany` from the terminal and voilà.

### Breakdown
The core concept here is to get you started with a base image then you customize it to your heart's content and get going with your development. I chose alpine linux as the base image because I think less is more. However, I did go with openjdk image so that majority of the java configuration is handled for me. This is also a work-in-progress, so the repository may evolve overtime as I find better fit for my needs.

### Conclusion
Your container is what you make of it! Please feel free to customize it to your heart's content and reach out to the amazing community with your questions. I would love to address anything that I missed so definitely let me know. If you think anything I said is incorrect I would be thrilled to learn and correct myself for future readers.
Leave your questions down below and I will get to them as soon as I can.