Alana Storm
Alana Storm

Reputation: 166066

Docker: Creating a Fully Installed PHP Application

Can I use docker-compose to create a one step setup for a completely installed PHP application? Since that's a pretty vague questions. I will use WordPress as an example.

If I look at the official wordpress docker repositories, I see there's already a super-useful yml file for docker-composer

version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'

This is great and gets me a running frontend app server with WordPress already there. It also gets a database server. It sets up everything to talk to one another. That's all great.

What this doesn't get me is a fully installed WordPress. Like a lot of PHP applications, in order to be fully installed there's a few additional configuration fields that need to be set, and a few additional database fields as well.

This means I can't fully install the application until the both the wordpress and db container are fully up. I've thought about hacking up a workaround where I have the CMD or ENTRYPOINT wait around for a DB connection to be established, but the base WordPress Dockerfile(s) already uses ENTRYPOINT and CMD so that's not an option. (or is it?)

Is there an elegant, docker-ish way to do what I want to do? Or am I stuck telling my users to docker-compose up, and then run a second command to finish the installation?

Upvotes: 1

Views: 429

Answers (4)

Wiktor Karpinski
Wiktor Karpinski

Reputation: 11

As far as I know, the MySQL image has its own startup script which may still run after the container is ready. This startup script can be used to import data into the database - MySQL connections still wil not get accepted, but docket will think that your db is ready.

What this means for you is that if for any reason the db init script runs longer, it will stop the php install commands from working.

You might need to implement a polling thread which will wait for the database to start - only then run the install scripts on php.

Here’s an article I found that details a similar problem.

https://cweiske.de/tagebuch/docker-mysql-available.htm

There might be some other tips that might be appropriate for your use case, but I would need to know a bit more context.

EDIT:

Check docker healthchecks. This might fit your usecase.

https://docs.docker.com/compose/compose-file/#healthcheck

Upvotes: 1

Pranav G.
Pranav G.

Reputation: 71

If there are some commands that you want to run after the containers are up then there is a way. I don't know if it's the standard way to do it in docker but it will work.

As you already know that the wordpress image has its own ENTRYPOINT which is the script docker-entrypoint.sh.

So what you can do is put your custom command inside this script which will be executed on wordpress container start.

You can do it as follows :

  • Start your container and copy the contents of the existing docker-entrypoint.sh

  • Create a new docker-entrypoint.sh outside the container and edit that script to add your chmod command at appropriate location.

  • In your Dockerfile add a line to copy this new entrypoint script to the
    location /usr/local/bin/docker-entrypoint.sh

NOTE:

Do not put your custom command at the end of the script docker-entrypoint.sh. You can put it anywhere before the line exec "$@".

Upvotes: 1

Becquerel
Becquerel

Reputation: 406

What you will probably have to do is to create your own Dockerfile based on the Wordpress image, and then give them your own stuff to run.

I believe something like this should work

docker-compose.yml

version: '3.1'

services:

  wordpress:
    build:
      context: ./docker/wordpress
    restart: always
    ports:
      - 8080:80
    depends_on:
      - "db"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'

./docker/wordpress/Dockerfile

FROM wordpress
RUN your-own-commands

I only briefly put together, so it is not really tested, but it should give you a general idea and direction

Upvotes: 1

Mostafa Hussein
Mostafa Hussein

Reputation: 11940

If there are extra steps that you do manually or through scripts after running docker-compose up for the docker-compose posted in your question you can modify the original wordpress image with your own image in order to make it work as expected for your business needs all you have to do is to start writing a new Dockerfile that produces a new customized wordpress image. So you can do the following as an example:

FROM wordpress:5.1.0-php7.1-apache
COPY custom_docker-entrypoint.sh /usr/local/bin/

ENTRYPOINT ["custom_docker-entrypoint.sh"]
CMD ["apache2-foreground"]

The custom_docker-entrypoint.sh represents the extra steps which needed to be done. also you may introduce new environment variables inside the entrypoint script so you can make the process dynamic as possible for different clients without the need to build a custom image for each client.

The generated image can be used in your docker-compose file instead of the official one

Upvotes: 2

Related Questions