How to manage Docker with portainer on Ubuntu 16.04 LTS with Apache2 as reverse proxy

Today I want to show how to manage your Docker containers with portainer . We use the portainer docker image, Apache2 as a reverse proxy, and we will secure our installation with LetsEncrypt.

– an Ubuntu VPS
– LAMP stack installed
– Reverse Proxy Module enabled in Apache2
– Docker installed
– certbot installed
– DNS-A record for our Apache2-vHost

If requirements are missing, of course we have to do this first.

LAMP stack:

 sudo apt-get install lamp-server^

Enable reverse proxy modules:

sudo a2enmod proxy proxy_http proxy_ajp rewrite deflate headers proxy_balancer proxy_connect proxy_html proxy_wstunnel authz_core authn_core setenvif ssl

Version from the official package sources:

sudo apt-get install
sudo systemctl start docker
sudo systemctl enable docker

or directly from Docker:

sudo curl -sSL | CHANNEL=stable sh
sudo systemctl enable docker.service
sudo systemctl start docker.service


sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache

Afterwards we can continue and put Portainer into operation.

Step 1: Run Portainer docker Image

With the following command we start the container on our server:

sudo docker run -d -p 9000:9000 --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer:/data portainer/portainer

We check, if the container was started:

sudo docker ps

Portainer now listens on port 9000.

Step 2: Create Apache2 vHost

When the container is running, we create a vHost so we can use the reverse proxy functionality and call it in the browser without a port specification later:

sudo nano /etc/apache2/sites-available/003-portainer.conf

we add the following content:

<VirtualHost *:80>

ServerName portainer.your-domain.tld


Save file, activate site and restart Apache2:

sudo a2ensite 003-portainer.conf
sudo systemctl restart apache2

Now Portainer would already be accessible via http: //portainer.your-domain.tld. But we are working with password input, so we encrypt the connection with SSL.

we use Certbot:

sudo certbot --apache

Select the corresponding host and at the end select „2“ for „redirect“.

Now we have to edit the generated conf:

sudo nano /etc/apache2/sites-available/003-portainer-le-ssl.conf

and add the following block after ServerName:

# Proxy to Portainer
ProxyPreserveHost On
ProxyPass /
ProxyPassReverse /
RequestHeader set X-Forwarded-Proto "https"

ProxyVia Block

<Proxy *>
Require all granted

# SSL Configuration - uses strong cipher list - these might need to be downgraded if you need to support older browsers/devices
SSLEngine on
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On

# HSTS (optional)
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
# Prevent MIME based attacks
Header set X-Content-Type-Options "nosniff"

ErrorLog /var/log/apache2/portainer-error.log
CustomLog /var/log/apache2/portainer-access.log combined

#Proxy to docker container console

<Location /api/websocket/>
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /api/websocket/(.*) ws://$1 [P]

Save File and Restart Apache2 again.

sudo systemctl restart apache2

Step 3: Configure Portainer

via the browser of our choice we call https://portainer.your-domain.tld and must first assign a password for the admin:

In the next dialog we set the setting to „Local“:

click on the button „Connect“ and after a short time you will see the dashboard of portainer:

If we select „Container“, we can see more information about the individual containers or restart, stop, etc.:

Container details:


If you want to call Portainer in a subfolder of an existing vHost (as example: https://hostname.your-domain.tld/portainer/) than you have to add the following block to this conf:

<Location /portainer/>
RequestHeader set X-Forwarded-Proto "https"

<Location /portainer/api/websocket/>
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /api/websocket/(.*) ws://$1 [P]

Don not forget to enable reverse proxy modules.

That’s it for today, have fun 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert