Install Docker, Docker-Compose, Portainer & Nginx on CentOS 8 & Ubuntu 20.04 - NETSEC

Latest

Learning, Sharing, Creating

Cybersecurity Memo

Thursday, June 10, 2021

Install Docker, Docker-Compose, Portainer & Nginx on CentOS 8 & Ubuntu 20.04

This post is to summarize all installation steps for a new CentOS8 and get Docker and Docker-Compose and Portainer installed. Nginx will also be installed and configured as reverse proxy for Portainer with Cloudflare managed custom domain. Cert-Bot will be installed on Nginx to enable https for Portainer's web interface. 

The steps are same as CentOS7 and other Debian based release. 

For Arm-based architecture, here is the post to install Docker /Docker-Compose:



System Update

Check System Public IP:

[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# curl https://ip.51sec.org/api
132.145.100.226
Update CentOS 8system to latest:

 [root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# yum upgrade -y && yum update -y
Update Ubuntu 20.04 8system to latest:

 [root@OCP1-Ubuntu ~]# apt upgrade -y && apt update -y

Install NodeQuery Monitor Agent

Nodequery stopped the service since Sep 2021
Add a new server into your NodeQuery Account or select Reinstall to get code for agent installation.


[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# wget -N --no-check-certificate https://raw.github.com/nodequery/nq-agent/master/nq-install.sh && bash nq-install.sh Zb8Ge0oBFXvx24SM6YgfpH

SWAP Size change

Based on your VPS's default configuration, it might need to increase swap size. It will dramatically increase your service's stable ability for those small memory VPS (less than 2GB). 

[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# free
              total        used        free      shared  buff/cache   available
Mem:         823684      258292      120892        1904      444500      553072
Swap:       8388604        8532     8380072


Check post  "Change SWAP Size to Improve Low Memory Cloud VM Reliability "for how to change your swap size. 

Basic command: 
wget https://raw.githubusercontent.com/51sec/swap/main/swap.sh && bash swap.sh

———————————————————————————————————————
Linux VPS One Command Script to Set/Delete Swap
1. Add swap
2. Delete swap
———————————————————————————————————————
Please Enter Option [1-2]:1
Please enter the size of your swap,recommend size should be double of your memory!
enter /swapfile's size (MB):1024
/swapfile not fund, creating swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=8083fae2-0490-43cf-9600-ea873ee8191c
swapfile successful created, checking information:
Filename                                Type            Size            Used            Priority
/swapfile                               file            1048572         0               -2
SwapCached:            0 kB
SwapTotal:       1048572 kB
SwapFree:        1048572 kB
root@opc3ubuntu1:~# free
              total        used        free      shared  buff/cache   available
Mem:         995472      174508      144444        1900      676520      656492
Swap:       1048572           0     1048572





Install Docker and Docker Compose

Install Docker on CentOS 8:

curl -sSL https://get.docker.com/ | sh 
systemctl start docker 
systemctl enable docker

Install Docker on Ubuntu 20.04:

#Ubuntu 20.04
sudo apt install docker.io -y 

Install Docker Compose on CentOS 8:
Important: Check the latest version of docker-compose  from https://docs.docker.com/compose/release-notes/ then modify following command with latest version number.  (I got 1.29.2 for this installation)


curl -L "https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Install Docker Compose on Ubuntu 20.04:

#Ubuntu 20.04
sudo apt install docker-compose -y 

Check Version:

[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# /usr/local/bin/docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# docker version
Client: Docker Engine - Community
 Version:           20.10.6
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        370c289
 Built:             Fri Apr  9 22:44:36 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.6
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       8728dd2
  Built:            Fri Apr  9 22:43:02 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]#

Install Portainer

Please make sure your VPS's firewall port 80, 443 and 9000 has been opened. We can close 9000 later.

[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# docker volume create portainer_data
portainer_data
[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]# docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
Unable to find image 'portainer/portainer-ce:latest' locally
latest: Pulling from portainer/portainer-ce
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
f220caeff793: Pull complete
Digest: sha256:67e3edef02ba465d18663cd273cc24ec2764b27686ea5afbe8f392317a70ed72
Status: Downloaded newer image for portainer/portainer-ce:latest
d0ff883b063156b5929a8999593d38837501e6c16ffcefcbefb221ebe0301a32
[root@OCP1-CentOS8-Aria-Rclone-Portainer ~]#

Verify Portainer from Internet by visiting http://<VPS's Public IP>:9000


Install Nginx using Portainer


From Portainer Portal, click App Templates menu, then choose Nginx template to deploy:


Make sure you put port 80 and port 443 mapping as show below:



Now you should get your Ngix page from http://<VPS's public ip>




Configure Nginx as Reverse Proxy 

In this section, Nginx will be configured as reverse proxy to redirect all traffic for portainer1.51sec.eu.org on port 80 and 443 to proxied docker website Portainer. Connect into Nginx console from Portainer portal or command: docker exec -it nginx bin/bash. or docker exec -it nginx sh

root@ba4a30ab7371:/# apt update && apt install nano -y



root@ba4a30ab7371:/# nano /etc/nginx/conf.d/portainer.conf



server {
    listen       80;
    server_name  portainer1.51sec.eu.org;

location / {
    proxy_pass       http://172.31.23.170:6080;
    proxy_http_version         1.1;
    proxy_read_timeout 300;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Real-PORT $remote_port;
           }
}
Note: You can replace http://172.31.23.170:6080; to http://<WP Docker name>
Please make sure nginx and Wp_docker are in the same network.


root@ba4a30ab7371:/# service nginx restart



Visit http://portainer1.51sec.eu.org through Google Incognito window to verify the access and configuration. 

Enable Https for Nginx

Connect into Nginx console from Portainer portal or command: docker exec -it nginx bin/bash


apt update
apt install certbot python-certbot-nginx
certbot --nginx
Based on your Linux version, you might get an error : Unable to locate package python-certbot-nginx

root@80b7227d4eed:/etc/nginx/conf.d# apt install python-certbot-nginx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package python-certbot-nginx
root@80b7227d4eed:/etc/nginx/conf.d# 
In this case , install package apt install python3-certbot-nginx

python3-certbot-nginx will be the right nginx plug-in for your situation. After this plugin installed, you can start to configure https for your site.

root@ba4a30ab7371:/# certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): [email protected]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: portainer1.51sec.eu.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for portainer1.51sec.eu.org
2021/05/24 19:49:48 [notice] 1330#1330: signal process started
Waiting for verification...
Cleaning up challenges
2021/05/24 19:49:53 [notice] 1332#1332: signal process started
Deploying Certificate to VirtualHost /etc/nginx/conf.d/portainer.conf
2021/05/24 19:49:56 [notice] 1334#1334: signal process started

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://portainer1.51sec.eu.org

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=portainer1.51sec.eu.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/portainer1.51sec.eu.org/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/portainer1.51sec.eu.org/privkey.pem
   Your cert will expire on 2021-08-22. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

root@ba4a30ab7371:/# 

After this step, both http and https should work for your portainer site. 



Custom Bridge Network


Create a new bridge network to join your Containers into same network. In this way, they can access it through their name directly.





Get your Docker Container to join into your new created bridge network.

In this way, we can directly use container's name to access each other. After this, we can close firewall's port 9000. 




root@ba4a30ab7371:/# ping portainer
PING portainer (172.20.20.3) 56(84) bytes of data.
64 bytes from portainer.mybridge (172.20.20.3): icmp_seq=1 ttl=64 time=0.104 ms
64 bytes from portainer.mybridge (172.20.20.3): icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from portainer.mybridge (172.20.20.3): icmp_seq=3 ttl=64 time=0.081 ms
64 bytes from portainer.mybridge (172.20.20.3): icmp_seq=4 ttl=64 time=0.079 ms
^C
--- portainer ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 53ms
rtt min/avg/max/mdev = 0.079/0.086/0.104/0.010 ms
root@ba4a30ab7371:/# 


nano /etc/nginx/conf.d/portainer.conf

server {
    listen       80;
    server_name  portainer1.51sec.eu.org;

location / {
    proxy_pass       http://portainer:6080;
    proxy_http_version         1.1;
    proxy_read_timeout 300;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Real-PORT $remote_port;
           }
}


Install Network Utilities in Container

Most of times, the docker image is not including following network utilities which can help you troubleshooting your network connectivity, such as ping, ifconfig, tracert, telnet etc. You might want to install them for yourself.


root@ba4a30ab7371:/# cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@ba4a30ab7371:/# 



root@26a4cc3a312a:/# apt-get update
root@26a4cc3a312a:/# apt-get install iputils-ping
root@26a4cc3a312a:/# apt-get install telnet
root@26a4cc3a312a:/# apt-get install traceroute
root@26a4cc3a312a:/# apt-get install net-tools

Note: net-tools will include ifconfig / netstat commands


Notes: For install Certbot on Ubuntu system:

Unfortunately the install instruction from Certbot is not working for my Nginx docker. But I can run following two commands to get Certbot installed. 

  • apt install certbot
  • apt install python-certbot-nginx


YouTube















1 comment:

  1. Hello,
    Thanks for the tuto. One note, in portainer.conf, port should be 9000 instead of 6080 following the previous steps.

    ReplyDelete