Running NiFi in a Docker Container

Running NiFi in a Docker Container

Summary

I've written a few articles on Apache NiFi and how to install it on Ubuntu. I recently ran into a situation where it wasn't possible to install NiFi directly, but it could be run via a docker container. Fortunately there are Apache NiFi docker images to accomplish this. We'll be using docker-compose in this example.

Setup

The first assumption is that you already have docker up and running, and ports 514/tcp, 514/udp, 8080/tcp, and 8443/tcp are available. You can always change these in the docker-compose.yml file too. We'll also create a few volumes that can be used for persistence: the cert directory for certificates, and the drivers directory for things like MaxMind or JDBC drivers. This will get created automatically once we bring up the container.

sudo mkdir -p /opt/nifi
sudo chown -R 1000:1000 /opt/nifi

The next step is to create the docker-compose file. First do the following:

sudo mkdir -p /opt/dockerfile/nifi
sudo vi /opt/dockerfiles/nifi/docker-compose.yml

And then add the following to the above file:

version: '3'

services:
  nifi:
    cap_add:
      - NET_ADMIN # low port bindings
    image: apache/nifi
    container_name: nifi
    ports:
      - "8080:8080/tcp" # HTTP interface
      - "8443:8443/tcp" # HTTPS interface
      - "514:514/tcp" # Syslog
      - "514:514/udp" # Syslog
      - "2055/udp:2055/udp" # NetFlow
    volumes:
      - /opt/nifi/drivers:/opt/nifi/nifi-current/drivers
      - /opt/nifi/certs:/opt/certs
      - nifi-conf:/opt/nifi/nifi-current/conf
    restart: unless-stopped

volumes:
  nifi-conf:

Next we'll bring up the containers with the following command:

cd /opt/dockerfiles/nifi/
sudo docker-compose up -d

# If you want to watch the output.
sudo docker logs -f nifi

Now that it's up, we'll tweak a few configuration options to add more RAM:

# Enter the docker container as root.
sudo docker exec -u 0 -it nifi bash

# At this point we're in the docker container.
# Install vim since nobody seems to think a text editor was necessary.
apt-get install vim

# Edit the NiFi bootstrap configuration.
vi /opt/nifi/nifi-current/conf/bootstrap.conf

# Edit out the following lines and change them.
# JVM memory settings
#java.arg.2=-Xms512m
#java.arg.3=-Xmx512m
java.arg.2=-Xms2g
java.arg.3=-Xmx2g

# Exit the docker container.
exit

# At this point we're back on the host.
# Restart the docker container.
sudo docker restart nifi

Conclusion

...and that's it. Once finished, you'll be able to access NiFi on port 8080 on the hosts, e.g. http://nifi.domain.local:8080/nifi.

Bonus! SSL and Authentication for NiFi

Disclaimer

This isn't the best security, but it's better than nothing. Configuring NiFi for authentication isn't the easiest process in the world. In this example we'll be using an NGINX docker container to act as an SSL front-end for unencrypted NiFi, and add basic user authentication on top of that.

Setup

We'll first create the directories:

sudo mkdir -p /opt/nginx/conf /opt/nginx/keys /opt/nifi/drivers /opt/dockerfiles/nifi/

We'll then create a self-signed SSL certificate for NGINX:

cd /opt/nginx/keys
sudo openssl req -x509 -sha256 -newkey rsa:2048 -keyout certificate.key -out certificate.crt -days 1024 -nodes -subj '/CN=my.domain.internal'

You'll end up with two files: certificate.key and certificate.crt. We'll be using these in the NGINX configuration to enable SSL. Next, we'll create the NGINX configuration file.

sudo vi /opt/nginx/conf/nginx.conf

Add the following to the file above:

events {
}

http {
  server {
    listen 8443 ssl;
    server_name my.domain.internal;
    ssl_certificate /keys/certificate.crt;
    ssl_certificate_key /keys/certificate.key;
    proxy_ssl_certificate /keys/certificate.crt;
    proxy_ssl_trusted_certificate /keys/certificate.key;

    location /nifi {
      proxy_pass http://nifi:8080;
      proxy_set_header Host $http_host;
      proxy_set_header X-ProxyScheme https;
      auth_basic "NiFi Authentication";
      auth_basic_user_file /keys/nginx.htpasswd;
    }
  }
}

We'll now use a modified docker-compose.yml from the original steps.

sudo vi /opt/dockerfiles/nifi/docker-compose.yml

Add the following to the file above:

version: '3'

services:
  nifi:
    cap_add:
      - NET_ADMIN # low port bindings
    image: apache/nifi
    container_name: nifi
    ports:
      - "514:514/tcp" # Syslog
      - "514:514/udp" # Syslog
      - "2055:2055/udp" # NetFlow
    volumes:
      - /opt/nifi/drivers:/opt/drivers
      - nifi-conf:/opt/nifi/nifi-current/conf
    restart: unless-stopped

  nginx:
    image: nginx
    container_name: nginx
    volumes:
      - /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - /opt/nginx/keys:/keys
    ports:
      - "8443:8443/tcp" # HTTPS interface
    restart: unless-stopped

volumes:
  nifi-conf:

Next we'll create a password for user authentication. You'll need htpasswd installed, or you can find a site that will generate one for you. Please note this is using md5 for the encryption since bcrypt doesn't always seem to play nice.

htpasswd -n admin > /opt/nginx/keys/nginx.htpasswd

# Checking the file for output.
cat /opt/nginx/keys/nginx.htpasswd
admin:$apr1$cUjKlTPI$KlnGph95k4OEBGSA3MSac0

Finally, let's bring up the docker containers:

cd /opt/dockerfiles/nifi
docker-compose up -d

Conclusion

At this point you should be prompted to log in when attempting to access NiFi. Please note that your URL will look something like this:

https://nifi.domain.local:8443/nifi

You'll need to use the port specified above and nifi at the end of the URL. Hope the helps!

Show Comments