DEV Community

Binaya Sharma
Binaya Sharma

Posted on • Originally published at Medium

Basic Authentication in Nginx with docker-compose

In this tutorial we are going to secure a deployment in which we are exposing application using reverse proxy. We will be using nginx in-front of nextjs application, and authenticating using simple auth. There could be multiple reason we would like it to do such as limiting access to the certain environment (may be development before big release to whole world)

Let us take a trivial docker-compose. I am taking example from the article.

docker-compose.yaml

version: '3.8'
services:
  nextjs:
    build:
      context: .
      dockerfile: Dockerfile.multistage
    container_name: nextjs_app
    ports:
      - "3000:3000"
    restart: unless-stopped
Enter fullscreen mode Exit fullscreen mode

Now we would like to introduce nginx in front of nexjs application. And this will have basic auth mechanism within it.

Now let us generate password (This will be md5 hash). We can use temporary docker to generate htpasswd which later will be used to mount.

$ docker run --rm httpd htpasswd -nb myuser mypassword > htpasswd

Enter fullscreen mode Exit fullscreen mode

Also, let us create a nginx.conf.

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    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;
    keepalive_timeout 65;

    server {
        listen 80;
        server_name localhost;

        location / {
            auth_basic "Restricted Access";
            auth_basic_user_file /etc/nginx/.htpasswd;

            proxy_pass http://nextjs:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Dockerfile for nginx

FROM nginx:latest

# Remove the default Nginx configuration file
RUN rm /etc/nginx/conf.d/default.conf

# Copy the custom Nginx configuration file
COPY nginx.conf /etc/nginx/nginx.conf

# Copy the htpasswd file
COPY htpasswd /etc/nginx/.htpasswd

# Expose port 80
EXPOSE 80

# Start Nginx when the container launches
CMD ["nginx", "-g", "daemon off;"]
Enter fullscreen mode Exit fullscreen mode

Now the docker-compose will look like

version: '3.8'
services:
  apache:
    build:
      context: . 
      dockerfile: Dockerfile.nginx
    container_name: nginx
    ports:
      - "8181:80"

  nextjs:
    build:
      context: .
      dockerfile: Dockerfile.multistage
    container_name: nextjs_app
    restart: unless-stopped
Enter fullscreen mode Exit fullscreen mode

Now we should be able to see a dialogue box before accessing nextjs application.

Image description

How to add additional Users ?

You can simply run the command for creating a new user.

$ docker run --rm httpd htpasswd -nb user2 password >> htpasswd
Enter fullscreen mode Exit fullscreen mode

And re-run docker-compose.

This will append new user.

Top comments (2)

Collapse
 
nevodavid profile image
Nevo David

nice setup for quick security, but i always wonder if basic auth is good enough long-term or if i should bother with something tougher?

Collapse
 
bs14 profile image
Binaya Sharma

We can have a strong password policies developed around setting it up. But in today's security landscape nothing is good enough, and it is good enough only upto the point we are secure.
Basically we have multiple options, such as we can leverage tools such as fail2ban along with basic auth. This could provide some additional security layer.

For my use-case i am using basic auth just to protect my internal tools. If anything is going out in the web and should only be accessible within organization, solutions like cloudflare zero trust could be alot handy.