Skip to content

Commit

Permalink
docker-3
Browse files Browse the repository at this point in the history
  • Loading branch information
Baykanurov committed Oct 28, 2023
1 parent 52ad2f5 commit d203dac
Show file tree
Hide file tree
Showing 35 changed files with 1,349 additions and 0 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,56 @@ docker push baykanurov/otus-reddit:1.0
```shell
docker pull baykanurov/otus-reddit:1.0
```

## Docker-3
### Что было сделано:
1. Написал Dockerfiles для сервисов:
- **post-py**
- **comment**
- **ui**
2. Запустил и проверил, что всё работает
```shell
docker network create reddit
docker run -d --network=reddit --network-alias=post_db --network-alias=comment_db mongo:4.4
docker run -d --network=reddit --network-alias=post baykanurov/post:1.0
docker run -d --network=reddit --network-alias=comment baykanurov/comment:1.0
docker run -d --network=reddit -p 9292:9292 baykanurov/ui:1.0
```
3. С какими проблемами столкнулся:
- Образ `mongo:latest` не работал с той кодовой базой которая была в приложении, поэтому я опустил версию до 4.4
- Сервис post-py не собирался и было необходимо добавить `pip install --upgrade pip`
- Для сервисов comment и ui необходимо было добавить `gem install bundler:1.17.2`
### Дополнительное задание
Т.к. я сразу писал на alpine образах, поэтому оптимизировать их не было смысла.

**Вес образов до выполнения дополнительного задания:**
```shell
REPOSITORY TAG IMAGE ID CREATED SIZE
baykanurov/comment 1.0 4a0cdac51e5b 30 seconds ago 286MB
baykanurov/ui 1.0 1def719ed381 45 seconds ago 289MB
baykanurov/post 1.0 23c8f2aca095 35 minutes ago 121MB
mongo 4.4 e772806c1f73 2 weeks ago 432MB
```
Протестировал сборку с Ubuntu для сервиса ui, результаты:
```shell
REPOSITORY TAG IMAGE ID CREATED SIZE
baykanurov/ui 2.0 2d7b29a1f364 About a minute ago 487MB
baykanurov/comment 1.0 4a0cdac51e5b 6 minutes ago 286MB
baykanurov/ui 1.0 1def719ed381 6 minutes ago 289MB
baykanurov/post 1.0 23c8f2aca095 40 minutes ago 121MB
mongo 4.4 e772806c1f73 2 weeks ago 432MB
```
Как можно увидеть вес существенно отличается от образа `ui:1.0`.

**src/ui/ubuntu.Dockerfile** - Dockerfile для сервиса ui на основе образа Ubuntu.

Также тестировал запуск образов с альтернативными alias меняя переменные окружения в Dockerfile соответственно.

Дополнительно добавил для MongoDB volume чтобы данные сохранялись.
```shell
docker volume create reddit_db
docker run -d --network=reddit --network-alias=post_db --network-alias=comment_db -v reddit_db:/data/db mongo:4.4
docker run -d --network=reddit --network-alias=post baykanurov/post:1.0
docker run -d --network=reddit --network-alias=comment baykanurov/comment:1.0
docker run -d --network=reddit -p 9292:9292 baykanurov/ui:1.0
```
6 changes: 6 additions & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
docker-compose.yml
build_info.txt
prometheus/

## python specific
*.pyc
1 change: 1 addition & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Micorservices
1 change: 1 addition & 0 deletions src/comment/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Dockerfile
16 changes: 16 additions & 0 deletions src/comment/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ruby:2.7.8-alpine

ENV WORKDIR /app
ENV COMMENT_DATABASE_HOST comment_db
ENV COMMENT_DATABASE comments

WORKDIR $WORKDIR

COPY . ./

RUN apk update --no-cache && \
apk add --no-cache build-base && \
gem install bundler:1.17.2 && \
bundle install

ENTRYPOINT ["puma"]
10 changes: 10 additions & 0 deletions src/comment/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
source 'https://rubygems.org'

