처음이라도 할 수 있는, 안전한 환경을 세우는 방법【EC2・Nginx・Unicorn】
11263 단어 nginxRails유니콘EC2CloudFormation
소개
전체 그림은 이런 느낌입니다.
설정합니다.
nginx 측
EC2 서버를 설치하고 nginx를 설치합니다.
# yum -y install nginx
설치 후, nginx의 설정을 만나갑니다.
이 파일은/etc/nginx/nginx.conf에서 작성되었습니다.
코드는 전체적으로 이런 느낌이었던 것 같은... 다르면 죄송합니다.
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.fedora.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
index index.html index.htm;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
set_real_ip_from 172.200.0.0/21;
real_ip_header X-Forwarded-For;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
try_files $uri/index.html $uri @unicorn;
location / {
proxy_pass http://xxx.xxx.xxx.xxxx:8080;
}
}
}
괴롭히는 것은 server의 곳입니다. 꺼내 보겠습니다.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
set_real_ip_from xxx.xxx.xxx.xxxx/21; #←VPCのIPを設定
real_ip_header X-Forwarded-For;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
try_files $uri/index.html $uri @unicorn;
location / {
proxy_pass http://xxx.xxx.xxx.xxxx:8080;#←privateインスタンスのIPを設定、ポート番号も設定する
}
}
수정해야 할 것은 위치 부분입니다. (set_real_ip_from과 real_ip_header는 ALB를 통과했을 때 여기의 코드가 없으면 ALB의 IP 주소가 되어 버리므로, 자사로부터의 액세스인지 어떤지를 판단할 수 있도록 넣고 있습니다)
거기에 지정하면 포트 8080에서 개인 인스턴스에 요청을 전달할 수 있습니다.
시작할 때는 다음 명령입니다.
# nginx
유니콘
Gemfile에 넣고 bundle install하면됩니다.
gem 'unicorn'
unicorn 설정은 다음과 같습니다.
파일은 config/unicorn.rb
$unicorn_user = "user"
$unicorn_group = "user"
worker_processes 16
working_directory '/var/www/app'
listen '/tmp/unicorn.sock', :backlog => 1024
listen 8080, :tcp_nopush => true #←ここを8080にする
timeout 120
pid "/tmp/pids/unicorn.pid"
stderr_path "/var/log/unicorn/unicorn_error.log"
stdout_path "/var/log/unicorn/unicorn.log"
preload_app true
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{ server.config[:pid] }.oldbin"
unless old_pid == server.pid
begin
Process.kill :QUIT, File.read(old_pid).to_i
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
포트 번호를 nginx로 전달하는 포트에 맞춥니다.
시작할 때는 다음 명령입니다.
bundle exec unicorn_rails -c config/unicorn.rb -E development -D
kill 할 때는 다음과 같습니다. unicorn 설정의 pids와 일치합니다.
kill -QUIT `cat /tmp/pids/unicorn.pid`
마지막으로
이제 안전한 환경을 만들 수 있습니다. 같은 환경을 세울 때 귀찮아서 cloudformation으로 만들고 싶습니다.
nginx 구성 파일을 다시 작성합니다.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
set_real_ip_from xxx.xxx.xxx.xxxx/21; #←VPCのIPを設定
real_ip_header X-Forwarded-For;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
try_files $uri/index.html $uri @unicorn;
location / {
proxy_pass http://private_ip_address:8080;#←privateインスタンスのIPを設定、ポート番号も設定する
}
}
위치를 private_ip_address로 수정했습니다. 이런 방식으로 cloudformation 작업을 실행할 때 대체하고 IP를 넣는 전략입니다. 템플릿은 다음과 같습니다.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Green CloudFormation Template for User Production",
"Parameters": {
"KeyName": {
"Type": "AWS::EC2::KeyPair::KeyName"
},
"ALBName": {
"Type": "String",
"Description": "Production ALBName"
},
"LoadBalancerArn": {
"Type": "String",
"Description": "Production ALBName"
},
"VPCID": {
"Type": "String",
"Description": "Production VPC"
},
"PublicSubnetB": {
"Type": "String",
"Description": "Public SubnetId B"
},
"PrivateSubnetB": {
"Type": "String",
"Description": "Private Subnet B"
},
"InstanceSecurityGroupWeb": {
"Type": "String",
"Description": "WebServer SecurityGroup"
},
"InstanceSecurityGroupApp": {
"Type": "String",
"Description": "WebServer SecurityGroup"
},
"SSHGroup": {
"Type": "String",
"Description": "SSH SecurityGroup"
}
},
"Resources": {
"PrivateEc2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-xxxxxxxx",
"InstanceType": "c3.2xlarge",
"IamInstanceProfile": "ApplicationServer",
"SecurityGroupIds": [
{
"Ref": "InstanceSecurityGroupApp"
},
{
"Ref": "SSHGroup"
}
],
"SubnetId": {
"Ref": "PrivateSubnetB"
},
"KeyName": {
"Ref": "KeyName"
},
"Tags": [
{
"Key": "Name",
"Value": "ApplicationServer"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"sudo su\n",
"su user \n",
"cd \n",
"sudo dd if=/dev/zero of=/swapfile bs=1M count=1024\n",
"sudo mkswap /swapfile\n",
"sudo swapon /swapfile\n"
]
]
}
}
}
},
"PublicEc2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-xxxxxxx",
"InstanceType": "t2.small",
"SecurityGroupIds": [
{
"Ref": "InstanceSecurityGroupWeb"
},
{
"Ref": "SSHGroup"
}
],
"SubnetId": {
"Ref": "PublicSubnetB"
},
"KeyName": {
"Ref": "KeyName"
},
"Tags": [
{
"Key": "Name",
"Value": "WebServer"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"sudo su\n",
"su user\n",
"cd \n",
"sudo dd if=/dev/zero of=/swapfile bs=1M count=1024\n",
"sudo mkswap /swapfile\n",
"sudo swapon /swapfile\n",
"sudo sed -i \"s/private_ip_address/",
{
"Fn::GetAtt": [
"PrivateEc2Instance",
"PrivateIp"
]
},
"/g\" /etc/nginx/nginx.conf \n",
"sudo su \n",
"service nginx start \n"
]
]
}
}
}
},
"ALBTarget": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"HealthCheckIntervalSeconds": "30",
"HealthCheckPath": "/login",
"HealthCheckPort": "traffic-port",
"HealthCheckProtocol": "HTTP",
"HealthCheckTimeoutSeconds": "5",
"HealthyThresholdCount": "5",
"Matcher": {
"HttpCode": "200"
},
"Name": {
"Ref": "ALBName"
},
"Port": "80",
"Protocol": "HTTP",
"Targets": [
{
"Id": {
"Ref": "PublicEc2Instance"
},
"Port": "80"
}
],
"UnhealthyThresholdCount": "2",
"VpcId": {
"Ref": "VPCID"
}
}
}
}
}
이것이 기존 ALB의 타겟 그룹에 작성한 EC2를 넣고 nginx와 unicorn의 접속을 가능하게 한 것입니다.
webserver의 UserData 부분에 엉망진창 코드를 넣고 있습니다. 여기서 대체를 하여 연결을 가능하게 하고 있습니다. 또한 스왑 설정도 필요하므로 넣어 두었습니다.
nginx가 시작되지 않았기 때문에 그 설정도 넣어 두었습니다.
끝에
cloudformation으로 템플릿을 만들어 두면 같은 구성의 것을 만들 때 꽤 편해지므로 추천합니다. 또 AMI의 ID 지정으로 그 상태의 것을 사용해 구축할 수 있으므로 이것도 큰 메리트구나-라고 사용해 생각했습니다.
Reference
이 문제에 관하여(처음이라도 할 수 있는, 안전한 환경을 세우는 방법【EC2・Nginx・Unicorn】), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/katsuyuki/items/028685e7bcb2ccd0ab2e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)