Ship Application with Database Inside Docker Container
Feb 28, 2020 · 4 Min Read · 12 Likes · 2 Comments
DISCLAIMER: This is not the recommended process. Ideally you should have the database running in a separate container and use network to interact with that container.
Usually, we don’t ship application with the database inside the same container. But sometimes we are forced to do that. In this article we are going to see a minimalist way of shipping application with database built-in inside docker container.
Overview of the implementation
We will inherit the database image(ie official PostgreSQL image or MySQL image etc) as base and build it from there. We will write our own entrypoint
script, and call the parent image’s entrypoint script inside our entrypoint with arguments we receive from CMD
directive. With that, we will run additional commands which are required for running our application. Key points to remember here are:
- Override the base image’s entrypoint script inside our entrypoint script.
- Keep the
CMD
of the child(ourDockerfile
) same as the parent. For example:CMD ["postgres"]
for PostgreSQL,CMD ["mysqld"]
for MySQL. - In our entrypoint, we will add additional commands and scripts for running our application.
Codes for PostgreSQL based image
Write Dockerfile for PostgreSQL
First let us write a Dockerfile
based on postgres:12-alpine
:
FROM postgres:12-alpine
ENV POSTGRES_USERNAME 'postgres'
ENV POSTGRES_PASSWORD 'postgres'
ENV POSTGRES_DB 'postgres'
# Install your dependencies here
WORKDIR /src
ADD ./src /src
COPY my-entry-point.sh /
RUN chmod +x /my-entry-point.sh
# not necessary if you are planning to run commands without a bash file
COPY application-related-commands.sh /
RUN chmod +x /application-related-commands.sh
# entrypoint
ENTRYPOINT ["/my-entry-point.sh"]
CMD ["postgres"]
# expose port necessary for your application
EXPOSE 8000
Write entrypoint and application related scripts for PostgreSQL
Now, write necessary commands inside application-related-commands.sh
to run our app and put it in the same directory as Dockerfile
. Finally add your my-entry-point.sh
in the same directory as Dockerfile
like this:
#!/bin/sh
/usr/local/bin/docker-entrypoint.sh "$@" & /application-related-commands.sh
Instead of /application-related-commands
, you can add your custom commands without needing any files.
Here we are running the parent image’s(PostgreSQL) entry point script by /usr/local/bin/docker-entrypoint.sh
because if you check the source code in github, you will see that the entry point script is being stored in /usr/local/bin/
folder.
Build and run docker with PostgreSQL
Use this command to build:
docker build . -t psql-based-image
And run with:
docker run -p 8000:8000 -v /your/path:/var/lib/postgresql/data/ -t psql-based-image
Codes for MySQL based image
Write Dockerfile for MySQL
This is similar to the above implementation, apart from the CMD
directive. Let us write a Dockerfile
based on mysql:8
:
FROM mysql:8
ENV MYSQL_ROOT_PASSWORD 'mypassword'
# Install your dependencies here
WORKDIR /src
ADD ./*.jar /src/runable.jar
COPY my-entry-point.sh /
RUN chmod +x /my-entry-point.sh
# not necessary if you are planning to run commands without a bash file
COPY application-related-commands.sh /
RUN chmod +x /application-related-commands.sh
# entrypoint
ENTRYPOINT ["/my-entry-point.sh"]
CMD ["mysqld"]
# expose port necessary for your application
EXPOSE 7654
Write entrypoint and application related scripts for MySQL
Implementation of the rest of the stuff(my-entry-point.sh
and application-related-commands.sh
) are same as PostgreSQL image based implementation.
Build and run docker with MySQL
Use this command to build:
docker build . -t mysql-based-image
And run with:
docker run -p 7654:7654 -t mysql-based-image
Working examples in github
In this article, we have seen an overview on how we might be able to ship applications with database. For working examples, please checkout this repository on github. It has examples of:
- A Python Application with MySQL in Docker
- A Python Application with PostgreSQL in Docker
- A Django Project with MySQL in Docker
- A Django Project with PostgreSQL in Docker
- A Java App with MySQL in Docker
- A Java App with PostgreSQL in Docker
In conclusion
I still think this solution is far from perfect, maybe you can suggest better ideas. Let us discuss more in the comment section below.
Last updated: Feb 15, 2025
If I create my entrypoint file ENTRYPOINT [“new_env.sh”], after starting docker of postgres container, if you try to restore backup db, I get an error: pg_ctl: directory “/var/lib/postgresql/data” is not a database cluster directory
How can I call the default entrypoint-file docker postgres first?
Calling entry-point of postgres from your entry point is already covered in this section. Please let me know if you face further problems.