gem 'sinatra', '~> 2.0.2'
gem 'bson_ext'
gem 'mongo'
gem 'puma'
gem 'prometheus-client'
gem "rack", '>= 2.0.6'
gem 'rufus-scheduler'
gem 'tzinfo-data'
50 changes: 50 additions & 0 deletions src/comment/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
GEM
remote: https://rubygems.org/
specs:
bson (4.3.0)
bson_ext (1.5.1)
et-orbi (1.1.6)
tzinfo
fugit (1.1.6)
et-orbi (~> 1.1, >= 1.1.6)
raabro (~> 1.1)
mongo (2.6.2)
bson (>= 4.3.0, < 5.0.0)
mustermann (1.0.3)
prometheus-client (0.8.0)
quantile (~> 0.2.1)
puma (3.12.0)
quantile (0.2.1)
raabro (1.1.6)
rack (2.0.6)
rack-protection (2.0.4)
rack
rufus-scheduler (3.5.2)
fugit (~> 1.1, >= 1.1.5)
sinatra (2.0.4)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.4)
tilt (~> 2.0)
thread_safe (0.3.6)
tilt (2.0.9)
tzinfo (1.2.5)
thread_safe (~> 0.1)
tzinfo-data (1.2018.7)
tzinfo (>= 1.0.0)

PLATFORMS
ruby

DEPENDENCIES
bson_ext
mongo
prometheus-client
puma
rack (>= 2.0.6)
rufus-scheduler
sinatra (~> 2.0.2)
tzinfo-data

BUNDLED WITH
1.17.2
1 change: 1 addition & 0 deletions src/comment/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.3
132 changes: 132 additions & 0 deletions src/comment/comment_app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
require 'sinatra'
require 'json/ext'
require 'uri'
require 'mongo'
require 'prometheus/client'
require 'rufus-scheduler'
require_relative 'helpers'

# Database connection info
COMMENT_DATABASE_HOST ||= ENV['COMMENT_DATABASE_HOST'] || '127.0.0.1'
COMMENT_DATABASE_PORT ||= ENV['COMMENT_DATABASE_PORT'] || '27017'
COMMENT_DATABASE ||= ENV['COMMENT_DATABASE'] || 'test'
DB_URL ||= "mongodb://#{COMMENT_DATABASE_HOST}:#{COMMENT_DATABASE_PORT}"

# App version and build info
if File.exist?('VERSION')
VERSION ||= File.read('VERSION').strip
else
VERSION ||= "version_missing"
end

if File.exist?('build_info.txt')
BUILD_INFO = File.readlines('build_info.txt')
else
BUILD_INFO = Array.new(2, "build_info_missing")
end

configure do
Mongo::Logger.logger.level = Logger::WARN
db = Mongo::Client.new(DB_URL, database: COMMENT_DATABASE,
heartbeat_frequency: 2)
set :mongo_db, db[:comments]
set :bind, '0.0.0.0'
set :server, :puma
set :logging, false
set :mylogger, Logger.new(STDOUT)
end

# Create and register metrics
prometheus = Prometheus::Client.registry
comment_health_gauge = Prometheus::Client::Gauge.new(
:comment_health,
'Health status of Comment service'
)
comment_health_db_gauge = Prometheus::Client::Gauge.new(
:comment_health_mongo_availability,
'Check if MongoDB is available to Comment'
)
comment_count = Prometheus::Client::Counter.new(
:comment_count,
'A counter of new comments'
)
prometheus.register(comment_health_gauge)
prometheus.register(comment_health_db_gauge)
prometheus.register(comment_count)

# Schedule health check function
scheduler = Rufus::Scheduler.new
scheduler.every '5s' do
check = JSON.parse(healthcheck_handler(DB_URL, VERSION))
set_health_gauge(comment_health_gauge, check['status'])
set_health_gauge(comment_health_db_gauge, check['dependent_services']['commentdb'])
end

before do
env['rack.logger'] = settings.mylogger # set custom logger
end

after do
request_id = env['HTTP_REQUEST_ID'] || 'null'
logger.info('service=comment | event=request | ' \
"path=#{env['REQUEST_PATH']}\n" \
"request_id=#{request_id} | " \
"remote_addr=#{env['REMOTE_ADDR']} | " \
"method= #{env['REQUEST_METHOD']} | " \
"response_status=#{response.status}")
end

