How to migrate from docker-compose to vagrant?
Tags: docker, dockercompose, vagrant
Published: 2022-10-11 09:25:31

---
title: How to migrate from docker-compose to vagrant?
published: true
description: How to reproduce multi container setup in docker-compose file in vagrant?
tags: docker, dockercompose, vagrant
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
---
Consider you are building multiple containers with networking using docker-compose and for some reason you want to do the same thing in vagrant, how can it be done?

Here is a example: 
First the working docker-compose setup. In this example we will build docker containers for `mysql` and `phpmyadmin`. `phpmyadmin` will be connected to the `mysql` container instance with in the same network.
```
version: '3.7'
services:
  db:
    image: mysql:5.7.36
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: test_db
    ports:
      - "3308:3306"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    restart: always
    environment:
      PMA_HOST: db
      PMA_USER: root
      PMA_PASSWORD: root
    ports:
      - "8080:80"
```
Lets do the same thing in `vagrant`. 
```
# -*- mode: ruby -*-
# vi: set ft=ruby :

# This file works exactly like the docker-compose.yml file.
Vagrant.configure("2") do |config|
    config.vm.network :private_network, type: "dhcp"
    config.vm.define "mysql" do |db|
        # Without prot forwardign vagrant entwork doesnt work
        db.vm.network "forwarded_port", guest: 3306, host: 3306
        db.vm.hostname = "mysqldb"
        db.vm.provider "docker" do |d|
          d.image = "mysql:5.7.36"
          d.env = {
            :MYSQL_ROOT_PASSWORD  => "root",
            :MYSQL_DATBASE        => "test_db"
          }
          d.remains_running = "true"
        end
      end
    config.vm.define "phpmyadmin" do |pa|
        pa.vm.network "forwarded_port", guest: 80, host: 8080
        pa.vm.hostname = "phpmyadmin"
        pa.vm.provider "docker" do |d|
            d.image = "phpmyadmin/phpmyadmin:latest"
            d.env = {
                :PMA_HOST       => "mysqldb",
                :PMA_USER       => "root",
                :PMA_PASSWORD   => "root",
                # Without specifying the specific port phpmyadmin container doesn't work
                :PMA_PORT       => "3306", 
            }
            d.remains_running = "true"
        end
    end
end
```
---
Unlike `docker-compose` it is not possible to set a direct dependency in `vagrant`. But it is possible to do a sequential build by setting the option `--no-parallel` eg:- `vagrant up --no-parallel`.

Even though `docker-compose` has the dependency set, the dependency is only to the extent of waiting for the dependent container to be built but not waiting for the services in the container to be up and running.

Hence even after building sequentially in `vagrant`, the dependent services failed to connect. It did not matter `vagrant` or `docker-compose`. Services with in the containers need to wait for their dependent services to be up.

So I added a delay in the dependent containers in a timed loop, the dependent service will attempt to connect and upon failure will wait for 30 seconds to connect again, after 10 attempts it gives up.