Docker
Run the AnsibleForms app and RTE images with Docker or Podman, next to a MySQL server of your own
You can run AnsibleForms with Docker or Podman as two containers, the app and the RTE that runs the playbooks, connected to a MySQL database.
Prerequisites
Before you start, you need:
- Docker or Podman : one of them installed and running
- MySQL : installed and running
Install MySQL
Install MySQL 8+, or MariaDB, on a Linux server that the container can reach:
Ubuntu ships MySQL 8:
sudo apt-get update
sudo apt-get install -y mysql-server
sudo systemctl enable --now mysql
sudo mysql_secure_installation
Debian ships MariaDB in place of MySQL, which AnsibleForms also supports:
sudo apt-get update
sudo apt-get install -y mariadb-server
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation
RHEL 8 and later, and its rebuilds, ship MySQL 8 in AppStream:
sudo dnf install -y mysql-server
sudo systemctl enable --now mysqld
sudo mysql_secure_installation
AnsibleForms connects to the database over the network, as DB_USER with DB_PASSWORD. Give it a user of its own, with rights on the AnsibleForms schema only, not root:
CREATE USER 'ansibleforms'@'%' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON `AnsibleForms`.* TO 'ansibleforms'@'%';
That is all AnsibleForms needs: with it, it creates and patches its schema and makes its backups. The Status page and the log warn when the user has rights on every database. On Ubuntu and Debian the server listens on localhost only: set bind-address in its configuration so that the containers can reach it.
Prepare the folders
AnsibleForms 7 runs in two containers: the app, and the RTE (runtime environment) that runs the playbooks. Both mount a folder for your config.yaml, forms, playbooks, logs and certificates, and a folder for the SSH key. The images run as the user node (uid 1000), so give that user both folders:
sudo mkdir -p /srv/apps/ansibleforms/persistent /srv/apps/ansibleforms/ssh
sudo chown -R 1000:1000 /srv/apps/ansibleforms/persistent /srv/apps/ansibleforms/ssh
Put the app’s settings in an environment file: the database connection, ENCRYPTION_SECRET before you store any credential, the token the app and the RTE share (RTE_TOKEN, at least 16 characters) and the config seed that declares the RTE:
sudo tee /srv/apps/ansibleforms/ansibleforms.env > /dev/null <<'END'
DB_HOST=192.168.0.1
DB_PORT=3306
DB_USER=ansibleforms
DB_PASSWORD=<password>
ENCRYPTION_SECRET=<a long random string>
RTE_TOKEN=<at least 16 characters>
CONFIG_SEED_PATH=/app/dist/persistent/seed.yaml
END
sudo chmod 600 /srv/apps/ansibleforms/ansibleforms.env
The RTE gets a file of its own, without the database’s settings: since 7.3.0 the app dials it and keeps one WebSocket open (RTE_MODE=inbound, see Modes), and it runs the playbooks from the same folders (RTE_FILES=local):
sudo tee /srv/apps/ansibleforms/rte.env > /dev/null <<'END'
RTE_MODE=inbound
RTE_TOKEN=<the same token>
RTE_FILES=local
PORT=8000
HTTPS=0
END
sudo chmod 600 /srv/apps/ansibleforms/rte.env
The config seed declares an RTE credential with the RTE’s address and its token, and the default runner rte that signs in with it:
sudo tee /srv/apps/ansibleforms/persistent/seed.yaml > /dev/null <<'END'
version: 1
credentials:
items:
- name: rte
credential_type: rte
url: http://rte:8000
password: ${RTE_TOKEN}
runners:
items:
- name: rte
type: rte
rte_mode: inbound
credential: rte
is_default: true
END
sudo chown 1000:1000 /srv/apps/ansibleforms/persistent/seed.yaml
Start the containers
Run the published images from the GitHub Container Registry (see Image tags): ghcr.io/ansibleforms/ansibleforms for the app and ghcr.io/ansibleforms/ansibleforms-rte-full for the RTE.
The seed adds the RTE under Connections > Runners as the runner rte, the default one, so playbook forms run on it without further setup. The app creates the schema at its first start, and dials the RTE once both run (a sample config.yaml is in the docker-compose project):
docker network create ansibleforms
docker run -d --name ansibleforms --network ansibleforms -p 8000:8000 --restart unless-stopped \
--env-file /srv/apps/ansibleforms/ansibleforms.env \
-v /srv/apps/ansibleforms/persistent:/app/dist/persistent \
-v /srv/apps/ansibleforms/ssh:/home/node/.ssh \
ghcr.io/ansibleforms/ansibleforms:7
docker run -d --name rte --network ansibleforms --restart unless-stopped --stop-timeout 30 \
--env-file /srv/apps/ansibleforms/rte.env \
-v /srv/apps/ansibleforms/persistent:/app/dist/persistent \
-v /srv/apps/ansibleforms/ssh:/home/node/.ssh \
ghcr.io/ansibleforms/ansibleforms-rte-full:7
Once started, both containers are listed:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c0e2a91d7f4 ghcr.io/ansibleforms/ansibleforms-rte-full:7 "/usr/bin/tini -- no…" 10 seconds ago Up 9 seconds (healthy) rte
d91f7b05b67e ghcr.io/ansibleforms/ansibleforms:7 "/usr/bin/tini -- no…" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:8000->8000/tcp ansibleforms
Podman takes the same options and does not require a service:
podman network create ansibleforms
podman run -d --name ansibleforms --network ansibleforms -p 8000:8000 --restart unless-stopped \
--env-file /srv/apps/ansibleforms/ansibleforms.env \
-v /srv/apps/ansibleforms/persistent:/app/dist/persistent \
-v /srv/apps/ansibleforms/ssh:/home/node/.ssh \
ghcr.io/ansibleforms/ansibleforms:7
podman run -d --name rte --network ansibleforms --restart unless-stopped --stop-timeout 30 \
--env-file /srv/apps/ansibleforms/rte.env \
-v /srv/apps/ansibleforms/persistent:/app/dist/persistent \
-v /srv/apps/ansibleforms/ssh:/home/node/.ssh \
ghcr.io/ansibleforms/ansibleforms-rte-full:7
Once started, both containers are listed:
podman ps
The app listens on port 8000, over HTTP unless you set HTTPS=1. The RTE is not published on the host: only the app dials it, inside the network. --stop-timeout 30 gives the RTE time to let its running playbooks end on a stop (see Run an RTE for the RTE settings and for building an RTE of your own).
Test the application
Once the containers are up, open AnsibleForms in a browser:
- Open
http://your_ip:8000(or HTTPS, if you setHTTPS=1) - Log in as
admin/AnsibleForms!123(or with the password you set withADMIN_PASSWORD), and choose a new password - Check under Connections > Runners that the RTE is listed as
rte, the default runner, and that its page shows its Connection as Connected - Next steps:
- Create forms by adding YAML files to the
formsfolder or by using the built-in designer - Add your playbooks to the
playbooksfolder of the mounted persistent folder - Add an LDAP connection
- Add users and groups
- Add runners for template forms: AWX, AAP or Ascender, Semaphore, Rundeck or Jenkins
- Add credentials for external connections, such as other MySQL servers or REST APIs, or to pass to Ansible playbooks
- Create forms by adding YAML files to the