Search code examples
dockeransible

How to copy the web site contents into the docker container from controller machine using ansible


I was working to deploy a docker container with a simple web files and wrote following Ansible script for configure and deploy the docker container with creating a docker network. I am able to access the docker container from the network but I was not able to manage copying the website to the container. following is the my Ansible script and other scripts. I was trying with different approaches but was not able to make it fix.

- name: Deploy Apache Docker Container
  hosts: docker_hosts  
  #connection: remote
  become: true
  tasks:
    - name: Install Docker dependencies
      apt:
        name: "{{ item }}"
        state: present
      loop:
        - apt-transport-https
        - ca-certificates
        - curl
        - gnupg
        - lsb-release

    - name: Add Docker's official GPG key
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Add Docker repository
      apt_repository:
        repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} stable
        state: present

    - name: Update apt packages cache
      apt:
        update_cache: yes

    - name: Install Docker
      apt:
        name: docker-ce
        state: present

    - name: Start Docker service
      service:
        name: docker
        state: started

    #Install Docker python package which is already not installed
    - name: Install Docker Python package
      apt:
        name: python3-docker
        state: present
    # Creates docker network with /30 subnet mask
    - name: Set up container to run on 172.168.11.0/30 subnet
      docker_network:
        name: 20024471_B9IS121-network
        ipam_config:
          - subnet: "172.168.11.0/30"
        
    # Pulls the latest docker image with Apache web server.
    - name: Pull Apache Docker image
      docker_image:
        name: httpd
        tag: latest
        source: pull

    # Defines the list of container configurations to add to the docker network
    # In this case, second IP is automatically assign to the bridge network between 
    # docker host computer and the containers. this is a limitation.
    - name: Define list of container configurations
      set_fact:
        container_configs:
          - name: 20024471_B9IS121-container-1
            image: httpd:latest
            # add website directory to htdocs on the container
            volumes:
              - "{{ playbook_dir }}/myweb:/usr/local/apache2/htdocs"
            ports:
              - "8080:80"
            networks:
              - name: 20024471_B9IS121-network
                ipv4_address: 172.168.11.2
            networks_cli_compatible: yes
            container_default_behavior: compatibility
            network_mode: default               
    
          # increase the subnet to enable more containers if required.
          # uncomment following under -name to configure more containers.
          #- name: 20024471_B9IS121-container-2
          #  image: httpd:latest
          #  volumes:
          #    - "{{ playbook_dir }}/myweb:/usr/local/apache2/htdocs"
          #  ports:
          #    - "8081:80"
          #  networks:
          #    - name: 20024471_B9IS121-network
          #      ipv4_address: 172.168.10.3
          #  networks_cli_compatible: yes
          #  container_default_behavior: compatibility
          #  network_mode: default

    # iterate the list of containers and create the containers
    - name: deploy an Apache Docker container
      docker_container:
        name: "{{ item.name }}"
        image: "{{ item.image }}"
        volumes: "{{ item.volumes }}"
        ports: "{{ item.ports }}"
        networks: "{{ item.networks }}"
        networks_cli_compatible: "{{ item.networks_cli_compatible }}"
        container_default_behavior: "{{ item.container_default_behavior }}"
        network_mode: "{{ item.network_mode }}"
      loop: "{{ container_configs }}"

    - name: Print playbook directory
      debug:
        var: playbook_dir

the inventory.ini file

[docker_hosts]
#host1 ansible_host=192.168.18.22
host1 ansible_host=192.168.122.192 ansible_user=kala ansible_password=kalabara
#192.168.122.192

Output when running the ansible-plabook

# ansible-playbook -i inventory.ini docker_deploy.yml --ask-pass --ask-become-pass
SSH password: 
BECOME password[defaults to SSH password]: 

PLAY [Deploy Apache Docker Container] ****************************************************************************************************************

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

TASK [Install Docker dependencies] *******************************************************************************************************************
ok: [host1] => (item=apt-transport-https)
ok: [host1] => (item=ca-certificates)
ok: [host1] => (item=curl)
ok: [host1] => (item=gnupg)
ok: [host1] => (item=lsb-release)

