Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

In this example we are going to run Ansible on local server to setup a Nginx docker container in remote server. Process will install docker and docker-compose on remote server.


Structure


absible@local:/application$ tree
.
├── docker
│   ├── docker-compose.yml
│   └── nginx
│   └── Dockerfile
└── provisioning
├── host_vars
│   └── remote
├── hosts.yml
├── roles
│   ├── app
│   │   └── tasks
│   │   └── main.yml
│   └── setup
│   ├── handlers
│   │   └── main.yml
│   └── tasks
│   ├── docker.yml
│   └── main.yml
└── site.yml

Files


docker/.env


COMPOSE_PROJECT_NAME=helloworld

NGINX_IP=192.168.0.11
NETWORK_SUBNET=192.168.0.0/24

docker/docker-compose.yml


version: '3'

services:
nginx_img:
container_name: ${COMPOSE_PROJECT_NAME}_nginx_con
build:
context: ./nginx
networks:
public_net:
ipv4_address: ${NGINX_IP}

networks:
public_net:
driver: bridge
ipam:
driver: default
config:
- subnet: ${NETWORK_SUBNET}

docker/nginx/Dockerfile


FROM nginx:1.13.8

RUN echo 'This is the Nginx container'

provisioning/hosts.yml


all:
hosts:
remote:
ansible_connection: ssh
ansible_user: ubuntu # Remote user
ansible_host: 192.168.99.30 # Remote host
ansible_port: 22

provisioning/site.yml


---
# This playbook sets up whole stack.

- name: Configurations to "remote" host
hosts: remote
remote_user: ubuntu # Remote user
become: yes
roles:
- setup

- name: Copying "docker" application folder on remote server
hosts: remote
remote_user: ubuntu # Remote user
become: yes
roles:
- app

provisioning/host_vars/remote


---
# Variables listed here are applicable to "setup" role

ansible_python_interpreter: /usr/bin/python3

remote_user: ubuntu
docker_group: docker

docker_remote_app_dir: /tmp/helloworld

provisioning/roles/app/tasks/main.yml


---
# This playbook contains all actions that will be run on "local" host.

# cp ~/application/provisioning/../docker/* /tmp/helloworld
- name: Copy "docker" application folder across
copy:
src: "{{ playbook_dir }}/../docker/"
dest: "{{ docker_remote_app_dir }}"
tags:
- app

# cd /tmp/helloworld/ && docker-compose up -d --build
- name: Rebuild images defined in compose file and restart containers whose images have changed
command: docker-compose up -d --build
args:
chdir: "{{ docker_remote_app_dir }}"
tags:
- app

provisioning/roles/setup/handlers/main.yml


---
# This playbook contains common handlers that can be called in "setup" tasks.

# sudo systemctl enable docker
- name: Start docker on boot
systemd:
name: docker
state: started
enabled: yes

provisioning/roles/setup/tasks/docker.yml


---
# This playbook contains docker actions that will be run on "remote" host.

# sudo apt-get install *
- name: Install docker packages
apt:
name: "{{ item }}"
state: present
update_cache: yes
with_items:
- apt-transport-https
- ca-certificates
- curl
- software-properties-common
tags:
- docker

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- name: Add Dockers official GPG key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
tags:
- docker

# sudo apt-key fingerprint 0EBFCD88
- name: Verify that we have the key with the fingerprint
apt_key:
id: 0EBFCD88
state: present
tags:
- docker

# sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
- name: Set up the stable repository
apt_repository:
repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable
state: present
update_cache: yes
tags:
- docker

# sudo apt-get update
- name: Update apt packages
apt:
update_cache: yes
tags:
- docker

# sudo apt-get install docker-ce=18.03.*
- name: Install docker
apt:
name: docker-ce=18.03.*
state: present
update_cache: yes
notify: Start docker on boot
tags:
- docker

# sudo groupadd docker
- name: Create "docker" group
group:
name: "{{ docker_group }}"
state: present
tags:
- docker

# sudo usermod -aG docker ubuntu
- name: Add remote "ubuntu" user to "docker" group
user:
name: "{{ remote_user }}"
group: "{{ docker_group }}"
append: yes
tags:
- docker

