Dockerize projects for local development
If a project is contained from the start then you have a greater degree of confidence that it’ll run in any environment. If it works locally then it’ll work anywhere.
There are a few elements that are required to achieve local docker development:
- Docker to build & run the project image & container
- Docker-Compose to connect all the containers and expose the ports to localhost and share files between container and host
- Nodemon to watch for file changes and restart the app process (for development)
I’ve created a repo to serve as an example, so I’ll use that to step through the process. The repo has a nodejs and python service. Each will be setup for local development using nodemon (yes nodemon can work for python too!).
Step 1: Dockerfiles
COPY package*.json ./
RUN npm install
RUN npm install -g nodemon
This is an example Dockerfile for a nodejs app. It’s a pretty simple boilerplate. I won’t go into much detail to the layers but all its doing is pulling from node:10 image then copying the project dependency files into the container then installing the dependencies.
COPY requirements.txt ./
RUN npm install -g nodemon
RUN apt-get update
RUN pip install -r requirements.txt
This python Dockerfile is very similar to the nodejs example above. Instead of pulling from the python:3 image we’re pulling from an image that has both python and nodejs. The reason we need nodejs is so that we can use nodemon for watching python file changes. We’ll install nodemon globally using npm.
Step 2: docker-compose
Now we’ll connect the services using docker-compose:
version: '3'services: nodejs-service:
command: nodemon --inspect=0.0.0.0 app.js python-service:
command: nodemon app.py
For each of the services we’re directing docker-compose to build their images from their respective directories with the ‘build’ directive. The ‘volumes’ directive maps the host’s ‘src’ directory of the service to the container’s ‘src’ directory. The ‘ports’ are simply setup so that the containerised app port maps to the host port so that you can test the app (using Postman or some other HTTP client). In the nodejs service there is an extra port (9229) — this is the debugging port, I’ll cover this next. One last thing to mention is the ‘command’ directive — as this docker-compose file is configured for development only (and could be configured further with environment variables for local & production) the app process is handled by nodemon. Again, the nodejs service is a bit different as ‘ — inspect=0.0.0.0’ is used for debugging.
If you’re not interested in setting up debugging for nodejs then you should be good to go. Do a ‘docker-compose’ and get developing.
Step 3: Debugging Nodejs
At this moment in time I don’t have a clean method to setup debugging with Python, so I must settle with just nodejs. If anyone has any suggestions then please leave a comment.
In the root directory of your project repo create a folder called ‘.vscode’ then create a file called ‘launch.json’ then add the following code:
"name": "Attach: Nodejs",
I hope this has helped. If anyone has any improvements or suggestions then please let me know in the comments :)
Thanks to the references: