Skip to content

Commit

Permalink
Made microservices easier to locally develop.
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzziah Eyee committed Apr 30, 2019
1 parent f0b0bb4 commit fc7f7a7
Show file tree
Hide file tree
Showing 10 changed files with 497 additions and 31 deletions.
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to api-server container",
"type": "node",
"request": "attach",
// should match the exposed debug address specified in docker-compose
"address": "localhost",
"port": 9229,
"protocol": "inspector",
// you typically copy the src folder into a location in docker...specify this mapping.
"localRoot": "${workspaceFolder}/api-server/src",
"remoteRoot": "/usr/src/app"
}
]
}
74 changes: 64 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,52 @@
# Horus

Monitoring containerized microservices with a centralized logging architecture.
A test project for learning microservices observability through: **centralized logging** and **distributed tracing**.

## Dependencies
## Requirements

- Docker Compose v1.23.2
- OSX or GNU/Linux operating system

## Setup
## Development Setup

1. Signup with an ELK SaaS provider like [Logz.io](logz.io) to obtain an authentication token. Then for each microservice, rename `example.env` to `.env` and supply the needed secrets.
1. Clone this repo and open the root folder in an IDE like *Visual Studio Code*.

2. Run the following commands.
2. For each microservice, rename `example.env` to `.env` and supply the needed secrets.

docker-compose build --pull
docker-compose up -d --force-recreate
3. Then log into your ELK SaaS and view your microservices logs.
3. Start all microservices in *development mode*.

docker-compose -f docker-compose.dev.yml \
up -d --build

> Development mode is important for 2 reasons.
> - Changes to a service's source files will automatically restart/rebuild the docker service to show the changes.
> - You can attach a remote debugger from your IDE to the docker process for seemless debugging like placing breakpoints and watching variables.
> - NOTE: When you edit a service's source files, the docker process will restart, severing your remote debugger connection. So, you'd need to reattach the debugger again.
4. Attach the IDE's debugger to the desired service. Follow these steps in Visual Studio Code: *shift+cmd+D > Select a debug configuration > F5*.
> All Visual Studio Code debug configurations are stored in *.vscode/launch.json*. You can modify configs as you see fit.
### Useful dev commands

# list all running services
docker-compose -f docker-compose.dev.yml ps

# stop all services
docker-compose -f docker-compose.dev.yml down

# restart only all [or specific] service
docker-compose -f docker-compose.dev.yml \
up -d --no-deps --build [service-name]

# tail logs from all [or specific] service
docker-compose logs -f [service-name]

## Production Setup

TODO

- Signup with an ELK SaaS provider like [Logz.io](logz.io) to obtain an authentication token. Then for each microservice, rename `example.env` to `.env` and supply the needed secrets.
- Then log into your ELK SaaS and view your microservices logs.

## Project Documentation

Expand All @@ -27,6 +58,16 @@ I wrote an accompanying [article](https://hackernoon.com/monitoring-containerize

## Notes

- You can update a single service/container while the entire suite is running using the following command

docker-compose -f docker-compose.dev.yml \
up -d --no-deps --build <service_name>

docker-compose -f docker-compose.prod.yml \
up -d --no-deps --build <service_name>

> `--build` recreates the container from its image/dockerfile and `--no-deps` ensures dependent services aren't affected.

### Docker Networking

By default each containerized process runs in an isolated network namespace. For inter-container communication, place them in the same network namespace...as seen in *docker-compose.yml*.
Expand All @@ -36,8 +77,21 @@ By default each containerized process runs in an isolated network namespace. For
1. You can pass secrets for a microservice using the `env_file` attribute in *docker-compose.yml*.
2. Microservices can communicate using their service names if they are in the same docker network.

### How do you debug an app running in a container (i.e breakpoints and watch variables etc.)?
?
- You can tail the logs from all services using `docker-compose [-f <file>] logs -f`.

### Improvement Considerations

1. **Name Duplication:** The value of the `API_SERVER_ADDRESS` variable in *user-simulator/.env* depends on the service name `api-server` specified in *docker-compose.yml*. If we rename the service, we must also change the variable. Is there a way to make this DRY?

2. In the log-shipper container, I had to install a logz.io-specific plugin. Can't this step be eliminated since fluentd is capable of connecting to https endpoints without plugins?
2. In the log-shipper container, I had to install a logz.io-specific plugin. Can't this step be eliminated since fluentd is capable of connecting to https endpoints without plugins?

3. Use sub-second precision for fluentd timestamps (probably best to use nanoseconds.)

## Some References

https://medium.com/lucjuggery/docker-in-development-with-nodemon-d500366e74df
https://blog.risingstack.com/how-to-debug-a-node-js-app-in-a-docker-container/
https://codefresh.io/docker-tutorial/debug_node_in_docker/
https://code.visualstudio.com/docs/editor/debugging
2 changes: 1 addition & 1 deletion api-server/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.env
/node_modules
node_modules
npm-debug.log
.DS_Store
4 changes: 3 additions & 1 deletion api-server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ WORKDIR /usr/src/app
# optimization to only rebuild npm modules iff package[-lock].json changes
COPY src/package*.json ./

# TODO: only install nodemon if some arg is set to 'dev'
RUN npm install -g nodemon
# For production `RUN npm install --only=production`
RUN npm install

COPY src .

CMD ["npm", "start"]
CMD ["node", "."]
2 changes: 1 addition & 1 deletion api-server/example.env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PORT=
# TODO
18 changes: 8 additions & 10 deletions api-server/src/app.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
// const dotenv = require('dotenv')
// if (process.env.NODE_ENV !== 'production') {
// const result = dotenv.config()
// if (result.error) {
// throw result.error
// }
// }

const app = require('express')()
const uuid = require('uuid/v1')

app.use('/api/v1/tokens', (req, res) => {
console.log(`Handling request for token`)
res.json({token: uuid()})
})

const server = app.listen(process.env.PORT, () => {
app.use('/api/v1/whereami', (req, res) => {
// TODO: get geolocation info from IP address
// TODO: get weather info from geolocation
// TODO: return everything
let data = {'info': null}
res.json(data)
})
const server = app.listen(process.env.PORT || 3000, () => {
console.log(`Listening on ${ server.address().address }:${ server.address().port }`)
})
Loading

0 comments on commit fc7f7a7

Please sign in to comment.