.
|_____README.md
|_____package.json
|_____conf
|_____|_____docker
|_____|_____|_____Dockerfile
|_____|_____|_____Dockerfile.dev
|_____|_____|_____Dockerfile.prod
|_____|_____|_____docker-compose.dev.yml
|_____|_____|_____docker-compose.network.yml
|_____|_____|_____docker-compose.prod.yml
|_____src
|_____|_____server.js
- README.md - The document you are reading.
- package.json - Defines the dependencies, entry point and startup script for the project.
- conf/docker/Dockerfile - Builds a container for the project src.
- conf/docker/Dockerfile.dev - Builds a container for the project src in
dev mode
. - conf/docker/Dockerfile.prod - Builds a container for the project src in
production mode
. - conf/docker/docker-compose.dev.yml - Orchestrates the instantiation of the containers used in the project in
dev mode
. - conf/docker/docker-compose.prod.yml - Orchestrates the instantiation of the containers used in the project in
production
mode. - conf/docker/docker-compose.network.yml - Orchestrates the instantiation of the containers used in the project in
network
mode. - src/server.js - The actual project src code that executes in the container.
The project is run with (one of) the following commands from the root dir ( .
in the tree ):
$ docker-compose --project-name ttg -f conf/docker/docker-compose.dev.yml up
$ docker-compose --project-name ttg -f conf/docker/docker-compose.prod.yml up
$ docker-compose -f conf/docker/docker-compose.network.yml up
-
The file docker-compose.yml defines the service(s), build context, dockerfile(s) to use, and any other configuration details salient to the specific container(s) running (including args, ports, labels, tags, names, etc.)
-
The Dockerfile specified by the service being containerized by the docker-compose.yml file will now build the container image (layer by layer - caching where possible) and deploy the container once it has succesfully been built and configured. These steps include (but ar enot limited too):
- defining the base image to build the container from.
- define directories used in the container/project.
- copy src files into the container form the host system.
- install dependencies into the container.
- expose ports
- issue runtime commands (eg. 'start')
Note: You can specify the project name in the docker-compose command. Default is the name of the folder containing the docker-compose.yml file. This will not work with a docker-compose file in which a network has been defined (eg. docker-compose.network.yml).
Note: All docker-compose actions are executed relative to the path location of the docker-compose.yml file or its specific build context value.
Note: All Dockerfile actions are executed relative to the path location of the Dockerfile file.
Note: You can supply multiple -f configuration files. When you supply multiple files, Compose combines them into a single configuration. Compose builds the configuration in the order you supply the files. Subsequent files override and add to their predecessors.
# DEVNOTE: This does not appear to be working correctly.
$ docker-compose -f docker-compose.dev.yml -f docker-compose.prod.yml -f docker-compose.network.yml
Note: You must provide a unique name for each image your docker-compose file generates. This is based on the service name used in the docker-compose.yml file. Two services of the same name cannot run on the same host, even if defined in different docker-compose files. They will generate image names that conflict in the image listing. Therefore best practice is to use unique names for all running services.
Package.json
This file defines the metadata for the project app, specifies dependencies, and defines the scripts used by docker to run the application.
{
"name": "docker-nodejs-webapp-example",
"version": "1.0.0",
"description": "Node.js in docker",
"author": "",
"license": "ISC",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node src/server.js"
},
"dependencies": {
"express": "^4.13.3",
"ip": "^1.1.5"
}
}
server.js
This is the actuall expresss application used in testing the setup.
'use strict';
const express = require('express');
const ip = require('ip');
// Constants
const PORT = 8080;
// const HOST = '0.0.0.0';
const HOST = ip.address();
console.log(HOST)
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello world\n');
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
Dockerfile, Dockerfile.dev, Dockerfile.prod
FROM node:boron
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 8000
CMD [ "npm", "start" ]
docker-compose.dev.yml
version: '3'
services:
dev_web:
# DEFINE BUILD CONTEXT.
build:
#context: .
context: ../../
# DOCKERFILE PATH RELATIVE TO BUILD CONTEXT.
#dockerfile: ./conf/docker/Dockerfile.dev
dockerfile: ./conf/docker/Dockerfile
ports:
#MAPPING -> "HOST:CONTAINER"
- "50000:8080"
container_name: ttg_webapp_dev
hostname: ttg_webapp_dev
docker-compose.prod.yml
version: '3'
services:
prod_web:
# DEFINE BUILD CONTEXT.
build:
#context: .
context: ../../
# DOCKERFILE PATH RELATIVE TO BUILD CONTEXT.
# dockerfile: ./conf/docker/Dockerfile.prod
dockerfile: ./conf/docker/Dockerfile
ports:
#MAPPING -> "HOST:CONTAINER"
- "52000:8080"
container_name: ttg_webapp_prod
hostname: ttg_webapp_prod
docker-compose.network.yml
version: '3'
services:
net_web:
# DEFINE BUILD CONTEXT.
build:
#context: .
context: ../../
# DOCKERFILE PATH RELATIVE TO BUILD CONTEXT.
dockerfile: ./conf/docker/Dockerfile
networks:
net_net:
ipv4_address: 10.0.0.9
ports:
#MAPPING -> "HOST:CONTAINER"
- "54000:8080"
container_name: ttg_webapp_net
hostname: ttg_webapp_net
networks:
net_net:
ipam:
driver: default
config:
- subnet: 10.0.0.0/8