Digital Ocean Initial Server Setup Guide

Initial Setup
https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04

Securing VPS
https://www.digitalocean.com/community/tutorials/an-introduction-to-securing-your-linux-vps

Hostname
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-host-name-with-digitalocean

Nginx
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-14-04-lts

Tomcat
https://www.digitalocean.com/community/tutorials/how-to-install-apache-tomcat-8-on-ubuntu-14-04

Basic Nginx Reverse Proxy Configuration for Atlassian Jira, Confluence, and Bamboo

This is a template Nginx configuration I use to reverse proxy for my test instances in Amazon AWS using Amazon Linux instances.  This configuration uses virtual hosts and TLS 1.2. Additional configuration may be required at the DNS level to support the subdomains used here.

Configuration Location:

/etc/nginx/nginx.conf

Contents:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

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   300;
    types_hash_max_size 2048;
    proxy_connect_timeout 75;
    proxy_read_timeout 300;
    proxy_send_timeout 300;
    send_timeout 300;

    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;
        server_name jira.{your-domain}.com;
        rewrite ^ https://$server_name$request_uri? permanent;
    }

    server {
        listen 80;
        server_name confluence.{your-domain}.com;
        rewrite ^ https://$server_name$request_uri? permanent;
    }

    server {
        listen 80;
        server_name bamboo.{your-domain}.com;
        rewrite ^ https://$server_name$request_uri? permanent;
    }

    server {
        listen       443 ssl;
        listen       [::]:443 ssl;

        # SSL/TLS Configuration
        ssl_certificate {PATH-TO-CERT};
        ssl_certificate_key {PATH-TO-CERT-KEY};
        ssl_protocols TLSv1.2;
        ssl_ciphers {SSL-Ciphers}
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 10m;
        ssl_session_cache shared:SSL:1m;
        ssl_dhparam "{PATH-TO-GENERATED-DHPARAM}";

        server_name jira.{your-domain}.com;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass https://{internal-ip-to-jira}:{internal-port-to-jira}/;
        }
    }

    server {
        listen       443 ssl;
        listen       [::]:443 ssl;

        # SSL/TLS Configuration
        ssl_certificate {PATH-TO-CERT};
        ssl_certificate_key {PATH-TO-CERT-KEY};
        ssl_protocols TLSv1.2;
        ssl_ciphers {SSL-Ciphers}
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 10m;
        ssl_session_cache shared:SSL:1m;
        ssl_dhparam "{PATH-TO-GENERATED-DHPARAM}";

        server_name confluence.{your-domain}.com;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass https://{internal-ip-to-confluence}:{internal-port-to- confluence }/;
        }
    }

    server {
        listen       443 ssl;
        listen       [::]:443 ssl;

        # SSL/TLS Configuration
        ssl_certificate {PATH-TO-CERT};
        ssl_certificate_key {PATH-TO-CERT-KEY};
        ssl_protocols TLSv1.2;
        ssl_ciphers {SSL-Ciphers}
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 10m;
        ssl_session_cache shared:SSL:1m;
        ssl_dhparam "{PATH-TO-GENERATED-DHPARAM}";

        server_name bamboo.{your-domain}.com;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass https://{internal-ip-to- bamboo}:{internal-port-to-bamboo}/;
        }
    }
}

For SSL

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
openssl dhparam -check -out /etc/nginx/ssl/dhparams.pem 2048
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK
sudo service nginx restart

Impact of Decisions on Agile Scrum

Wrote a white paper on the impact of decisions (sprint length, scrum time, prioritization, estimation process, etc.) on agile scrum projects.  Part 1 of the series. I’m planning to get more in-depth in the next one.

http://kastling.com/wp-content/uploads/2016/02/White-Paper-Impact-of-Decisions-on-Agile-Scrum.pdf

Multipart Configuration for JBoss Enterprise Application Platform/Application Server

Spring REST controller on Spring Boot (1.12) was not accepting multi-part requests for file upload on JBoss EAP/AS but working on Embedded Tomcat.

org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present

I needed to add a multipart filter on my web xml configuration in Java

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableJpaRepositories
@EnableSpringDataWebSupport
public class Application extends SpringBootServletInitializer {

 @Override
 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
 return application.sources(Application.class);
 }

 @Override
 public void onStartup(ServletContext servletContext) throws ServletException {
 WebApplicationContext context = createRootApplicationContext(servletContext);
 ServletRegistration.Dynamic servletRegistration = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
 servletRegistration.setLoadOnStartup(1);
 servletRegistration.addMapping("/*"); // required JBOSS EAP
 servletRegistration.setMultipartConfig(getMultiPartConfig()); // fixes multipart requests
 super.onStartup(servletContext);
 }

 private MultipartConfigElement getMultiPartConfig() {
 String location = "";
 long maxFileSize = -1;
 long maxRequestSize = -1;
 int fileSizeThreshold = 0;
 return new MultipartConfigElement(
 location,
 maxFileSize,
 maxRequestSize,
 fileSizeThreshold
 );
 }

 public static void main(String[] args) {
 SpringApplication.run(Application.class, args);
 }
}

My Spring and web.xml is configured via Java annotations.

I found this post for this configuration: http://stackoverflow.com/questions/19293862/how-make-the-setmultipartconfig-work-for-a-dynamic-added-servlet

Story Point Estimation

Story points should reflect the complexity and effort required to complete the story.  If points are purely based on complexity, it can inaccurately represent a relatively simple task that requires a lot of repetitive effort.  If points are purely based on effort, it may not reflect the potential risks involved with the complexity of the task.

Story points should be relative to a reference story (it should not necessarily correlate to the number of task hours).  The number of hours are dependent on who works on the story, so story points should be based on a another story. Attempting to correlate the two will lead to extra work with little or no value if there are more than one member in a team.

The numbers should accurately represent the size relationship for better velocity estimation.  For example, if we use story pointing system (1, 2, 4, 8), a story with 4 points should be about double the [effort/complexity estimation of] story with 2 points.  The point system should not start with 0 because a hundred 0 point stories adds 0 points to the team velocity. It should also not have granular differences for the larger numbers as this should be a rough estimation where some stories are slightly more or less than estimated.

Ideal Agile Daily Scrum Time

I personally don’t like daily scrum in the mornings for a local team (without members in different timezones).

Early Morning Scrum
Late comers may miss stand up.  Difficult to start work knowing stand up is in within 30 min after arrival.

Late Morning Scrum
Work day tends to start later as some members consider daily scrum time to be the beginning of the work day.

Early Afternoon Scrum
After lunch, team may have food coma.  Probably the least productive time anyway.

Late Afternoon Scrum
Early goers may miss stand up. Team may develop a practice of checking out after stand up.

I think the best time is early afternoon, at least in my experience.  Any impediments or announcements should be escalated immediately as they arise regardless of when daily scrum is held.

Quickbooks Invoice does not show Service Date

We use quickbooks for invoicing, and the new invoices were missing the “Service Date” column in the preview and the final invoice. I called Intuit support, waited ~20 minutes on hold, but eventually got the answer.

It seems like they’ve added a new feature that needs to be checked in order for the service date to show.

Gear Icon -> Company Settings -> Sales -> Sales form Content -> Service Date (on)
1s

Also ensure Gear Icon -> Company Settings -> Sales -> Customize Sales Forms -> Activity Table Columns -> Date (on)
2