Starting a new project :ref:`from an Ansible Galaxy project template <example-project>` is pretty easy. But what if you've already got an existing project you'd like to use with Ansible Container?
If you have an existing project that you're containerizing by building from a
Dockerfile, you can translate that Dockerfile into an Ansible Container project
and Ansible role using the import
command.
The import
command will examine your Dockerfile and translate its directives
into an Ansible container-enabled role that is its equivalent. RUN
directives
will be split and turned into shell
or command
tasks. ADD
or COPY
directives will be turned into copy
, synchronize
, or get_url
tasks.
And other directives will be converted into role default variables or container
metadata.
When you run your build process, pay attention to the output that Ansible provides
offering suggestions for how you can better leverage built-in Ansible modules to
refine your tasks. For example, if your Dockerfile contained a directive to
RUN yum install
, Ansible will give you a suggestion that you might wish to
make use of the built-in yum
module bundled with Ansible instead.
What comes out of running import
will get you there most of the time, but
it always makes sense to walk through what was generated to give it a sanity
check.
By way of an example, let's imagine a Dockerfile for a simple NodeJS project:
FROM node:7.9.0
RUN mkdir -p /app
WORKDIR /app
ARG NODE_ENV dev
ENV NODE_ENV $NODE_ENV
COPY package.json /app/
RUN npm install && npm cache clean
COPY . /app/
CMD [ "npm", "start" ]
If we run ansible-container import
in the directory with this Dockerfile,
it will translate it to a role with these tasks:
- shell: mkdir -p /app
- name: Ensure /app/ exists
file:
path: /app/
state: directory
- shell: npm install && npm cache clean
args:
chdir: /app
- name: Ensure /app exists
file:
path: /app
state: directory
- synchronize:
src: .
dest: /app/
recursive: yes
The ARG NODE_ENV dev
becomes a variable in the role's defaults/main.yml
while the remaining directives become container-enabled role metadata in the
meta/container.yml
file:
from: node:7.9.0
working_dir: /app
environment:
NODE_ENV: '{{ NODE_ENV }}'
command:
- npm
- start
Additionally, the import
command left us with a functioning skeleton of the
project's container.yml
that we can build upon:
settings:
conductor_base: node:7.9.0
services:
nodejs:
roles:
- mynodeapp
Note that the default :ref:`conductor_container` base image is the same as the
NodeJS service from the Dockerfile. It's best to ensure that your Conductor
derives from the same distribution as your target containers, so since the
node container derives from Debian Jessie
it would make sense to change the conductor_base
key value to debian:jessie
.
As pre-1.0 projects are apt to do, releases 0.4.x and earlier had a much different
structure and approach. Those releases did not specify Ansible Roles in the
container.yml
file and had a separate main.yml
file, as well as putting
all of the Ansible Container artifacts in a separate ansible/
subdirectory.
There is not an automated process for this, however in most cases, you can follow these steps:
- Move the contents of
ansible/
one directory-level up. Therequirements.txt
file needs to be renamed toansible-requirements.txt
, so as not to conflict with Python projects that have their own standardrequirements.txt
file. - Abstract the
main.yml
playbook into one or more roles. There are many helpful guides to this process, such as this one. - Modify your
container.yml
file.- Add a
settings
section with a keyconductor_base
, specifying the base distribution for your :ref:`conductor_container`. This should probably match the distribution you're using to build your target containers. - For each service, add a
roles
key with a list of all the roles that go into building that service. - For each service, the
image
key should be renamedfrom
.
- Add a
For example, each container with a settings list might look like:
settings:
conductor_base: centos:7
services:
webapp:
roles:
- python2
- mywebapp
redis:
roles:
- redis
If you are having difficulty, please :ref:`reach out for help <ask_a_question>`.