TASK [Add Docker's official GPG key] *****************************************************************************************************************
ok: [host1]

TASK [Add Docker repository] *************************************************************************************************************************
ok: [host1]

TASK [Update apt packages cache] *********************************************************************************************************************
changed: [host1]

TASK [Install Docker] ********************************************************************************************************************************
ok: [host1]

TASK [Start Docker service] **************************************************************************************************************************
ok: [host1]

TASK [Install Docker Python package] *****************************************************************************************************************
ok: [host1]

TASK [Set up container to run on 172.168.11.0/30 subnet] *********************************************************************************************
ok: [host1]

TASK [Pull Apache Docker image] **********************************************************************************************************************
ok: [host1]

TASK [Define list of container configurations] *******************************************************************************************************
ok: [host1]

TASK [deploy an Apache Docker container] *************************************************************************************************************
ok: [host1] => (item={'name': '20024471_B9IS121-container-1', 'image': 'httpd:latest', 'volumes': ['/home/nishshanka/Documents/20024471_B9IS121_2324_TMD2_NETWORKS_SYSTEMS_ADM/myweb:/usr/local/apache2/htdocs'], 'ports': ['8080:80'], 'networks': [{'name': '20024471_B9IS121-network', 'ipv4_address': '172.168.11.2'}], 'networks_cli_compatible': True, 'container_default_behavior': 'compatibility', 'network_mode': 'default'})

TASK [Print playbook directory] **********************************************************************************************************************
ok: [host1] => {
    "playbook_dir": "/home/username/Documents/20024471_B9IS121_2324_TMD2_NETWORKS_SYSTEMS_ADM"
}

PLAY RECAP *******************************************************************************************************************************************
host1                      : ok=13   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Solution

  • This can be done with additional step to copy the content from Controller PC to the Host, then mount the file location for file deployment. following new tasks added to the Ansible.

    # copy the website to the host volume for deployment
        - name: Create destination directory if it doesn't exist
          ansible.builtin.file:
            path: /tmp/nish-data
            state: directory
    
        - name: Copy files to Docker volume
          ansible.builtin.copy:
            src: "{{ playbook_dir }}/myweb"
            dest: /tmp/nish-data
    

    and then we have to add volume property to the container configurations.

    # Defines the list of container configurations to add to the docker network
        # In this case, second IP is automatically assign to the bridge network between 
        # docker host computer and the containers. this is a limitation.
        - name: Define list of container configurations
          set_fact:
            container_configs:
              - name: 20024471_B9IS121-container-1
                image: httpd:latest
                # add website directory to htdocs on the container
                volumes:
                  - "/tmp/nish-data/:/usr/local/apache2/htdocs/"
                ports:
                  - "8080:80"
                networks:
                  - name: 20024471_B9IS121-network
                    ipv4_address: 172.168.10.2
                networks_cli_compatible: yes
                container_default_behavior: compatibility
                network_mode: default 
    

    with this approach, web site files will be copied to the host PC first then deploy. following is the full content for YML file.

    - name: Deploy Apache Docker Container
      hosts: docker_hosts  
      become: true
      tasks:
        - name: Install Docker dependencies
          apt:
            name: "{{ item }}"
            state: present
          loop:
            - apt-transport-https
            - ca-certificates
            - curl
            - gnupg
            - lsb-release
    
        - name: Add Docker's official GPG key
          apt_key:
            url: https://download.docker.com/linux/ubuntu/gpg
            state: present
    
        - name: Add Docker repository
          apt_repository:
            repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} stable
            state: present
    
        - name: Update apt packages cache
          apt:
            update_cache: yes
    
        - name: Install Docker
          apt:
            name: docker-ce
            state: present
    
        - name: Start Docker service
          service:
            name: docker
            state: started
    
        #Install Docker python package which is already not installed
        - name: Install Docker Python package
          apt:
            name: python3-docker
            state: present
        # Creates docker network with /30 subnet mask
        - name: Set up container to run on 172.168.10.0/30 subnet
          docker_network:
            name: 20024471_B9IS121-network
            ipam_config:
              - subnet: "172.168.10.0/30"
            
        # Pulls the latest docker image with Apache web server.
        - name: Pull Apache Docker image
          docker_image:
            name: httpd
            tag: latest
            source: pull
    
        # copy the website to the host volume for deployment
        - name: Create destination directory if it doesn't exist
          ansible.builtin.file:
            path: /tmp/nish-data
            state: directory
    
        - name: Copy files to Docker volume
          ansible.builtin.copy:
            src: "{{ playbook_dir }}/myweb"
            dest: /tmp/nish-data
    
    
        # Defines the list of container configurations to add to the docker network
        # In this case, second IP is automatically assign to the bridge network between 
        # docker host computer and the containers. this is a limitation.
        - name: Define list of container configurations
          set_fact:
            container_configs:
              - name: 20024471_B9IS121-container-1
                image: httpd:latest
                # add website directory to htdocs on the container
                volumes:
                  - "/tmp/nish-data/:/usr/local/apache2/htdocs/"
                ports:
                  - "8080:80"
                networks:
                  - name: 20024471_B9IS121-network
                    ipv4_address: 172.168.10.2
                networks_cli_compatible: yes
                container_default_behavior: compatibility
                network_mode: default               
        
              # increase the subnet to enable more containers if required.
              # uncomment following under -name to configure more containers.
              #- name: 20024471_B9IS121-container-2
              #  image: httpd:latest
              # add website directory to htdocs on the container
              #  volumes:
              #    - "/tmp/nish-data/:/usr/local/apache2/htdocs/"
              #  ports:
              #    - "8080:80"
              #  networks:
              #    - name: 20024471_B9IS121-network
              #      ipv4_address: 172.168.10.2
              #  networks_cli_compatible: yes
              #  container_default_behavior: compatibility
              #  network_mode: default 
    
        # iterate the list of container configurations and create the containers
        - name: deploy an Apache Docker container
          docker_container:
            name: "{{ item.name }}"
            image: "{{ item.image }}"
            volumes: "{{ item.volumes }}"
            ports: "{{ item.ports }}"
            networks: "{{ item.networks }}"
            networks_cli_compatible: "{{ item.networks_cli_compatible }}"
            container_default_behavior: "{{ item.container_default_behavior }}"
            network_mode: "{{ item.network_mode }}"
          loop: "{{ container_configs }}"
    
        # print variable values for debug purposes 
        - name: Print playbook directory
          debug:
            var: playbook_dir