Docker container behind NGINX Frontend - ghomem/legacy_puppet_infrastructure GitHub Wiki
Installing the docker module
The first step would be installing the docker module. Because of a bug in the offical docker module that makes containers with the latest
tag redownload after every agent run, we forked the project and added a fix for that.
To install this version, please do the following:
On the puppet master, switch to root with sudo su -
. If you already have the docker module installed, remove it with
puppet module uninstall puppetlabs-docker
Clone our fork of the repository to a folder named docker:
cd /etc/puppetlabs/code/environments/production/modules
git clone https://github.com/ghomem/puppetlabs-docker-compat.git docker
chown -R deployment:deployment docker
and create a link pointing to it in the deployment home directory:
sudo ln -s /etc/puppetlabs/code/environments/production/modules/docker /home/deployment/docker
git config --global --add safe.directory /etc/puppetlabs/code/environments/production/modules/docker
# upgrade the version of puppetlabs-powershell
puppet module upgrade puppetlabs-powershell --version 4.0.0
After this is done, we need to switch the branch of the repository to the one with our fix:
su - deployment
cd docker
git checkout puppetlabs_docker_issue_627_compat
# Exit from the deployment user
exit
# restart the puppet service as root
systemctl restart puppetserver.service
With that done, you can check that the module is indeed installed with the correct version, which should be 3.14.0
:
sudo puppet module list | grep docker
Node declaration example for hello world docker
The node declaration of a simple docker-based hello world could be written as:
node 'hello-world-node' {
# this declaration allows for docker to manage its own firewall rules
class { 'puppet_infrastructure::node_base' : firewall_strict_purge => false, firewall_ignore_patterns => ['docker'] }
include passwd_common
$app_domain = 'helloworld.domain.eu'
$app_port = '5007'
$nameserver = '8.8.8.8'
class {'docker':
use_upstream_package_source => false,
service_overrides_template => false,
docker_ce_package_name => 'docker.io',
dns => $nameserver,
}
puppet_infrastructure::docker_container { 'flask-helloworld':
image => 'digitalocean/flask-helloworld',
app_port => '5000',
host_port => $app_port,
}
# nginx reverse proxy frontend
include puppet_infrastructure::nginx_base
class { 'puppet_infrastructure::nginx_frontend':
domain => $app_domain,
frontend_sslprefix => 'star.domain.eu',
backend_hosts_and_ports => ["localhost:${app_port}", ],
backend_protocol => 'http',
letsencrypt_certificate => true,
}
# Allow HTTP/HTTPS connections
include puppet_infrastructure::firewall_addon_web
}
Node declaration for registry imported images
If you wish to import images from one or more private or public registries, your node declaration would be written as:
node 'ubuntu-node' {
# this declaration allows for docker to manage its own firewall rules
class { 'puppet_infrastructure::node_base' : firewall_strict_purge => false, firewall_ignore_patterns => ['docker'] }
include passwd_common
$nameserver = '8.8.8.8'
$domain = 'domain.eu'
$priv_registry = 'ghcr.io'
$username = 'exampleuser'
$token = 'MYPRIVATETOKEN'
$custom_network = 'my-net'
class {'docker':
use_upstream_package_source => false,
service_overrides_template => false,
docker_ce_package_name => 'docker.io',
dns => $nameserver,
require => Class['puppet_infrastructure::node_base'],
}
# setup a custom network so that the containers communicate between each other
docker_network { $custom_network:
ensure => present,
}
# a container pulled from a private registry
puppet_infrastructure::docker_container { 'app-name':
image => "${priv_registry}/${username}/app-name/",
digest => 'sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
app_port => '3000',
username => $username,
token => $token,
network => $custom_network,
}
# another container pulled from the same private registry
puppet_infrastructure::docker_container { 'other-app-name':
image => "${priv_registry}/${username}/app-name/",
tag => 'latest',
app_port => '4000',
username => $username,
token => $token,
network => $custom_network,
env => ['FOO=BAR', 'FOO2=BAR2'],
}
# a container pulled from a public registry
puppet_infrastructure::docker_container { 'hello-world':
image => 'infrastructureascode/hello-world',
app_port => '8080',
network => $custom_network,
}
# nginx reverse proxy frontend
include puppet_infrastructure::nginx_base
puppet_infrastructure::ssl_nginx_domain { "star.${domain}":
sslprefix => "star.${domain}",
letsencrypt_certificate => true,
}
# the reverse proxy for the first container
puppet_infrastructure::nginx_frontend_domain { 'myservice.${domain}':
domain => 'myservice.${domain}',
frontend_sslprefix => 'star.${domain}',
backend_hosts_and_ports => ['localhost:3000', ],
backend_protocol => 'http',
manage_ssl => false,
letsencrypt_certificate => true,
}
# the reverse proxy for the second container
puppet_infrastructure::nginx_frontend_domain { 'myservice2.${domain}':
domain => 'myservice2.${domain}',
frontend_sslprefix => 'star.${domain}',
backend_hosts_and_ports => ['localhost:4000', ],
backend_protocol => 'http',
manage_ssl => false,
letsencrypt_certificate => true,
}
# the reverse proxy for the third container
puppet_infrastructure::nginx_frontend_domain { 'myservice3.${domain}':
domain => 'myservice3.${domain}',
frontend_sslprefix => 'star.${domain}',
backend_hosts_and_ports => ['localhost:8080', ],
backend_protocol => 'http',
manage_ssl => false,
letsencrypt_certificate => true,
}
# Allow HTTP/HTTPS connections
include puppet_infrastructure::firewall_addon_web
}
Creating custom networks is not mandatory for running individual containers or multiple containers that do not require intercommunication. However, for scenarios where containers need to communicate with each other, setting up one or more custom networks is essential. Containers on the same network can communicate with each other using their container names. To verify this inter-container communication, after deploying and running the agent with the provided code, execute the following command to test if two containers within the same network can successfully ping each other:
sudo docker exec -it app-name ping other-app-name