How to setup HTTP server with security headers using Nginx docker
Published: 2022-04-07 20:59:57

Nginx is one of the most commonly used, familiar, and trustworthy Web-Server (among other things) that are out there today.
We migrated from http-server to Nginx for multiple reasons, the most recent one was adding security headers to our requests.
you can check your site security headers at: https://securityheaders.com
this guide will easily take you from zero to hero :)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmgfa4i8rn4ahnzckzop.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s07lc9ufvqb0yxx9i1ff.png)

## Why security headers are important?
many websites and systems can be hacked due to a lack or bad configuration or lack of protection. Besides improving your site's SEO score, Security headers will protect your website from some common attacks like Code injection, XSS, click-jacking, and more.
For my personal use, I choose to use the following HTTP security headers:

1. X-Content-Type-Options "nosniff"
_This prevents the browser from "sniffing" the asset to try and determine if the file type is something other than what is declared by the server_

2. X-Frame-Options "sameorigin"
_The page can only be embedded in a frame on a page with the same origin as itself_

3. X-XSS-Protection "1; mode=block"
_Enables XSS filtering. Rather than sanitizing the page, the browser will prevent rendering of the page if an attack is detected_

4. Strict-Transport-Security "max-age=31536000; includeSubDomains"
_informs browsers that the site (and subdomains) should only be accessed using HTTPS_

5. Content-Security-Policy "default-src 'self';
_Allow to load content and resources only from your domain only_

6. 'Permissions-Policy' "camera=none, geolocation=none, microphone=none"
_Permissions Policy (formerly known as feature policy) allows web developers to selectively enable, disable, and modify the behavior of certain APIs and web features in the browser_.
you can generate your header easily using this cute online utility:[permissionspolicy](https://www.permissionspolicy.com/)

7. 'Referrer-Policy' 'sameorigin'
_The Referrer Policy HTTP header sets the parameter for amount of information sent along with Referrer Header while making a request
sameorigin sends referrer information when origin is on same website but no information is sent for cross origin._

## Step 1 - Creating Nginx Configuration file
create/edit the following file `/etc/nginx/conf.d/nginx.conf`
`server {
    listen 8080;
    root {{your_root_path}};
add_header 'X-Content-Type-Options'  'nosniff';
    add_header 'X-Frame-Options' 'sameorigin';
    add_header 'X-XSS-Protection' '1; mode=block';
    add_header 'Strict-Transport-Security' 'max-age=31536000; includeSubDomains; preload';
    add_header 'Cache-control' 'no-cache';
    add_header 'Content-Security-Policy' "default-src 'self'; font-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; frame-src 'self'";
    add_header 'Permissions-Policy' 'camera=(), geolocation=(), microphone=()';
    add_header 'Referrer-Policy' 'same-origin';
}`
if you are using SPA (like react or vue), and your site stops working due for 'Content-Security-Policy' try the following header (with google fonts and analytics)
`add_header 'Content-Security-Policy' "default-src 'none';img-src 'self'; connect-src https://www.google-analytics.com/; script-src 'self' www.google-analytics.com 'unsafe-inline'; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com; base-uri 'self';";`

## Step 2- Creating DockerFile

create an file named `Dockerfile`

`FROM nginx:stable-alpine`

`# copy both "package.json" and "package-lock.json" (if available)`
`COPY {{project_path}}/nginx.conf /etc/nginx/conf.d/default.conf`
`#assuming that your site files are on a dist folder
COPY {{project_path}}/dist /usr/share/nginx/html
"]`

`EXPOSE 8080`

## Step 3 - Build & Run the docker image

1. build the docker image using
`docker build -t {{image_tag_name}} -f {{project_path}}/Dockerfile .`
2. run the docker image `$ docker run --name {{container_name}} -p 8080:80 -d {{image_tag_name}}`

Well, that's it! now you can enjoy your new secured HTTP server and stronger SEO score :)