├── .deploy ├── Dockerfile ├── config │ ├── Caddyfile │ ├── crontab │ ├── php │ │ └── local.ini │ └── supervisor.conf └── entrypoint.sh ├── LICENSE ├── README.md └── captain-definition /.deploy/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION=${PHP_VERSION:-7.4} 2 | FROM php:${PHP_VERSION}-fpm-alpine AS php-system-setup 3 | 4 | # Install system dependencies 5 | RUN apk add --no-cache dcron busybox-suid libcap curl zip unzip git 6 | 7 | # Install PHP extensions 8 | COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/bin/ 9 | RUN install-php-extensions intl bcmath gd pdo_mysql pdo_pgsql opcache redis uuid exif pcntl zip 10 | 11 | # Install supervisord implementation 12 | COPY --from=ochinchina/supervisord:latest /usr/local/bin/supervisord /usr/local/bin/supervisord 13 | 14 | # Install caddy 15 | COPY --from=caddy:2.2.1 /usr/bin/caddy /usr/local/bin/caddy 16 | RUN setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy 17 | 18 | # Install composer 19 | COPY --from=composer/composer:2 /usr/bin/composer /usr/local/bin/composer 20 | 21 | FROM php-system-setup AS app-setup 22 | 23 | # Set working directory 24 | ENV LARAVEL_PATH=/srv/app 25 | WORKDIR $LARAVEL_PATH 26 | 27 | # Add non-root user: 'app' 28 | ARG NON_ROOT_GROUP=${NON_ROOT_GROUP:-app} 29 | ARG NON_ROOT_USER=${NON_ROOT_USER:-app} 30 | RUN addgroup -S $NON_ROOT_GROUP && adduser -S $NON_ROOT_USER -G $NON_ROOT_GROUP 31 | RUN addgroup $NON_ROOT_USER wheel 32 | 33 | # Set cron job 34 | COPY ./.deploy/config/crontab /etc/crontabs/$NON_ROOT_USER 35 | RUN chmod 777 /usr/sbin/crond 36 | RUN chown -R $NON_ROOT_USER:$NON_ROOT_GROUP /etc/crontabs/$NON_ROOT_USER && setcap cap_setgid=ep /usr/sbin/crond 37 | 38 | # Switch to non-root 'app' user & install app dependencies 39 | COPY composer.json composer.lock ./ 40 | RUN chown -R $NON_ROOT_USER:$NON_ROOT_GROUP $LARAVEL_PATH 41 | USER $NON_ROOT_USER 42 | RUN composer install --prefer-dist --no-scripts --no-dev --no-autoloader 43 | RUN rm -rf /home/$NON_ROOT_USER/.composer 44 | 45 | # Copy app 46 | COPY --chown=$NON_ROOT_USER:$NON_ROOT_GROUP . $LARAVEL_PATH/ 47 | COPY ./.deploy/config/php/local.ini /usr/local/etc/php/conf.d/local.ini 48 | 49 | # Set any ENVs 50 | ARG APP_KEY=${APP_KEY} 51 | ARG APP_NAME=${APP_NAME} 52 | ARG APP_URL=${APP_URL} 53 | ARG APP_ENV=${APP_ENV} 54 | ARG APP_DEBUG=${APP_DEBUG} 55 | 56 | ARG LOG_CHANNEL=${LOG_CHANNEL} 57 | 58 | ARG DB_CONNECTION=${DB_CONNECTION} 59 | ARG DB_HOST=${DB_HOST} 60 | ARG DB_PORT=${DB_PORT} 61 | ARG DB_DATABASE=${DB_DATABASE} 62 | ARG DB_USERNAME=${DB_USERNAME} 63 | ARG DB_PASSWORD=${DB_PASSWORD} 64 | 65 | ARG BROADCAST_DRIVER=${BROADCAST_DRIVER} 66 | ARG CACHE_DRIVER=${CACHE_DRIVER} 67 | ARG QUEUE_CONNECTION=${QUEUE_CONNECTION} 68 | ARG SESSION_DRIVER=${SESSION_DRIVER} 69 | ARG SESSION_LIFETIME=${SESSION_LIFETIME} 70 | 71 | ARG REDIS_HOST=${REDIS_HOST} 72 | ARG REDIS_PASSWORD=${REDIS_PASSWORD} 73 | ARG REDIS_PORT=${REDIS_PORT} 74 | 75 | ARG MAIL_MAILER=${MAIL_MAILER} 76 | ARG MAIL_HOST=${MAIL_HOST} 77 | ARG MAIL_PORT=${MAIL_PORT} 78 | ARG MAIL_USERNAME=${MAIL_USERNAME} 79 | ARG MAIL_PASSWORD=${MAIL_PASSWORD} 80 | ARG MAIL_ENCRYPTION=${MAIL_ENCRYPTION} 81 | ARG MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS} 82 | ARG MAIL_ENCRYPTION=${MAIL_ENCRYPTION} 83 | ARG MAIL_FROM_NAME=${APP_NAME} 84 | 85 | ARG PUSHER_APP_ID=${PUSHER_APP_ID} 86 | ARG PUSHER_APP_KEY=${PUSHER_APP_KEY} 87 | ARG PUSHER_APP_SECRET=${PUSHER_APP_SECRET} 88 | ARG PUSHER_APP_CLUSTER=${PUSHER_APP_CLUSTER} 89 | 90 | # Start app 91 | EXPOSE 80 92 | COPY ./.deploy/entrypoint.sh / 93 | 94 | ENTRYPOINT ["sh", "/entrypoint.sh"] 95 | -------------------------------------------------------------------------------- /.deploy/config/Caddyfile: -------------------------------------------------------------------------------- 1 | :80 { 2 | root * /srv/app/public 3 | 4 | @websockets { 5 | header Connection *upgrade* 6 | header Upgrade websocket 7 | } 8 | reverse_proxy @websockets 127.0.0.1:6001 { 9 | header_down -X-Powered-By 10 | } 11 | 12 | redir /index.php / 308 13 | redir /index.php/ / 308 14 | route /index.php/* { 15 | uri strip_prefix /index.php 16 | redir {path} 308 17 | } 18 | 19 | php_fastcgi 127.0.0.1:9000 20 | encode gzip 21 | header -X-Powered-By 22 | file_server 23 | log 24 | } 25 | -------------------------------------------------------------------------------- /.deploy/config/crontab: -------------------------------------------------------------------------------- 1 | * * * * * /usr/local/bin/php /srv/app/artisan schedule:run > /proc/1/fd/1 2>/proc/1/fd/2 2 | -------------------------------------------------------------------------------- /.deploy/config/php/local.ini: -------------------------------------------------------------------------------- 1 | memory_limit = 512M 2 | max_execution_time = 30 3 | upload_max_filesize = 30M 4 | post_max_size = 35M 5 | -------------------------------------------------------------------------------- /.deploy/config/supervisor.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | logfile=/dev/null 3 | logfile_maxbytes=0 4 | logfile_backups=0 5 | loglevel=info 6 | nodaemon=true 7 | 8 | [program:php-fpm] 9 | command=php-fpm --nodaemonize 10 | autorestart=true 11 | stdout_events_enabled=true 12 | stderr_events_enabled=true 13 | stdout_logfile_maxbytes=0 14 | stderr_logfile_maxbytes=0 15 | stdout_logfile=/dev/stdout 16 | stderr_logfile=/dev/stderr 17 | 18 | [program:caddy] 19 | command=caddy run --config %(ENV_LARAVEL_PATH)s/.deploy/config/Caddyfile 20 | autorestart=true 21 | stdout_events_enabled=true 22 | stderr_events_enabled=true 23 | stdout_logfile_maxbytes=0 24 | stderr_logfile_maxbytes=0 25 | stdout_logfile=/dev/stdout 26 | stderr_logfile=/dev/stderr 27 | 28 | [program:cron] 29 | command=crond -l 2 -f 30 | autorestart=true 31 | 32 | ; [program:horizon] 33 | ; command=php %(ENV_LARAVEL_PATH)s/artisan horizon 34 | ; autorestart=true 35 | ; stdout_events_enabled=true 36 | ; stderr_events_enabled=true 37 | ; stdout_logfile_maxbytes=0 38 | ; stderr_logfile_maxbytes=0 39 | ; stdout_logfile=/dev/stdout 40 | ; stderr_logfile=/dev/stderr 41 | ; stopwaitsecs=3600 42 | 43 | ; [program:websockets] 44 | ; command=php %(ENV_LARAVEL_PATH)s/artisan websockets:serve --port=6001 45 | ; numprocs=1 46 | ; autorestart=true 47 | ; stdout_events_enabled=true 48 | ; stderr_events_enabled=true 49 | ; stdout_logfile_maxbytes=0 50 | ; stderr_logfile_maxbytes=0 51 | ; stdout_logfile=/dev/stdout 52 | ; stderr_logfile=/dev/stderr 53 | -------------------------------------------------------------------------------- /.deploy/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "🎬 entrypoint.sh: [$(whoami)] [PHP $(php -r 'echo phpversion();')]" 4 | 5 | composer dump-autoload --no-interaction --no-dev --optimize 6 | 7 | echo "🎬 artisan commands" 8 | 9 | # 💡 Group into a custom command e.g. php artisan app:on-deploy 10 | php artisan migrate --no-interaction --force 11 | 12 | echo "🎬 start supervisord" 13 | 14 | supervisord -c $LARAVEL_PATH/.deploy/config/supervisor.conf 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jack Bryce-Smith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | +
6 |
7 |
8 |
9 |
14 | Template to deploy a Laravel app to a server managed by CapRover. 15 |
16 | 17 |18 | 19 | jack.bryce-smith.com/💡/laravel-docker-caprover 20 | 21 |
22 | 23 | ## Features 24 | 25 | - 🐳 Lightweight [PHP](https://github.com/jackbrycesmith/laravel-caprover-template/blob/master/.deploy/Dockerfile#L1) image with [common extensions](https://github.com/jackbrycesmith/laravel-caprover-template/blob/master/.deploy/Dockerfile#L21) 26 | - [Overridable PHP version](https://github.com/jackbrycesmith/laravel-caprover-template/pull/13) 27 | - Add other required extensions easily; [thanks to mlocati/docker-php-extension-installer](https://github.com/mlocati/docker-php-extension-installer) 28 | - 📦 [Installs composer dependencies](https://github.com/jackbrycesmith/laravel-caprover-template/blob/master/.deploy/Dockerfile#L30); cached between builds if no changes 29 | - ⚡️ Served via [Caddy 2](https://github.com/caddyserver/caddy) 30 | - ⏰ [Setup to call](https://github.com/jackbrycesmith/laravel-caprover-template/blob/master/.deploy/Dockerfile#L11) the [Laravel command scheduler](https://laravel.com/docs/7.x/scheduling) 31 | - 🛰 Straightforward websockets support 32 | - 💪 [Services will restart](https://github.com/jackbrycesmith/laravel-caprover-template/blob/master/.deploy/config/supervisor.conf) thanks to [supervisord](https://github.com/ochinchina/supervisord) 33 | 34 | ## Usage 35 | 36 | 1. [Install Laravel](https://laravel.com/docs/installation) 37 | > *e.g. Zsh one-liner with the [Laravel Installer](https://github.com/laravel/installer):* 38 | >laravel new my-app --prompt-jetstream && mv my-app/*(DN) ./ && rm -rf my-app
39 | 2. jack.bryce-smith.com/💡/laravel-docker-caprover
40 | 3. [Deploy to CapRover](https://caprover.com/docs/deployment-methods.html), e.g. `caprover deploy`
41 |
--------------------------------------------------------------------------------
/captain-definition:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion" :2 ,
3 | "dockerfilePath" : "./.deploy/Dockerfile"
4 | }
5 |
6 |
--------------------------------------------------------------------------------