Purpose of this repo is to show the "proper" way of "doing things" for Docker compose app's. Not to teach the "proper" coding.
For starters organize your multi container projects with the root folder and subfolders; one for each container. This repository folder structure is:
.
├───backend // container
├───environprinter // container
├───docs // not a container
└───frontend // container
- each container code is in a separate folder
- keep the
Dockerfile
s in them individual container folders docker-compose.yaml
is in the root folder- create and use the simple script (
decoupled_build.cmd
in this case) to remove and restart deploying your compose app.
@echo off
@REM first remove the previous
docker-compose down --rmi all
@REM now build and start
@REM -d for daemon is optional arguments bellow
docker-compose up
Usually deployment scripts and source code are externally configured.And there are .env files as an universally accepted solution. News to you? Please be sure to detour over here before proceeding:
- In here we have very simple windows desktop docker compose app deployment
- for the time being we will not separately deploy non prod and prod code
- WARNING: Often the literature mixes OS environment variables and Docker environment variables
- be sure to understand they are different 'things'
- in here I avoid the confusion by not using the OS env vars
- I use only
.env
files- I create env vars in docker-compose and docker files
- I do strongly advise against mixing
- ditto: only one
.env
file - used only by the one top level
docker-compose.yaml
- env vars passed down from it to the docker files
- ditto: only one
- added complexity (confusion) comes from the fact
.env
files can be read from the source code - simply do not do that, keep separate configurations in separate language specific configuration files
- see the node js examples bellow
- Be sure to read and understand the comments in the simple source files in this repo
- especially the ones about
.env
files
- especially the ones about
- purpose of the source in here is to show the recommended organization of the multi container project organization and configurations
- not the "best" algorithms and such
NOTE: this is not docker or OS environment variables.
Example. Create a JSON file, such as config.json
, and define your configuration variables and values:
{
"database": {
"host": "localhost",
"port": 27017,
"username": "admin",
"password": "password"
},
"server": {
"port": 3000,
"secretKey": "mysecretkey"
}
}
Read this JSON file in your Node.js application using the require function:
const config = require('./config.json');
console.log(config.database.host); // localhost
console.log(config.server.port); // 3000
That snippet also illustrates the applicability of the NODE js to the JSON handling. To do the same from any other language will require (much) more lines of code, to the same effect. Yes Python including. Nothing beats javascript when it comes to json.
One can create a node js configuration module that exports the configuration variables as an object. This allows JavaScript code to handle complex configurations as if they are objects and constants in the code.
For example, create a config.js
file representing one node js module:
// config.js
const databaseHost = 'localhost';
const databasePort = 27017;
// we use the env vars from the Dockerfile
// that has been given the .env defined vars
// used by the docker-compose above it
const serverPort = process.env.BACKEND_PORT ;
// do not do this bellow, is is a quiet error anti pattern!
// const serverPort = process.env.PORT || 3000;
// instead signal the error and exit, as bellow
if (!process.env.BACKEND_PORT) {
console.error('Error from config.js module: BACKEND_PORT environment variable is not defined?');
process.exit(1); // Exit the process with a non-zero status code
}
module.exports = {
database: {
host: databaseHost,
port: databasePort
},
server: {
port: serverPort
}
};
Now simply require this configuration module in your application:
const config = require('./config.js');
console.log(config.database.host); // localhost
console.log(config.server.port); // the value of BACKEND_PORT environment variable
Importantly using that configuration mechanism, we are not confusing ourselves (and reviewers) by using the
.env
files, for other purposes, hidden in the source code.
This project is W.I.P.
(c) [email protected] CC BY SA 4.0