Project

General

Profile

Redmine

Costs

Instance: $42 / year (Reserved Instance)
Domain: $90 / year (Jp Domain)

Instance

Region: Tokyo
Type: t3.nano
Image: Debian GNU/Linux 9 (Stretch)

Install

Debian Wiki - Redmine通りにオペレーションして特に問題なし
パッケージはRDS代が払えないのでredmine-sqliteにした

CloudFront

Path Pattern Origin Path Origin Cache
/javascripts/* S3-aretan.jp /usr/share/redmine/public/javascripts/ on
/stylesheets/* S3-aretan.jp /usr/share/redmine/public/stylesheets/ on
/images/* S3-aretan.jp /usr/share/redmine/public/images/ on
/themes/* S3-aretan.jp /usr/share/redmine/public/themes/ on
/help/* S3-aretan.jp /usr/share/redmine/public/help/ on
/plugin_assets/* S3-aretan.jp /var/cache/redmine/default/plugin_assets/ on
/attachments/download/* EC2 Passenger on
Default (*) EC2 Passenger off

Security

対策箇所 対策内容
CloudFront HTTPS Termination
Geo Restrictions
Set Origin Custom Header
S3 Origin Access Identity
EC2 SecurityGroup SSH IP Whitelist
Debian unattended-upgrades
sshguard
Redmine Validate Origin Custom Header

Apache

/etc/apache2/apache2.conf

KeepAliveTimeout 120
Timeout 5

/etc/apache2/sites-enabled/redmine.conf

ServerName     aretan.jp
RemoteIPHeader X-Forwarded-For

/etc/apache2/mods-enabled/mpm_event.conf

StartServers             2
MinSpareThreads          2
MaxSpareThreads          2
ThreadsPerChild          2
MaxRequestWorkers        2
MaxConnectionsPerChild   0

/etc/apache2/mods-enabled/passenger.conf

PassengerPreStart           http://aretan.jp/
PassengerFriendlyErrorPages off
PassengerHighPerformance    on
PassengerMaxPoolSize        1
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"

Benchmark

Concurrency Level:      100
Time taken for tests:   87.199 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      18883000 bytes
HTML transferred:       18094000 bytes
Requests per second:    11.47 [#/sec] (mean)
Time per request:       8719.943 [ms] (mean)
Time per request:       87.199 [ms] (mean, across all concurrent requests)
Transfer rate:          211.47 [Kbytes/sec] received
top - 17:09:06 up  4:05,  2 users,  load average: 0.87, 0.54, 0.24
Tasks:  79 total,   1 running,  78 sleeping,   0 stopped,   0 zombie
%Cpu(s): 97.0 us,  3.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   502452 total,   123908 free,   279100 used,    99444 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   206056 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 8566 www-data  20   0  468116 177256  10436 S 98.0 35.3   0:57.05 Passenger RubyApp: redmine_default
 8551 www-data  20   0  330868 116664  14836 S  0.0 23.2   0:02.82 Passenger AppPreloader: /usr/share/redmine
 8518 root      20   0  658644  11496   9572 S  0.0  2.3   0:00.21 Passenger core

プラグイン追加のオペレーション

# cd /usr/share/redmine
# # put plugin into /usr/share/redmine/plugins/
# bundle install
# rake redmine:plugins:migrate RAILS_ENV=production
# sudo service apache2 restart

ファイル更新のオペレーション

# cd /usr/share/redmine
# # edit static file
# aws s3 cp stylesheets/application.css s3://aretan.jp/stylesheets/application.css --cache-control max-age=604800 --storage-class REDUCED_REDUNDANCY
# aws cloudfront create-invalidation --distribution-id E3RKCYCW0QF7RA --paths /stylesheets/application.css

Embedded Tweets

/usr/share/redmine/app/views/layouts/base.html.erb

<%= stylesheet_link_tag 'oembed/jquery.oembed.min.css' %>
<%= javascript_include_tag "oembed/jquery.oembed.min.js" %>
<script type="text/javascript">
$(document).ready(function(){
  $("a[href^='https://twitter.com/aretan/status/']").oembed(null,{
    embedMethod: 'fill',
  });
});
</script>

Crontab DB Backup

0 6 * * * aws s3 cp /var/lib/dbconfig-common/sqlite3/redmine/instances/default/redmine_default s3://back.aretan.jp/$(date +\%Y\%m\%d).db