Created
          August 4, 2021 00:08 
        
      - 
      
 - 
        
Save patlegu/ac87b89d403de7d0017d8d5c0f62c684 to your computer and use it in GitHub Desktop.  
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | # Building Docker image with Packer and provisioning with Ansible | |
| ## Overview | |
| **Packer** | |
| * Packer is used to build image from a base image, perform provisions and store (commit) the final image. | |
| * We use provisioners and Packer templates to do the actual work to create the final image. | |
| * We use Ansible for provisioning. | |
| **Ansible** | |
| * Ansible runs playbooks on localhost (inside Docker container). | |
| * Ansible must be installed on the image you're provisioning. | |
| * Packer uploads the contents of the Ansible playbook to the Docker container instance, and runs it locally. | |
| # Install Packer | |
| * Follow instructions here: https://www.packer.io/docs/installation.html | |
| * Check Packer is installed: | |
| ``` | |
| packer | |
| usage: packer [--version] [--help] <command> [<args>] | |
| Available commands are: | |
| build build image(s) from template | |
| fix fixes templates from old versions of packer | |
| inspect see components of a template | |
| validate check that a template is valid | |
| ``` | |
| # Build image with Packer | |
| Files: | |
| ``` | |
| build.json - main file with configuration for packer | |
| playbook.yml - Ansible playbook for provisioning | |
| vars/prod.json - main config file for production environment | |
| vars/default.yml - default variables passed to Ansible | |
| vars/prod.yml - variables to pass to Ansible for production environment | |
| ``` | |
| ## Build workflow | |
| Build image for production environment specified by prod.json file: | |
| * run build process with packer build command: | |
| ``` | |
| sudo packer build -var-file=prod.json build.json | |
| ``` | |
| * packer start from the base image specified in build.json | |
| ``` | |
| # build.json | |
| { | |
| ... | |
| "builders":[ | |
| { | |
| "type": "docker", | |
| "image": "phusion/passenger-ruby22:0.9.18", | |
| "commit": true, | |
| ... | |
| } | |
| ], | |
| ... | |
| } | |
| ``` | |
| * packer runs provisioners specified in build.json | |
| * first, it installs Ansible in Docker container: | |
| ``` | |
| "provisioners":[ | |
| { | |
| "type": "shell", | |
| "inline": [ | |
| "apt-get -y update", | |
| "apt-get install -y software-properties-common", | |
| "apt-add-repository ppa:ansible/ansible", | |
| "apt-get -y update", | |
| "apt-get install -y ansible" | |
| ] | |
| }, | |
| ``` | |
| * packer uploads `vars/prod.yml` to the Docker container and saves it as `vars.yml` | |
| ``` | |
| { | |
| "type": "file", | |
| "source": "{{user `config_file`}}", | |
| "destination": "{{user `tmp_dir`}}/vars.yml" | |
| } | |
| ``` | |
| * packer uploads playbook.yml to the Docker container | |
| * packer runs Ansible playbook.yml locally in the Docker container | |
| ``` | |
| { | |
| "type": "ansible-local", | |
| "staging_directory": "{{user `tmp_dir`}}/ansible", | |
| "playbook_file": "playbook.yml", | |
| "extra_arguments": [ "--extra-vars \"tmp_dir={{user `tmp_dir`}} \"" ] | |
| } | |
| ``` | |
| * Ansible playbook uses variables defined in corresponding vars.yml file | |
| ``` | |
| - hosts: 127.0.0.1 | |
| user: root | |
| vars_files: | |
| - "{{tmp_dir}}/vars.yml" | |
| tasks: | |
| ``` | |
| * The final image is saved as "my-nginx:0.1" specified in build.json | |
| ``` | |
| "post-processors": [ | |
| [ | |
| { | |
| "type": "docker-tag", | |
| "repository": "my-nginx", | |
| "tag": "0.1" | |
| } | |
| ] | |
| ] | |
| ``` | |
| ## build configuration | |
| Create build.json file with configuration how to build Docker image. | |
| build.json: | |
| ``` | |
| { | |
| "variables": { | |
| "config_file": "vars/default.yml", | |
| "tmp_dir": "/tmp" | |
| }, | |
| "builders":[ | |
| { | |
| "type": "docker", | |
| "image": "nginx", | |
| "commit": true, | |
| "run_command": ["-d", "{{.Image}}", "nginx -g daemon off"] | |
| } | |
| ], | |
| "provisioners":[ | |
| { | |
| "type": "shell", | |
| "inline": [ | |
| "apt-get -y update", | |
| "apt-get install -y software-properties-common", | |
| "apt-add-repository ppa:ansible/ansible", | |
| "apt-get -y update", | |
| "apt-get install -y ansible" | |
| ] | |
| }, | |
| { | |
| "type": "shell", | |
| "inline": [ | |
| "mkdir -p {{user `tmp_dir`}}" | |
| ] | |
| } | |
| , | |
| { | |
| "type": "file", | |
| "source": "{{user `config_file`}}", | |
| "destination": "{{user `tmp_dir`}}/vars.yml" | |
| } | |
| , | |
| { | |
| "type": "ansible-local", | |
| "staging_directory": "{{user `tmp_dir`}}/ansible", | |
| "playbook_file": "playbook.yml", | |
| "extra_arguments": [ "--extra-vars \"tmp_dir={{user `tmp_dir`}} \"" ] | |
| } | |
| ], | |
| "post-processors": [ | |
| [ | |
| { | |
| "type": "docker-tag", | |
| "repository": "my-nginx", | |
| "tag": "0.1" | |
| } | |
| ] | |
| ] | |
| } | |
| ``` | |
| ## Configs | |
| ## Build image | |
| ``` | |
| sudo packer build -var-file=vars/prod.json build.json | |
| ``` | |
| ## Run Docker container | |
| ``` | |
| sudo docker run -d -p 8080:80 --name=my-server1 my-nginx:0.1 | |
| ``` | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment