Docker and Dancer (Take 2)
Tags: perl, docker, aws, dancer
Published: 2019-08-29 17:29:06

---
title: Docker and Dancer (Take 2)
published: true
tags: perl, docker, aws, dancer
series: Into the Cloud
cover_image: https://thepracticaldev.s3.amazonaws.com/i/r172e0ipwn9t9tkgkmfx.jpg 
---

A few months ago, I published [my first attempt at building a Docker container](https://dev.to/davorg/docker-and-dancer-4m82) for the Dancer application that powers one of my web sites. It was blatantly obvious that I was learning as I was going and the Dockerfile I was using was rather out of date. I got a deluge of good advice from various people knew a lot more about this stuff than I do.

It might have looked like I had abandoned the project, but that's not the case. A few other things took a lot of my time recently, but now I'm back to look at this again.

So here's take 2 of my Dockerfile:

    FROM perl:5.30.0
    LABEL maintainer="dave@perlhacks.org"

    EXPOSE 1701
    CMD carton exec starman --port 1701 Succession/bin/app.psgi

    RUN cpanm Carton Starman

    COPY . /succession
    RUN cd /succession && carton install --deployment
    WORKDIR /succession

The first thing you'll (hopefully) notice is that it's simpler than [the previous version](https://dev.to/davorg/docker-and-dancer-4m82). I've been able to remove a few instructions - there were some things that were already installed on my base image (`cpanm` and a few C libraries that I was using).

Oh, and I've moved the Dockerfile into the main code repo instead of having a separate one and having to clone the real repo into it. I really don't understand why I thought that was a good idea!

I'm not going to explain it line by line like I did last time - that would be a little repetitive.

I build an image from this file using the same `docker` command as I previously did (`docker build -t succession .`) and then run the container from this image with this simple shell script:

    docker run --name succession \
      --network="host"
      -e SUCC_DB_HOST \
      -e SUCC_DB_NAME \
      -e SUCC_DB_USER \
      -e SUCC_DB_PASS \
      -p 1701:1701 succession

The various `SUCC_DB_*` environment variables used in the script contain the connection details for the database that the application uses. And if I have a database running and those variables set correctly, then I can get the application in a browser looking at port 1701 on `localhost`.

Of course, the next thing I need is to get the database running in another container. And I now think I have a solution for that. I've created another Dockerfile called `Dockerfile-db` and it contains this:

    FROM mariadb/server:10.3
    LABEL maintainer="dave@perlhacks.org"

    COPY data/succession.dump /docker-entrypoint-initdb.d/succession.dump.sql

As you'll see, it's very simple. I've based it on an official MariaDB image and the only thing I've added is to copy a file from the Git checkout into a directory called `/docker-entrypoint-initdb.d`. If the MariaDB image sees a file with the extension `.sql` in that directory at run-time, then that data is loaded into the database. As it happens, my data is pretty static and I already have a dump of it in the Git repo.

I build my image with the command `docker build -t succession-db -f Dockerfile-db .` and then run it with this script:


    docker run --name succession-db \
      -e MARIADB_ROOT_PASSWORD=sekrit \
      -e MARIADB_DATABASE=$SUCC_DB_NAME \
      -e MARIADB_USER=$SUCC_DB_USER \
      -e MARIADB_PASSWORD=$SUCC_DB_PASS \
      -p 13306:3306 -d succession-db

The `MARIADB_*` environment variables are all documented on the [Docker Hub page for the image](https://hub.docker.com/r/mariadb/server). And I've remapped the port to a higher number so it doesn't clash with any DB server that might already be running on the host.

Once I've run that, I can connect to the server by running:

    mysql -h127.0.0.1 -u$SUCC_DB_USER -P 13306 -p$SUCC_DB_PASS -D$SUCC_DB_NAME

And I can see all of my data in the database.

So I have one container running my app and another running my database. The next step is to get them starting up together and talking to each other. That sounds like a job for `docker-compose`. And a good topic for the next article in this series.