# sudo curl -L https://github.com/docker/compose/releases/download/1.20.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# sudo chmod +x /usr/local/bin/docker-compose
- name: Install docker-compose
get_url:
url: https://github.com/docker/compose/releases/download/1.20.1/docker-compose-Linux-x86_64
dest: /usr/local/bin/docker-compose
mode: 0755
tags:
- docker

provisioning/roles/setup/tasks/main.yml


---
# This playbook contains all actions that will be run on "local" host.

# sudo apt-get update
- name: Update apt packages
apt:
update_cache: yes
tags:
- system

# Import docker tasks
- name: Import docker tasks
include_tasks: docker.yml

# sudo apt-get autoclean
- name: Remove useless apt packages from the cache
apt:
autoclean: yes
tags:
- system

# sudo apt-get autoremove
- name: Remove dependencies that are no longer required
apt:
autoremove: yes
tags:
- system

Build


Make sure that your local server can access to remote server over SSH. There is a post on this blog that explains it.


absible@local:/application$ ansible-playbook provisioning/site.yml -i provisioning/hosts.yml

PLAY [Configurations to "remote" host] **************************************************

TASK [Gathering Facts] ******************************************************************
ok: [remote]

TASK [setup : Update apt packages] ******************************************************
changed: [remote]

TASK [setup : Import docker tasks] ******************************************************
included: /var/www/html/application/provisioning/roles/setup/tasks/docker.yml for remote

TASK [setup : Install docker packages] **************************************************
ok: [remote] => (item=[u'apt-transport-https', u'ca-certificates', u'curl', u'software-properties-common'])

TASK [setup : Add Docker's official GPG key] ********************************************
changed: [remote]

TASK [setup : Verify that we have the key with the fingerprint] *************************
ok: [remote]

TASK [setup : Set up the stable repository] *********************************************
changed: [remote]

TASK [setup : Update apt packages] ******************************************************
changed: [remote]

TASK [setup : Install docker] ***********************************************************
changed: [remote]

TASK [setup : Create "docker" group] ****************************************************
ok: [remote]

TASK [setup : Add remote "ubuntu" user to "docker" group] *******************************
changed: [remote]

TASK [setup : Install docker-compose] ***************************************************
changed: [remote]

TASK [setup : Remove useless apt packages from the cache] *******************************
ok: [remote]

TASK [setup : Remove dependencies that are no longer required] **************************
ok: [remote]

RUNNING HANDLER [setup : Start docker on boot] ******************************************
ok: [remote]

PLAY [Copying "docker" application folder on remote server] *****************************

TASK [Gathering Facts] ******************************************************************
ok: [remote]

TASK [app : Copy "docker" application folder across] ************************************
changed: [remote]

TASK [app : Rebuild images defined in compose file and restart containers whose images have changed] ******
changed: [remote]

PLAY RECAP ******************************************************************************
remote : ok=18 changed=9 unreachable=0 failed=0

Remote server checks


Application folder


ubuntu@remote:~$ ls -l /tmp/
drwxr-xr-x 3 root root 4096 Mar 25 18:55 helloworld

ubuntu@remote:~$ ls -l /tmp/helloworld/
-rw-r--r-- 1 root root 381 Mar 25 18:55 docker-compose.yml
drwxr-xr-x 2 root root 4096 Mar 25 18:55 nginx

ubuntu@remote:~$ tree /tmp/helloworld/
.
├── docker-compose.yml
└── nginx
└── Dockerfile

1 directory, 2 files

Versions


ubuntu@remote:~$ docker -v
Docker version 18.03.0-ce, build 0520e24

ubuntu@remote:~$ docker-compose --version
docker-compose version 1.20.1, build 5d8c71b

Image, Network, Container


ubuntu@remote:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld_nginx_img latest 3f95ac3b41a1 57 seconds ago 109MB
nginx 1.13.8 9e988ed19567 5 weeks ago 109MB

ubuntu@remote:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
02cc6c8d92c5 bridge bridge local
a5f870514a79 helloworld_public_net bridge local
b7ba4fc4154e host host local
b9295d67997c none null local

ubuntu@remote:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7416c3a441b helloworld_nginx_img "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp helloworld_nginx_con

ubuntu@remote:~$ curl 192.168.0.11
This will print "Welcome to nginx!" message.