Docker and Dancer (Take 2)

Dave Cross - Aug 29 '19 - - Dev Community

A few months ago, I published my first attempt at building a Docker container 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
Enter fullscreen mode Exit fullscreen mode

The first thing you'll (hopefully) notice is that it's simpler than the previous version. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

The MARIADB_* environment variables are all documented on the Docker Hub page for the image. 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
Enter fullscreen mode Exit fullscreen mode

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.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .