Skip to content

Instantly share code, notes, and snippets.

@steve-chavez
Created June 1, 2020 00:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steve-chavez/683da01894ecfa96af09bdbb7b63d543 to your computer and use it in GitHub Desktop.
Save steve-chavez/683da01894ecfa96af09bdbb7b63d543 to your computer and use it in GitHub Desktop.
Nix file for deploying https://stevechavez.xyz.
# From: https://stevechavez.xyz/nixops-blog.html
let
region = "us-east-2";
accessKeyId = "dev";
in {
network.description = "stevechavez.xyz";
resources = {
ec2KeyPairs.xyzKeyPair = { inherit region accessKeyId; };
elasticIPs.xyzIP = { inherit region accessKeyId; };
ec2SecurityGroups.xyzGroup = {
inherit region accessKeyId;
name = "xyz-group";
description = "stevechavez.xyz security group";
rules = [
{ fromPort = 22; toPort = 22; sourceIp = "0.0.0.0/0"; }
{ fromPort = 80; toPort = 80; sourceIp = "0.0.0.0/0"; }
{ fromPort = 443; toPort = 443; sourceIp = "0.0.0.0/0"; }
];
};
};
main = { config, pkgs, resources, ... }: {
deployment = {
targetEnv = "ec2";
ec2 = {
inherit region accessKeyId;
instanceType = "t2.nano";
associatePublicIpAddress = true;
keyPair = resources.ec2KeyPairs.xyzKeyPair;
elasticIPv4 = resources.elasticIPs.xyzIP;
securityGroups = [ resources.ec2SecurityGroups.xyzGroup ];
};
};
time.timeZone = "America/Lima";
environment.systemPackages = [
pkgs.vim
pkgs.cloud-utils # For growpart. If we don't have this from the start, we risk not having enough space to install it and resizing the disk.
];
# Disallow ssh login with password
services.openssh = {
passwordAuthentication = false;
challengeResponseAuthentication = false;
};
# For DNS-01 challenge
security.acme = {
acceptTerms = true;
email = "stevechavezast@gmail.com";
certs."stevechavez.xyz" = {
extraDomains = {
"www.stevechavez.xyz" = {};
};
group = "nginx";
allowKeysForGroup = true;
dnsProvider = "namesilo";
#pkgs.writeText "namesilo.env" ''env vars here'' can be used for defining this inline
credentialsFile = "${./secrets/namesilo.env}";
#The file contents are like:
#NAMESILO_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
#NAMESILO_PROPAGATION_TIMEOUT=1800
#NAMESILO_POLLING_INTERVAL=120
#Getting the cert can take a long time, like 15 to 30 mins.
#That's why setting the propagation time is important. Otherwise the service will fail.
};
};
# By default it logs to /var/spool/nginx.
# For getting a log file from the remote nixos machine use:
# nixops scp -d xyz --from main /var/spool/nginx/logs/access.log .
services.nginx = {
enable = true;
config = ''
# run nproc
worker_processes 1;
events {
# run ulimit -n
worker_connections 1024;
}
http {
server_tokens off;
# limit clients doing too many requests
# can be tested with ab -n 20 -c 10 <host>
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
# limit clients opening too many connections
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
include ${pkgs.nginx}/conf/mime.types;
log_format main '$request_id|$remote_addr|$time_local'
'|$request_uri|$request_method|$status|$body_bytes_sent|"$http_referer"'
'|"$http_user_agent"|"$http_x_forwarded_for"|"$request_time"|"$request"';
access_log logs/access.log main buffer=32k flush=5m;
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl;
ssl_certificate ${config.security.acme.certs."stevechavez.xyz".directory}/fullchain.pem;
ssl_certificate_key ${config.security.acme.certs."stevechavez.xyz".directory}/key.pem;
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
# Send gzip header
gzip on;
gzip_vary on;
# What media types to compress
gzip_types
application/atom+xml
application/javascript
application/json
application/xml
application/xml+rss
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
# limit clients payload size
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
# limit clients slow connections(slowloris)
client_body_timeout 5s;
client_header_timeout 5s;
# optimization for sending files
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# apply limits
limit_req zone=req_limit_per_ip burst=20 nodelay;
limit_conn conn_limit_per_ip 10;
root ${./public};
index index.html;
error_page 404 /404.html;
error_page 410 /410.html;
location / {
try_files $uri $uri/ =404;
}
}
## Can only be accesed with curl http://127.0.0.1/nginx_status
server {
listen 127.0.0.1:80;
server_name 127.0.0.1;
location /nginx_status {
stub_status;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}
'';
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment