I want to deploy a laravel application using a Dockerfile:
Dockerfile
FROM php:8.1-fpm
WORKDIR /var/www
RUN apt-get update && apt-get install -y --no-install-recommends wget \
default-mysql-client libmagickwand-dev nano procps libzip-dev nginx \
supervisor git-core
&& pecl install imagick \
&& docker-php-ext-enable imagick \
&& docker-php-ext-install pdo_mysql \
&& docker-php-ext-install zip
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install NodeJS + NPM
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
COPY . /var/www
RUN cp docker/supervisord.conf /etc/supervisord.conf
RUN cp docker/php.ini /usr/local/etc/php/conf.d/app.ini
RUN cp docker/nginx.conf /etc/nginx/sites-enabled/default
RUN mkdir /var/log/php
RUN touch /var/log/php/errors.log && chmod 777 /var/log/php/errors.log
RUN composer install --optimize-autoloader --no-dev
RUN chmod +x /var/www/docker/run.sh
RUN chown -R www-data:www-data \
/var/www/storage \
/var/www/bootstrap/cache
EXPOSE 80
ENTRYPOINT ["/var/www/docker/run.sh"]
docker-compose.yml
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: myapp
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '80:80'
volumes:
- '/etc/localtime:/etc/localtime:ro'./data/upload:/var/www/storage/upload
networks:
- mynetwork
depends_on:
- mysql
mysql:
image: 'mysql/mysql-server:8.0'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- './data/mysql:/var/lib/mysql'
- '/etc/localtime:/etc/localtime:ro'
networks:
- mynetwork
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
retries: 3
timeout: 5s
networks:
mynetwork:
driver: bridge
run.sh
#!/bin/sh
cd /var/www
php artisan key:generate
php artisan storage:link
php artisan migrate:fresh --seed
php artisan cache:clear
php artisan route:cache
npm i
npm run production
/usr/bin/supervisord -c /etc/supervisord.conf
supervisord.conf
[supervisord]
nodaemon=true
loglevel = info
logfile=/var/log/supervisord.log
pidfile=/var/run/supervisord.pid
[group:laravel-worker]
priority=999
programs=nginx,php8-fpm
[program:nginx]
priority=10
autostart=true
autorestart=true
stderr_logfile_maxbytes=0
stdout_logfile_maxbytes=0
stdout_events_enabled=true
stderr_events_enabled=true
command=/usr/sbin/nginx -g 'daemon off;'
stderr_logfile=/var/log/nginx/error.log
stdout_logfile=/var/log/nginx/access.log
[program:php8-fpm]
priority=5
autostart=true
autorestart=true
stderr_logfile_maxbytes=0
stdout_logfile_maxbytes=0
command=/usr/local/sbin/php-fpm -R
stderr_logfile=/var/log/nginx/php-error.log
stdout_logfile=/var/log/nginx/php-access.log77
My entry point is the run.sh script, that I need to make everything ready (e.g. migrate and seed the database).
But when I have an update for the app, I will create a new image and this will run the php artisan migrate:fresh -seed command, what I need on the first load, but then never.
When I remove it from the script, I would need to migrate manually, what I want to avoid, as the app will later life build from GitHub Actions.
What can I do to avoid a database loss when I update my app?