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
- For Windows: install wsl
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. Please check the github repo 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 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 runsudo
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
orfirefox
orgeany
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.
Top comments (4)
Wouldn't Virtual Machine do the same thing? I mean create a VM, install needed packages, save VM, copy VM to new machine. And all your GUI goodies are there ready to use.
It's been awhile since I've used virtual machine so I could be incorrect.
VM is a lot bulkier, I've run into performance issues with VM on a beefy laptop. The key benefit here is you can manage your configuration for the stuff you actually need as code. It is reproducible and easily portable. You are pulling down a Dockerfile here and now you can get your entire team setup with this. Now imagine having to download a couple GB of VM image (this blows out of proportion when you are talking about updates which you inevitably need) and then the pain of figuring out any issues a dev might have on their machine. Overall, VM is good in certain cases when security is a big concern, and you don't trust what the guest might be doing. However, we don't really need that kind of protection for day to day development. So, you trade in that extra layer of security for performance. This is the same reason you would prefer to deploy your apps as a container vs a VM.
The biggest thing here is you are using the display server of your host, so that's another reason this is so lean. You aren't necessarily bringing in display drivers, rather using whatever your host has. Plus you don't even bring in a kernel, you are using the host kernel.
Hi Adnan!
It's really great setup and I know your pain - containerization helps a lot, especially when I want to create setup for webdev and easily share it with someone else.
Please, explain to me, how are you using the apps, you have installed in container (browser, IDE, etc.). By the time I thought that you can only run interactive shell or connect with shared port, but I wasn't aware, that you can run a GUI app, too.
Hey great question! this is done by sharing your X11 server that handles display in unix systems. However, for windows, I'm having difficulties sharing a X11 server, as windows does not use similar systems. I will update the article once I have that working. Thanks!