Skip to content

Commit 521f83a

Browse files
xRuiAlvesmiguelpduarte
authored andcommitted
Feature/dotenv flow (#23)
* Add dotenv-flow package * Add local env files rule to gitignore * Add example env file * Update readme with new env setup instructions * Implement review suggestions - Refactor env variables usages - Refactor .env files structure, in order to follow the recommendations of dotenv-flow's documentation - Fix Docker configs to handle this change - Fix TravisCI configs to handle this change - Made shell scripts safer 🍝 - Update README.md with the new information - Accidentally started work on #24 - Everything was tested and analised thoroughly
1 parent 21ccf6c commit 521f83a

16 files changed

+132
-101
lines changed

.env

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Specifies the host for the mongodb database
2+
DB_HOST=localhost
3+
# Specifies the port for the mongodb database
4+
DB_PORT=27017
5+
# Specifies the username with which to connect to the database
6+
DB_USER=
7+
# Specified the password with which to connect to the database
8+
DB_PASS=
9+
# Specifies the name of the database to connect to
10+
DB_NAME=nijobs
11+
12+
# Session secret - OVERRIDE IN PRODUCTION
13+
SESSION_SECRET=O Rui foi membro do IEEE.
14+
15+
# Specifies the port in which the app will be exposed
16+
PORT=8000

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
# Env related
2+
# Ignoring the local configuration files. However .env.ENVIRONMENT (and .env) SHOULD be version controlled! See dotenv-flow's docs for details: https://www.npmjs.com/package/dotenv-flow
3+
.env*.local
4+
15
# Extras
2-
.env
36
.vscode
47

58
# Created by https://www.gitignore.io/api/node,macos,linux,windows

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ services:
1010

1111
env:
1212
global:
13-
- HOST_PORT=3000
13+
# The hostname is set to mongo because of the docker configuration (using networks to access the DB)
1414
- DB_HOSTNAME=mongo
1515
matrix:
1616
# Any separate test environment variables go here, one per line each creating a different test environment
@@ -19,4 +19,4 @@ script:
1919
- docker-compose up --exit-code-from test test
2020

2121
cache:
22-
npm: true
22+
npm: true

Dockerfile

+9-12
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,21 @@
22
# Use node 8-LTS
33
FROM node:8
44

5-
RUN mkdir -p /usr/src/nijobs-be
6-
WORKDIR /usr/src/nijobs-be
5+
WORKDIR /usr/src/app
76

87
# Install app dependencies
9-
# A wildcard is used to ensure both package.json AND package-lock.json are copied
10-
# where available (npm@5+)
11-
COPY package*.json ./
8+
COPY package.json package-lock.json ./
129

13-
# Install Node Packages (only production if not in dev mode)
10+
# Install Node Packages
1411
RUN npm install
1512

1613
# Copying app source
17-
COPY ./src ./src
18-
19-
# Copying .env file because it is necessary for the app to run
20-
COPY .env ./
14+
COPY src/ src/
2115

2216
# Copying test suite
23-
COPY ./test ./test
17+
COPY test/ test/
18+
19+
# Copying .env files
20+
COPY .env* ./
2421

25-
CMD ["npm", "start"]
22+
CMD ["npm", "start"]

Dockerfile-prod

+7-10
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,18 @@
22
# Use node 8-LTS
33
FROM node:8
44

5-
RUN mkdir -p /usr/src/nijobs-be
6-
WORKDIR /usr/src/nijobs-be
5+
WORKDIR /usr/src/app
76

87
# Install app dependencies
9-
# A wildcard is used to ensure both package.json AND package-lock.json are copied
10-
# where available (npm@5+)
11-
COPY package*.json ./
8+
COPY package.json package-lock.json ./
129

1310
# Install Node Packages (only production)
14-
RUN npm install --only=production
11+
RUN npm install --production
1512

1613
# Copying app source
17-
COPY ./src ./src
14+
COPY src/ src/
1815

19-
# Copying .env file because it is necessary for the app to run
20-
COPY .env ./
16+
# Copying .env files
17+
COPY .env* ./
2118

22-
CMD ["npm", "run", "prod"]
19+
CMD ["npm", "run", "prod"]

Dockerfile-test

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
# Use node 8-LTS
33
FROM node:8
44

5-
RUN mkdir -p /usr/src/nijobs-be
6-
WORKDIR /usr/src/nijobs-be
5+
WORKDIR /usr/src/app
76

87
# Install app dependencies
9-
# A wildcard is used to ensure both package.json AND package-lock.json are copied
10-
# where available (npm@5+)
11-
COPY package*.json ./
8+
COPY package.json package-lock.json ./
129

13-
# Install Node Packages (only production if not in dev mode)
10+
# Install Node Packages
1411
RUN npm install
1512

1613
# Copying app source
17-
COPY ./src ./src
14+
COPY src/ src/
1815

1916
# Copying test suite
20-
COPY ./test ./test
17+
COPY test/ test/
2118

2219
# Copying linting configuration (for running the linter)
2320
COPY .eslintrc.json .
2421

25-
CMD ["npm", "test"]
22+
# Copying .env files
23+
COPY .env* ./
24+
25+
CMD ["npm", "test"]

README.md

+31-10
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,38 @@ Next, follow [these](https://docs.docker.com/install/linux/linux-postinstall/) s
2828

2929
### Installing Docker Compose
3030

31-
The best approach to install `docker-compose` is to follow the offical guide [here](https://docs.docker.com/compose/install/#install-compose).
31+
The best approach to install `docker-compose` is to follow the offical guide [here](https://docs.docker.com/compose/install/#install-compose).
32+
33+
### Env files setup
34+
35+
To start developing, copy `.env` to `.env.local` (by running `cp .env .env.local`).
36+
37+
`.env.local` (the file you just created) is your local configuration file, in which you should override the default configurations provided by `.env`.
38+
39+
Then, you can override the variable's values, according to their explanation in `.env`.
40+
3241

3342
## Usage
3443

44+
After [setting up your env files](#env-files-setup), you can run the project:
45+
3546
### Development Environment
36-
To start developing, you must create a file `.env` with environment variables, which are explained in more detail [below](#env-file-specification).
3747

38-
After creating the `.env` file, you must build a dev server.
48+
You can start developing by building a local server:
3949

4050
```bash
4151
docker-compose build web-dev
4252
```
53+
4354
If you have already built the images/containers before you can simply run:
55+
4456
```bash
4557
docker-compose up web-dev
4658
```
4759

4860
> A `dev.sh` file is available in the project's root folder to run these commands on linux environments (simply run `./dev.sh [--build]`)
4961
50-
This will create a development server with hot reloading which will listen on `http://localhost:<HOST_PORT>`.
62+
This will create a development server with hot reloading which will listen on `http://localhost:<PORT>`.
5163

5264
### Testing Environment
5365

@@ -65,7 +77,7 @@ docker-compose up test mongo --exit-code-from test
6577
6678
### Production Environment
6779

68-
The production environment is created by doing:
80+
The production environment can be created by doing:
6981

7082
```bash
7183
docker-compose build web-prod
@@ -79,15 +91,24 @@ docker-compose up web-prod
7991
8092
This environment doesn't have hot reloading or dev extensions and is made to be used in the deployment server running this aplication.
8193

82-
### Env File Specification
94+
### Manual Configuration (Recommended for flexibility)
95+
96+
> In order to install and manage versions for `nodejs`, the usage of a version manager such as [`asdf`](https://asdf-vm.com/) (very recommended) or [`nvm`](https://github.com/nvm-sh/nvm) (still decent, but limited to `node`).
97+
98+
If you already have a `node` installation you can simply use the `npm` commands specified in `package.json` directly.
99+
100+
So, you can run:
101+
102+
- `npm start` to run the application in development mode, with hot reloading
103+
- `npm test` to run the test suites
104+
- `npm run prod` to serve the development version of the project
105+
- Other `npm run` scripts configured in `package.json` (such as linting, for example)
83106

84-
- `HOST_PORT`= The port that the server will expose (http://localhost:<HOST_PORT>)
85-
- `MONGO_URI`= [Optional] Specify a URI for an external mongo database
86-
- `DB_HOSTNAME`= The hostname of the DB, in the case of not wanting to specify the full URI (defaults to `localhost`) - Useful for setting up docker containers, for example (the current docker configuration already considers this)
107+
This approach might be the least straightforward to set up but is the most flexible as you can freely and directly interact with the runtime of the application.
87108

88109
## Project Details
89110

90-
This project uses [`Node.js`](https://nodejs.org/en/) with [`Express.js`](https://expressjs.com/) for the API routing and request-response logic. The DBMS used is [`MongoDB`](https://www.mongodb.com/), along with [`Mongoose`](https://mongoosejs.com/) for the communication to it in Node.
111+
This project uses [`Node.js`](https://nodejs.org/en/) with [`Express.js`](https://expressjs.com/) for the API routing and request-response logic. The DBMS used is [`MongoDB`](https://www.mongodb.com/), along with [`Mongoose`](https://mongoosejs.com/) for integrating it with Node.
91112

92113
Testing is done using [`Mocha`](https://mochajs.org/) and [`Chai`](https://www.chaijs.com/).
93114

dev.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/usr/bin/env sh
22

3-
docker-compose up $1 web-dev
3+
docker-compose up "$1" web-dev

docker-compose.yml

+8-18
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,36 @@ services:
44
build:
55
context: .
66
dockerfile: Dockerfile-prod
7-
volumes:
8-
- ./src:/usr/src/nijobs-be/src
9-
ports:
10-
- ${HOST_PORT}:3000
117
environment:
12-
- PORT=3000
13-
- NODE_ENV=prod
14-
- DB_HOSTNAME=mongo
8+
- DB_HOST=mongo
9+
ports:
10+
- "${PORT}:${PORT}"
1511
depends_on:
1612
- mongo
1713
web-dev:
1814
build:
1915
context: .
2016
dockerfile: Dockerfile
17+
ports:
18+
- "${PORT}:${PORT}"
2119
environment:
22-
- PORT=3001
23-
- NODE_ENV=dev
24-
- DB_HOSTNAME=mongo
20+
- DB_HOST=mongo
2521
volumes:
2622
- ./src:/usr/src/nijobs-be/src
27-
ports:
28-
- "${HOST_PORT}:3001"
2923
depends_on:
3024
- mongo
3125
test:
3226
build:
3327
context: .
3428
dockerfile: Dockerfile-test
3529
environment:
36-
- PORT=3002
37-
- NODE_ENV=test
38-
- DB_HOSTNAME=mongo
30+
- DB_HOST=mongo
3931
volumes:
4032
- ./src:/usr/src/nijobs-be/src
4133
- ./test:/usr/src/nijobs-be/test
42-
ports:
43-
- "${HOST_PORT}:3002"
4434
depends_on:
4535
- mongo
4636
mongo:
4737
image: mongo
4838
ports:
49-
- "27017:27017"
39+
- "27017:27017"

package-lock.json

+11-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"dependencies": {
3535
"bcrypt-nodejs": "0.0.3",
3636
"body-parser": "^1.18.3",
37-
"dotenv": "^6.2.0",
37+
"dotenv-flow": "^3.0.0",
3838
"express": "^4.16.4",
3939
"express-session": "^1.15.6",
4040
"passport": "^0.4.0",

prod.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/usr/bin/env sh
22

3-
docker-compose up $1 web-prod
3+
docker-compose up "$1" web-prod

src/db_controller.js

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
const mongoose = require("mongoose");
22

3-
// Default mongo port
4-
const DB_PORT = 27017;
5-
const DB_HOST = process.env.DB_HOSTNAME || "localhost";
3+
// Getting configs from env variables (.env files)
4+
const {
5+
DB_HOST,
6+
DB_PORT,
7+
DB_USER,
8+
DB_PASS,
9+
DB_NAME,
10+
} = process.env;
611

7-
const MONGO_URI = process.env.MONGO_URI || `mongodb://${DB_HOST}:${DB_PORT}`;
12+
if (!DB_HOST || !DB_PORT) {
13+
console.error("'DB_HOST' and 'DB_PORT' must be specified in the env file! See README.md for details.");
14+
process.exit(125);
15+
}
816

9-
const DB_NAME = (process.env.NODE_ENV === "test" ? "test-db" : "nijobs-db");
17+
if (!DB_NAME) {
18+
console.error("'DB_NAME' must be specified in the env file! See README.md for details.");
19+
process.exit(126);
20+
}
1021

1122
const options = {
1223
useNewUrlParser: true,
13-
dbName: process.env.MONGO_URI ? undefined : DB_NAME,
24+
dbName: DB_NAME,
25+
user: DB_USER,
26+
pass: DB_PASS,
1427
useCreateIndex: true,
1528
};
1629

17-
const db_connection_promise = mongoose.connect(MONGO_URI, options);
30+
const db_connection_promise = mongoose.connect(`mongodb://${DB_HOST}:${DB_PORT}`, options);
1831

19-
module.exports = db_connection_promise;
32+
module.exports = db_connection_promise;

0 commit comments

Comments
 (0)