-
Notifications
You must be signed in to change notification settings - Fork 341
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
46 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,19 +2,19 @@ | |
title: 'Containers in development' | ||
--- | ||
|
||
Containers are not only great in production. They can be used in development environments as well and offer a number of benefits. The same _works-on-my-machine_ problem is faced often when a new developer joins the team. Not to mention the headache of switching runtime versions or a local database! | ||
Containers are not only great in production. They can be used in development environments as well and offer several benefits. The same _works-on-my-machine_ problem is faced often when a new developer joins the team. Not to mention the headache of switching runtime versions or a local database! | ||
|
||
For an example, a [software development team](https://toska.dev/) at the University of Helsinki has a fully [containerized development environment](https://ethesis.helsinki.fi/repository/handle/123456789/30995). The principle in all development projects is to have a setup so that a new developer only needs to install Docker and clone the project code from GitHub to get started. Not a single dependency is ever installed on to host machine, Git, Docker and the text editor of choice is only thing that is needed. | ||
For example, a [software development team](https://toska.dev/) at the University of Helsinki has a fully [containerized development environment](https://ethesis.helsinki.fi/repository/handle/123456789/30995). The principle in all development projects is to have a setup so that a new developer only needs to install Docker and clone the project code from GitHub to get started. Not a single dependency is ever installed on to host machine, Git, Docker and the text editor of choice are the only things that are needed. | ||
|
||
Even if your application is not completely containerized during development, containers can very helpful. For example, say you need MongoDB version 4.0.22 installed in port 5656. It's now a oneliner: "docker run -p 5656:27017 mongo:4.0.22" (MongoDB uses 27017 as default port). | ||
Even if your application is not completely containerized during development, containers can be very helpful. For example, say you need MongoDB version 4.0.22 installed in port 5656. It's now an oneliner: "docker run -p 5656:27017 mongo:4.0.22" (MongoDB uses 27017 as the default port). | ||
|
||
Let's containerize a NodeJS development environment. As you perhaps know [NodeJS](https://nodejs.org/en/) is a cross-platform JavaScript runtime that makes it possible to run JavaScript in your machine, servers and embedded devices, among many other platforms | ||
|
||
The setup requires some expertise on the way how NodeJS works. Here is a simplified explanation if you're not familiar: libraries are defined in `package.json` and `package-lock.json` and installed with `npm install`. [npm](https://www.npmjs.com/) is the Node package manager. | ||
The setup requires some expertise in the way how NodeJS works. Here is a simplified explanation if you're not familiar: libraries are defined in `package.json` and `package-lock.json` and installed with `npm install`. [npm](https://www.npmjs.com/) is the Node package manager. | ||
|
||
To run application with the packages we have script defined in package.json that instructs Node to execute index.js, the main/entry file in this case the script is executed with `npm start`. The application already includes code to watch for changes in the filesystem and restart the application if any changes are detected. | ||
To run the application with the packages we have a script defined in package.json that instructs Node to execute index.js, the main/entry file in this case the script is executed with `npm start`. The application already includes code to watch for changes in the filesystem and restart the application if any changes are detected. | ||
|
||
The project "node-dev-env" is here [https://github.com/docker-hy/material-applications/tree/main/node-dev-env](https://github.com/docker-hy/material-applications/tree/main/node-dev-env). I already included a development Dockerfile and a helpful docker-compose.yml. | ||
The project "node-dev-env" is here [https://github.com/docker-hy/material-applications/tree/main/node-dev-env](https://github.com/docker-hy/material-applications/tree/main/node-dev-env). We have already included a development Dockerfile and a helpful docker-compose.yml. | ||
|
||
**Dockerfile** | ||
```Dockerfile | ||
|
@@ -50,46 +50,49 @@ And that's it. We'll use volume to copy all source code inside the volume so CMD | |
```console | ||
$ docker compose up | ||
Creating network "node-dev-env_default" with the default driver | ||
Creating volume "node-dev-env_node_modules" with default driver | ||
Building node-dev-env | ||
Step 1/4 : FROM node:14 | ||
... | ||
|
||
Attaching to node-dev-env | ||
node-dev-env | | ||
node-dev-env | > [email protected] start /usr/src/app | ||
node-dev-env | > nodemon index.js | ||
... | ||
|
||
node-dev-env | App listening in port 3000 | ||
Attaching to node-dev-env | ||
node-dev-env | | ||
node-dev-env | > [email protected] start | ||
node-dev-env | > nodemon index.js | ||
node-dev-env | | ||
node-dev-env | [nodemon] 2.0.7 | ||
node-dev-env | [nodemon] to restart at any time, enter `rs` | ||
node-dev-env | [nodemon] watching path(s): *.* | ||
node-dev-env | [nodemon] watching extensions: js,mjs,json | ||
node-dev-env | [nodemon] starting `node index.js` | ||
node-dev-env | App listening in port 3000 | ||
``` | ||
|
||
Great! The initial start up is a bit slow. It is a lot faster now that the image is already built. We can rebuild the whole environment whenever we want with `docker compose up --build`. | ||
Great! The initial start-up is a bit slow. It is a lot faster now that the image is already built. We can rebuild the whole environment whenever we want with `docker compose up --build`. | ||
|
||
Let's see if the application works. Use browser to access [http://localhost:3000](http://localhost:3000), it should do a simple plus calculation with the query params. | ||
Let's see if the application works. Use the browser to access [http://localhost:3000](http://localhost:3000), it should do a simple plus calculation with the query params. | ||
|
||
However, the calulation doesn't make sense! Let's fix the bug. I bet it's this line right here [https://github.com/docker-hy/material-applications/blob/main/node-dev-env/index.js#L5](https://github.com/docker-hy/material-applications/blob/main/node-dev-env/index.js#L5) | ||
However, the calculation doesn't make sense! Let's fix the bug. I bet it's this line right here [https://github.com/docker-hy/material-applications/blob/main/node-dev-env/index.js#L5](https://github.com/docker-hy/material-applications/blob/main/node-dev-env/index.js#L5) | ||
|
||
When I change the line, on my host machine the application instantly notices that files have changed: | ||
|
||
```console | ||
▶ docker compose up | ||
Starting node-dev-env ... done | ||
$ docker compose up | ||
|
||
... | ||
|
||
Attaching to node-dev-env | ||
node-dev-env | | ||
node-dev-env | > [email protected] start /usr/src/app | ||
node-dev-env | > nodemon index.js | ||
node-dev-env | | ||
node-dev-env | [nodemon] 2.0.7 | ||
node-dev-env | [nodemon] to restart at any time, enter `rs` | ||
node-dev-env | [nodemon] watching path(s): *.* | ||
node-dev-env | [nodemon] watching extensions: js,mjs,json | ||
node-dev-env | [nodemon] starting `node index.js` | ||
node-dev-env | App listening in port 3000 | ||
node-dev-env | [nodemon] restarting due to changes... | ||
node-dev-env | [nodemon] starting `node index.js` | ||
node-dev-env | App listening in port 3000 | ||
node-dev-env | | ||
node-dev-env | > [email protected] start | ||
node-dev-env | > nodemon index.js | ||
node-dev-env | | ||
node-dev-env | [nodemon] 2.0.7 | ||
node-dev-env | [nodemon] to restart at any time, enter `rs` | ||
node-dev-env | [nodemon] watching path(s): *.* | ||
node-dev-env | [nodemon] watching extensions: js,mjs,json | ||
node-dev-env | [nodemon] starting `node index.js` | ||
node-dev-env | App listening in port 3000 | ||
node-dev-env | [nodemon] restarting due to changes... | ||
node-dev-env | [nodemon] starting `node index.js` | ||
node-dev-env | App listening in port 3000 | ||
``` | ||
|
||
And now a page refresh shows that our code change fixed the issue. The development environment works. | ||
|
@@ -98,11 +101,12 @@ The next exercise can be extremely easy or extremely hard. Feel free to have fun | |
|
||
## Exercise 2.11 | ||
|
||
|
||
:::info Exercise 2.11 | ||
|
||
Select some of your own development projects and start utilizing containers in the development environment. | ||
|
||
Explain what you have done. It can be anything, e.g., a support for docker-compose.yml to have services (such as databases) containerized or even a fully blown containerized development environment. | ||
Explain what you have done. It can be anything, e.g., support for docker-compose.yml to have services (such as databases) containerized or even a fully blown containerized development environment. | ||
|
||
::: | ||
|
||
If you are interested in how to build a containerized development environment for a React/Node Single page web app, please have a look at the course [Full stack open](https://fullstackopen.com) which has one [chapter](https://fullstackopen.com/en/part12/basics_of_orchestration#development-in-containers) devoted to the topic. |