# retrieve post's comments
get '/:id/comments' do
id = obj_id(params[:id])
begin
posts = settings.mongo_db.find(post_id: id.to_s).to_a.to_json
rescue StandardError => e
log_event('error', 'find_post_comments',
"Couldn't retrieve comments from DB. Reason: #{e.message}",
params)
halt 500
else
log_event('info', 'find_post_comments',
'Successfully retrieved post comments from DB', params)
posts
end
end

# add a new comment
post '/add_comment/?' do
begin
prms = { post_id: params['post_id'],
name: params['name'],
email: params['email'],
body: params['body'],
created_at: params['created_at'] }
rescue StandardError => e
log_event('error', 'add_comment',
"Bat input data. Reason: #{e.message}", prms)
end
db = settings.mongo_db
begin
result = db.insert_one post_id: params['post_id'], name: params['name'],
email: params['email'], body: params['body'],
created_at: params['created_at']
db.find(_id: result.inserted_id).to_a.first.to_json
rescue StandardError => e
log_event('error', 'add_comment',
"Failed to create a comment. Reason: #{e.message}", params)
halt 500
else
log_event('info', 'add_comment',
'Successfully created a new comment', params)
comment_count.increment
end
end

# health check endpoint
get '/healthcheck' do
healthcheck_handler(DB_URL, VERSION)
end

get '/*' do
halt 404, 'Page not found'
end
10 changes: 10 additions & 0 deletions src/comment/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require './comment_app'
require 'rack'
require 'prometheus/middleware/collector'
require 'prometheus/middleware/exporter'

use Rack::Deflater, if: ->(_, _, _, body) { body.any? && body[0].length > 512 }
use Prometheus::Middleware::Collector
use Prometheus::Middleware::Exporter

run Sinatra::Application
6 changes: 6 additions & 0 deletions src/comment/docker_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

echo `git show --format="%h" HEAD | head -1` > build_info.txt
echo `git rev-parse --abbrev-ref HEAD` >> build_info.txt

docker build -t $USER_NAME/comment .
75 changes: 75 additions & 0 deletions src/comment/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
def obj_id(val)
begin
BSON::ObjectId.from_string(val)
rescue BSON::ObjectId::Invalid
nil
end
end

def document_by_id(id)
id = obj_id(id) if String === id
if id.nil?
{}.to_json
else
document = settings.mongo_db.find(_id: id).to_a.first
(document || {}).to_json
end
end

def healthcheck_handler(db_url, version)
begin
commentdb_test = Mongo::Client.new(db_url,
server_selection_timeout: 2)
commentdb_test.database_names
commentdb_test.close
rescue StandardError
commentdb_status = 0
else
commentdb_status = 1
end

status = commentdb_status
healthcheck = {
status: status,
dependent_services: {
commentdb: commentdb_status
},
version: version
}

healthcheck.to_json
end

def set_health_gauge(metric, value)
metric.set(
{
version: VERSION,
commit_hash: BUILD_INFO[0].strip,
branch: BUILD_INFO[1].strip
},
value
)
end

def log_event(type, name, message, params = '{}')
case type
when 'error'
logger.error('service=comment | ' \
"event=#{name} | " \
"request_id=#{request.env['HTTP_REQUEST_ID']}\n" \
"message=\'#{message}\'\n" \
"params: #{params.to_json}")
when 'info'
logger.info('service=comment | ' \
"event=#{name} | " \
"request_id=#{request.env['HTTP_REQUEST_ID']}\n" \
"message=\'#{message}\'\n" \
"params: #{params.to_json}")
when 'warning'
logger.warn('service=comment | ' \
"event=#{name} | " \
"request_id=#{request.env['HTTP_REQUEST_ID']}\n" \
"message=\'#{message}\'\n" \
"params: #{params.to_json}")
end
end
1 change: 1 addition & 0 deletions src/post-py/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Dockerfile
15 changes: 15 additions & 0 deletions src/post-py/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM python:3.6.0-alpine

ENV WORKDIR /app
ENV POST_DATABASE_HOST post_db
ENV POST_DATABASE posts

WORKDIR $WORKDIR
COPY . ./

RUN apk --no-cache --update add build-base && \
pip install --upgrade pip && \
pip install -r requirements.txt && \
apk del build-base

ENTRYPOINT ["python3", "post_app.py"]
1 change: 1 addition & 0 deletions src/post-py/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.0.2
Loading

0 comments on commit d203dac

Please sign in to comment.