DEV Community

loading...
Cover image for Docker and Dancer (Take 2)

Docker and Dancer (Take 2)

Dave Cross
Geek, Fintech, SEO, Lefty. Feminist, Atheist. Skeptic. Rationalist. Secularist. Humanist. Republican (UK Meaning!). Londoner. Music lover. Writer. Genealogist.
・3 min read

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

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

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. 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.

Discussion (2)

Collapse
chrborup profile image
Christian Borup

You don't need your Dockerfile-db, it's easier to just pass set up the volume on the command line (or in docker-compose.yaml). Provided you are willing to rename your .dump to .sql...

docker ... -v $(pwd)/data:/docker-entrypoint-initdb.d ...

Would yield the same result.

Collapse
davorg profile image
Dave Cross Author

Excellent suggestion. Thank you; that works well.