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="email@example.com" 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
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
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="firstname.lastname@example.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
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.