Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exec init script only once after docker run but before entrypoint?

Tags:

docker

I am learning docker these days, and starts with building mysql image by myself.

Dockerfile:

FROM centos
MAINTAINER Michael
ENV REFRESHED_AT 2016-07-29
RUN yum install -y mysql mariadb-server
VOLUME /var/lib/mysql
ENTRYPOINT ["/usr/libexec/mysqld", "--user=root"]
EXPOSE 3306

docker run command

docker run -d --name mysql -v /root/docker/mysql/data:/var/lib/mysql -p 3306:3306 michael/mysql

This gave an error because I have to exec mysql_install_db first to init DB. But I could not add RUN mysql_install_db in the Dockerfile since I want to use Volume as external data store.

So how should I do this ?

I know there's an official image named mysql. I just want to do this as practice.


UPDATE: Thanks to @Pieter . I finally did this by using his solution which is provide another entrypoint.sh combines init & start scripts then make it as ENTRYPOINT in Dockerfile :

FROM centos
MAINTAINER Michael
ENV REFRESHED_AT 2016-07-29
RUN yum install -y mysql mariadb-server
VOLUME /var/lib/mysql
COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3306

entrypoint.sh

#!/bin/bash

if [ ! -d "/var/lib/mysql/mysql" ]; then #check whether the DB is initialized.
    echo 'Initializing database'
    mysql_install_db
    echo 'Database initialized'
fi

/usr/libexec/mysqld --user=root

docker run

docker run -d --name mysql -v /root/docker/mysql/data:/var/lib/mysql -p 3306:3306 michael/mysql

And this gives a generic solution for such scenario.

like image 310
Michael Avatar asked Aug 01 '16 03:08

Michael


1 Answers

I'm no expert but for all I know there is no way to run some script before ENTRYPOINT as ENTRYPOINT is literally the first thing your container runs.

What you can do is add a custom script to your docker container that contains both the mysql_install_db and mysqld instructions and use that as the entrypoint.

So your dockerfile might look like this.

FROM centos
MAINTAINER Michael
ENV REFRESHED_AT 2016-07-29
RUN yum install -y mysql mariadb-server
VOLUME /var/lib/mysql
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 3306

entrypoint.sh would simply look like this.

/usr/libexec/mysql_install_db --user=root
/usr/libexec/mysqld --user=root

Note that the same technique is also used in the official mariadb docker image. See https://github.com/docker-library/mariadb/tree/d969a465ee48fe10f4b532276f7337ddaaf3fc36/10.1

Note that the official image combines ENTRYPOINT with CMD. As you're learning docker you might want to take a look at https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/ for more information on how ENTRYPOINT and CMD can be used together.

UPDATE Assuming that mysql_install_db simply creates some files under /var/lib/mysql you should be able to run mysql_install_db as part of your docker build. (This doesn't mean that you should though -> see official mariadb image).

The docker run command initializes a newly created volume with any data that exists at the specified location within the base image. See https://docs.docker.com/engine/reference/builder/#/volume

like image 152
Pieter Avatar answered Nov 15 '22 05:11

Pieter