Deploy a Persistent Kubernetes Application with Portainer

I’ve been quite vocal over the past year as to how much I depend on Portainer as my container management platform. But not only is it great for managing containers, it’s also an outstanding platform for learning the ins and outs of working with containers.
For example, one thing you can do with relative ease is to deploy a container with a persistent volume. Why would you need to do that? Consider this: You build a website, using the NGINX container image. You’ve carefully constructed the container and built the website. If you do everything within the container, should something happen to the container, you could lose all of that precious work.
Instead, it’s always best to use persistent storage. With persistent storage, you map a drive on your local machine (or use a Samba/CIFS share from another machine) to a directory within the container. This way, all of the data (such as the sites you build) remain in sync between the internal directory within the container and the external directory on the remote (or host) machine.
This is, by far, the best way to approach containers that require data you want to maintain and keep.
The good thing about doing this with Portainer is that it’s incredibly easy. Let me show you how.
What You Need
To follow along, you’ll need the following things:
- A running instance of Portainer.
- A CIFS/Samba share on a remote machine (I prefer using Linux/Samba for this).
- A network connection.
I’ll be creating persistent storage using a Samba share that’s on a Pop!_OS Linux machine. Although the share is called Public, it is only accessible via my LAN. You will certainly want to adapt this to fit your needs.
If you’re curious, the share in my smb.conf file looks like this:
1 2 3 4 5 |
[PUBLIC] path = /home/jack/Public browsable = yes writable = yes read only = no |
I’ll be using a directory within Public, called NGINX
That’s it. Let’s get to the persistent storage.
Create the Volume
Log into your Portainer instance. Before you deploy the container, you first must create a volume. To do that, click Volumes in the left navigation. On the resulting page, click Add Volume in the upper right corner.
In the Add Volume page, give the volume a name (I’ve named my nginx-tns) and click the On/Off slider for Use CIFS Volume, which opens the CIFS Settings section (Figure 1).

Figure 1: The CIFS Settings options screen is where you create an SMB share for persistent volumes.
Here’s what you need to fill out in the CIFS section:
- Address: The IP address for the machine hosting the Samba share.
- Share: The name of the share and an optional directory. In my case, it would be Public/NGINX.
- CIFS Version: Select CIFS 3.0.
- Username: The username you use to access the share.
- Password: The password for the user that has access to the share.
Once you’ve filled out this information, click Create the Volume to save.
Create the Container with the Volume
With the volume created, it’s time to create the container and attach the volume. Click Containers in the left navigation and then click Add Container in the upper right corner. In the new window, give the container a name and type nginx in the Image section (Figure 2).

Figure 2: Name the container and configure the image to be used.
Scroll down to the Advanced Container Settings section and click the Volumes tab. In this tab, click Map Additional Volume.
Here’s where it gets a bit tricky. You must know which directory the container uses to save data. In our case, we’re using the NGINX image, which houses the document root in /usr/share/nginx/html/. So type that in the Container field (Figure 3) and, from the Volume drop-down menu, select the new volume you just created.

Figure 3: Configuring the volume for the new container.
If you want to map the container to specific port usage, click Publish a New Network Port and then configure the mapping (such as external port 8001 to internal port 80). Click Deploy the Container and the NGINX container should deploy without any errors.
How to Test Persistent Storage
This is where it gets fun. Open a web browser and point it to http://IP:PORT (Where IP is the hosting server’s IP address and PORT is the port you mapped for the container. You should see the Welcome To NGINX page in your browser (Figure 4).

Figure 4: The NGINX Welcome page.
Instead of accessing the NGINX index.html file from within the container, go to the machine hosting the persistent storage and navigate into the directory you mapped. In my case, it’s Public/NGINX. Inside that directory, you should see 2 files:
- 50x.html
- index.html
From that share, open the index.html file with a text editor. Delete the contents of that file and replace it with:
1 2 3 4 5 6 |
<!DOCTYPE html> <html><body> <h1>Welcome to The New Stack!</h1> <p>Our container with persistent storage has successfully been deployed.</p> </body> </html> |
Save and close the file. Refresh the browser page and you should see our new index.html presented (Figure 5).

Figure 5: Our new NGINX Welcome page.
Now, any time you need to change the website hosted by NGINX, you only need to access it from the SMB share. And, should anything go awry with the container, you still have your data intact.
That’s how you do Docker container persistent storage with Portainer.