Skip to content

Instantly share code, notes, and snippets.

@dignoe
Created March 8, 2017 23:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dignoe/63cea6924a885028f3c2c3430343881d to your computer and use it in GitHub Desktop.
Save dignoe/63cea6924a885028f3c2c3430343881d to your computer and use it in GitHub Desktop.
Automatic maintenance page on migrate with AWS OpsWorks + Rails
# Disable maintenance page
Chef::Log.info("Disabling maintenance page")
file "/srv/www/your_app/shared/system/maintenance.html" do
action :delete
end
# Enable maintenance page
Chef::Log.info("Enabling maintenance page")
if node["deploy"]["your_app"]["migrate"]
file "/srv/www/your_app/shared/system/maintenance.html" do
owner node["deploy"]["your_app"]["user"]
group node["deploy"]["your_app"]["group"]
mode 0755
content ::File.open("#{release_path}/deploy/maintenance.html").read
action :create
end
end
<!DOCTYPE html>
<html>
<head>
<title>Your site is being upgraded</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<header>
<div id="logo-container">
<a href="/" class="logo"></a>
</div>
</header>
<div id="content">
<h1 class="center-text">Your site is being upgraded</h1>
<p class="center-text">
Our engineers are currently upgrading the site. Please check back in a few minutes.
</p>
</div>
</body>
</html>
upstream unicorn_<%= @application[:domains].first %> {
server unix:<%= @application[:deploy_to]%>/shared/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name <%= @application[:domains].join(" ") %> <%= node[:hostname] %>;
<% if @application[:log_format] %>
<% @application[:log_format].each do |log_format_name| %>
access_log <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>.access.<%= log_format_name %>.log <%= log_format_name %>;
<% end %>
<% else %>
access_log <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>.access.log;
<%end %>
keepalive_timeout 5;
root <%= @application[:absolute_document_root] %>;
<% if @application[:nginx] && @application[:nginx][:client_max_body_size] %>
client_max_body_size <%= @application[:nginx][:client_max_body_size] %>;
<% end %>
location / {
if (-f <%= @application[:absolute_document_root] %>system/maintenance.html) {
return 503;
}
try_files $uri/index.html $uri/index.htm @unicorn;
}
location = /ping {
try_files $uri/index.html $uri/index.htm @unicorn;
}
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
<% if node[:nginx] && node[:nginx][:proxy_read_timeout] -%>
proxy_read_timeout <%= node[:nginx][:proxy_read_timeout] %>;
<% end -%>
<% if node[:nginx] && node[:nginx][:proxy_send_timeout] -%>
proxy_send_timeout <%= node[:nginx][:proxy_send_timeout] %>;
<% end -%>
# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://unicorn_<%= @application[:domains].first %>;
break;
}
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
error_page 500 502 504 /500.html;
location = /500.html {
root <%= @application[:absolute_document_root] %>;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /system/maintenance.html break;
}
}
<% if @application[:ssl_support] %>
server {
listen 443;
server_name <%= @application[:domains].join(" ") %> <%= node[:hostname] %>;
access_log <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>-ssl.access.log;
ssl on;
ssl_certificate /etc/nginx/ssl/<%= @application[:domains].first %>.crt;
ssl_certificate_key /etc/nginx/ssl/<%= @application[:domains].first %>.key;
<% if @application[:ssl_certificate_ca] -%>
ssl_client_certificate /etc/nginx/ssl/<%= @application[:domains].first %>.ca;
<% end -%>
keepalive_timeout 5;
root <%= @application[:absolute_document_root] %>;
<% if @application[:nginx] && @application[:nginx][:client_max_body_size] %>
client_max_body_size <%= @application[:nginx][:client_max_body_size] %>;
<% end %>
location / {
if (-f <%= @application[:absolute_document_root] %>system/maintenance.html) {
return 503;
}
try_files $uri/index.html $uri/index.htm @unicorn;
}
location = /ping {
try_files $uri/index.html $uri/index.htm @unicorn;
}
location @unicorn {
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
<% if node[:nginx] && node[:nginx][:proxy_read_timeout] -%>
proxy_read_timeout <%= node[:nginx][:proxy_read_timeout] %>;
<% end -%>
<% if node[:nginx] && node[:nginx][:proxy_send_timeout] -%>
proxy_send_timeout <%= node[:nginx][:proxy_send_timeout] %>;
<% end -%>
# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://unicorn_<%= @application[:domains].first %>;
break;
}
}
error_page 500 502 504 /500.html;
location = /500.html {
root <%= @application[:absolute_document_root] %>;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /system/maintenance.html break;
}
}
<% end %>
@dignoe
Copy link
Author

dignoe commented Mar 8, 2017

nginx_unicorn_web_app.erb should be in your custom cookbooks under unicorn/templates/default. This is current as of AWS cookbooks v3443: https://github.com/aws/opsworks-cookbooks/blob/v3443/unicorn/templates/default/nginx_unicorn_web_app.erb.

@dignoe
Copy link
Author

dignoe commented Mar 8, 2017

Note that this does work behind an AWS elastic load balancer (ELB). Just make sure your health check is checking /ping, or change the location in your nginx config file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment