Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker 4 #3

Merged
merged 8 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 74 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ yc compute instance create \
```shell
docker-machine --debug create \
--driver generic \
--generic-ip-address=51.250.84.88 \
--generic-ip-address=51.250.92.127 \
--generic-ssh-user yc-user \
--generic-ssh-key ~/.ssh/id_ed25519 \
docker-host
Expand All @@ -43,3 +43,76 @@ docker push baykanurov/otus-reddit:1.0
```shell
docker pull baykanurov/otus-reddit:1.0
```

## Docker-3
### Что было сделано:
1. Написал Dockerfile и собрал образ для каждого из сервисов приложения:
- **post-py**
- **comment**
- **ui**
```shell
docker build -t baykanurov/post:1.0 ./post-py
docker build -t baykanurov/comment:1.0 ./comment
docker build -t baykanurov/ui:1.0 ./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
```

## Docker-4
### Что было сделано:
- Изучено как работают сети Docker
- Написан docker-compose для сервисов нашего приложения
- Параметризированы значения в docker compose для:
- тегов образов для всех сервисов
- порт публикации сервиса ui
- username
- Также для всех параметров добавлены default values
- Задано имя для каждого контейнера
- Имя проекта можно задать через name в docker-compose
### Дополнительное задание
Добавил файл docker-compose.override.yml который пробрасывает код сервиса как volume и добавляет возможность запускать puma для руби приложений в дебаг
режиме с двумя воркерами
6 changes: 6 additions & 0 deletions src/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
USERNAME=test
MONGO_IMAGE_TAG=4.4
UI_IMAGE_TAG=1.0
POST_IMAGE_TAG=1.0
COMMENT_IMAGE_TAG=1.0
UI_PORT=9292
6 changes: 6 additions & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
build_info.txt
prometheus/
.env

## 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

CMD ["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 .
Loading
Loading