diff --git a/README.md b/README.md index a65365b6e..b9a2b4b24 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ # docker-compose-laravel A pretty simplified Docker Compose workflow that sets up a LEMP network of containers for local Laravel development. You can view the full article that inspired this repo [here](https://dev.to/aschmelyun/the-beauty-of-docker-for-local-laravel-development-13c0). -[![GitNFT](https://img.shields.io/badge/%F0%9F%94%AE-Open%20in%20GitNFT-darkviolet?style=flat)](https://gitnft.quine.sh/app/commits/list/repo/docker-compose-laravel) - ## Usage To get started, make sure you have [Docker installed](https://docs.docker.com/docker-for-mac/install/) on your system, and then clone this repository. -Next, navigate in your terminal to the directory you cloned this, and spin up the containers for the web server by running `docker-compose up -d --build site`. +Next, navigate in your terminal to the directory you cloned this, and spin up the containers for the web server by running `docker-compose up -d --build app`. After that completes, follow the steps from the [src/README.md](src/README.md) file to get your Laravel project added in (or create a new blank one). -Bringing up the Docker Compose network with `site` instead of just using `up`, ensures that only our site's containers are brought up at the start, instead of all of the command containers as well. The following are built for our web server, with their exposed ports detailed: +**Note**: Your MySQL database host name should be `mysql`, **not** `localhost`. The username and database should both be `homestead` with a password of `secret`. + +Bringing up the Docker Compose network with `app` instead of just using `up`, ensures that only our site's containers are brought up at the start, instead of all of the command containers as well. The following are built for our web server, with their exposed ports detailed: - **nginx** - `:80` - **mysql** - `:3306` @@ -32,7 +32,7 @@ If you encounter any issues with filesystem permissions while visiting your appl **If you are using your server or local environment as the root user:** - Bring any container(s) down with `docker-compose down` -- Rename `docker-compose.root.yml` file to `docker-compose.root.yml`, replacing the previous one +- Replace any instance of `php.dockerfile` in the docker-compose.yml file with `php.root.dockerfile` - Re-build the containers by running `docker-compose build --no-cache` **If you are using your server or local environment as a user that is not root:** @@ -56,28 +56,32 @@ volumes: - ./mysql:/var/lib/mysql ``` -## Using BrowserSync with Laravel Mix +## Usage in Production -If you want to enable the hot-reloading that comes with Laravel Mix's BrowserSync option, you'll have to follow a few small steps. First, ensure that you're using the updated `docker-compose.yml` with the `:3000` and `:3001` ports open on the npm service. Then, add the following to the end of your Laravel project's `webpack.mix.js` file: +While I originally created this template for local development, it's robust enough to be used in basic Laravel application deployments. The biggest recommendation would be to ensure that HTTPS is enabled by making additions to the `nginx/default.conf` file and utilizing something like [Let's Encrypt](https://hub.docker.com/r/linuxserver/letsencrypt) to produce an SSL certificate. -```javascript -.browserSync({ - proxy: 'site', - open: false, - port: 3000, -}); -``` +## Compiling Assets -From your terminal window at the project root, run the following command to start watching for changes with the npm container and its mapped ports: +This configuration should be able to compile assets with both [laravel mix](https://laravel-mix.com/) and [vite](https://vitejs.dev/). In order to get started, you first need to add ` --host 0.0.0.0` after the end of your relevant dev command in `package.json`. So for example, with a Laravel project using Vite, you should see: -```bash -docker-compose run --rm --service-ports npm run watch +```json +"scripts": { + "dev": "vite --host 0.0.0.0", + "build": "vite build" +}, ``` -That should keep a small info pane open in your terminal (which you can exit with Ctrl + C). Visiting [localhost:3000](http://localhost:3000) in your browser should then load up your Laravel application with BrowserSync enabled and hot-reloading active. +Then, run the following commands to install your dependencies and start the dev server: + +- `docker-compose run --rm npm install` +- `docker-compose run --rm --service-ports npm run dev` + +After that, you should be able to use `@vite` directives to enable hot-module reloading on your local Laravel application. + +Want to build for production? Simply run `docker-compose run --rm npm run build`. ## MailHog -The current version of Laravel (8 as of today) uses MailHog as the default application for testing email sending and general SMTP work during local development. Using the provided Docker Hub image, getting an instance set up and ready is simple and straight-forward. The service is included in the `docker-compose.yml` file, and spins up alongside the webserver and database services. +The current version of Laravel (9 as of today) uses MailHog as the default application for testing email sending and general SMTP work during local development. Using the provided Docker Hub image, getting an instance set up and ready is simple and straight-forward. The service is included in the `docker-compose.yml` file, and spins up alongside the webserver and database services. To see the dashboard and view any emails coming through the system, visit [localhost:8025](http://localhost:8025) after running `docker-compose up -d site`. diff --git a/docker-compose.root.yml b/docker-compose.root.yml deleted file mode 100644 index aac0bc95e..000000000 --- a/docker-compose.root.yml +++ /dev/null @@ -1,107 +0,0 @@ -version: '3' - -networks: - laravel: - -services: - site: - build: - context: ./dockerfiles - dockerfile: nginx.root.dockerfile - container_name: nginx - ports: - - 80:80 - volumes: - - ./src:/var/www/html:delegated - depends_on: - - php - - redis - - mysql - - mailhog - networks: - - laravel - - mysql: - image: mariadb:10.6 - container_name: mysql - restart: unless-stopped - tty: true - ports: - - 3306:3306 - environment: - MYSQL_DATABASE: homestead - MYSQL_USER: homestead - MYSQL_PASSWORD: secret - MYSQL_ROOT_PASSWORD: secret - SERVICE_TAGS: dev - SERVICE_NAME: mysql - networks: - - laravel - - php: - build: - context: ./dockerfiles - dockerfile: php.root.dockerfile - container_name: php - volumes: - - ./src:/var/www/html:delegated - networks: - - laravel - - redis: - image: redis:alpine - container_name: redis - restart: unless-stopped - ports: - - 6379:6379 - networks: - - laravel - - composer: - image: composer:2 - container_name: composer - volumes: - - ./src:/var/www/html - working_dir: /var/www/html - depends_on: - - php - user: root - entrypoint: ['composer', '--ignore-platform-reqs'] - networks: - - laravel - - npm: - image: node:13.7 - container_name: npm - volumes: - - ./src:/var/www/html - ports: - - 3000:3000 - - 3001:3001 - working_dir: /var/www/html - entrypoint: ['npm'] - networks: - - laravel - - artisan: - build: - context: ./dockerfiles - dockerfile: php.root.dockerfile - container_name: artisan - volumes: - - ./src:/var/www/html:delegated - depends_on: - - mysql - working_dir: /var/www/html - entrypoint: ['php', '/var/www/html/artisan'] - networks: - - laravel - - mailhog: - image: mailhog/mailhog:latest - container_name: mailhog - ports: - - 1025:1025 - - 8025:8025 - networks: - - laravel diff --git a/docker-compose.yml b/docker-compose.yml index bc731d8e6..809ac4a15 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,17 +3,17 @@ version: '3' networks: laravel: + services: - site: + app: build: context: ./dockerfiles dockerfile: nginx.dockerfile args: - UID=${UID:-1000} - GID=${GID:-1000} - container_name: nginx ports: - - 80:80 + - "80:80" volumes: - ./src:/var/www/html:delegated depends_on: @@ -26,11 +26,10 @@ services: mysql: image: mariadb:10.6 - container_name: mysql restart: unless-stopped tty: true ports: - - 3306:3306 + - "3306:3306" environment: MYSQL_DATABASE: homestead MYSQL_USER: homestead @@ -48,7 +47,8 @@ services: args: - UID=${UID:-1000} - GID=${GID:-1000} - container_name: php + ports: + - "9000:9000" volumes: - ./src:/var/www/html:delegated networks: @@ -56,41 +56,37 @@ services: redis: image: redis:alpine - container_name: redis restart: unless-stopped ports: - - 6379:6379 + - "6379:6379" networks: - laravel composer: build: context: ./dockerfiles - dockerfile: composer.dockerfile + dockerfile: php.dockerfile args: - UID=${UID:-1000} - GID=${GID:-1000} - container_name: composer volumes: - ./src:/var/www/html - working_dir: /var/www/html depends_on: - php - user: laravel - entrypoint: ['composer', '--ignore-platform-reqs'] + entrypoint: [ 'composer', '--ignore-platform-reqs' ] networks: - laravel npm: - image: node:13.7 - container_name: npm + image: node:current-alpine volumes: - ./src:/var/www/html ports: - - 3000:3000 - - 3001:3001 + - "3000:3000" + - "3001:3001" + - "5173:5173" working_dir: /var/www/html - entrypoint: ['npm'] + entrypoint: [ 'npm' ] networks: - laravel @@ -101,21 +97,18 @@ services: args: - UID=${UID:-1000} - GID=${GID:-1000} - container_name: artisan volumes: - ./src:/var/www/html:delegated depends_on: - mysql - working_dir: /var/www/html - entrypoint: ['php', '/var/www/html/artisan'] + entrypoint: [ 'php', '/var/www/html/artisan' ] networks: - laravel mailhog: image: mailhog/mailhog:latest - container_name: mailhog ports: - - 1025:1025 - - 8025:8025 + - "1025:1025" + - "8025:8025" networks: - laravel diff --git a/dockerfiles/composer.dockerfile b/dockerfiles/composer.dockerfile deleted file mode 100644 index 12ec12f37..000000000 --- a/dockerfiles/composer.dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM composer:2 - -ARG UID -ARG GID - -ENV UID=${UID} -ENV GID=${GID} - -# MacOS staff group's gid is 20, so is the dialout group in alpine linux. We're not using it, let's just remove it. -RUN delgroup dialout - -RUN addgroup -g ${GID} --system laravel -RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel - -WORKDIR /var/www/html diff --git a/dockerfiles/nginx.root.dockerfile b/dockerfiles/nginx.root.dockerfile deleted file mode 100644 index 1b1cf9100..000000000 --- a/dockerfiles/nginx.root.dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM nginx:stable-alpine - -RUN sed -i "s/user nginx/user root/g" /etc/nginx/nginx.conf - -ADD ./nginx/default.conf /etc/nginx/conf.d/ - -RUN mkdir -p /var/www/html \ No newline at end of file diff --git a/dockerfiles/php.dockerfile b/dockerfiles/php.dockerfile index a5f7be283..2b7d29dfb 100644 --- a/dockerfiles/php.dockerfile +++ b/dockerfiles/php.dockerfile @@ -10,6 +10,8 @@ RUN mkdir -p /var/www/html WORKDIR /var/www/html +COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer + # MacOS staff group's gid is 20, so is the dialout group in alpine linux. We're not using it, let's just remove it. RUN delgroup dialout @@ -26,5 +28,7 @@ RUN mkdir -p /usr/src/php/ext/redis \ && curl -L https://github.com/phpredis/phpredis/archive/5.3.4.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \ && echo 'redis' >> /usr/src/php-available-exts \ && docker-php-ext-install redis + +USER laravel CMD ["php-fpm", "-y", "/usr/local/etc/php-fpm.conf", "-R"] diff --git a/dockerfiles/php.root.dockerfile b/dockerfiles/php.root.dockerfile index 05e6625a5..51205eee0 100644 --- a/dockerfiles/php.root.dockerfile +++ b/dockerfiles/php.root.dockerfile @@ -4,6 +4,8 @@ RUN mkdir -p /var/www/html WORKDIR /var/www/html +COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer + RUN sed -i "s/user = www-data/user = root/g" /usr/local/etc/php-fpm.d/www.conf RUN sed -i "s/group = www-data/group = root/g" /usr/local/etc/php-fpm.d/www.conf RUN echo "php_admin_flag[log_errors] = on" >> /usr/local/etc/php-fpm.d/www.conf @@ -14,5 +16,7 @@ RUN mkdir -p /usr/src/php/ext/redis \ && curl -L https://github.com/phpredis/phpredis/archive/5.3.4.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \ && echo 'redis' >> /usr/src/php-available-exts \ && docker-php-ext-install redis + +USER root CMD ["php-fpm", "-y", "/usr/local/etc/php-fpm.conf", "-R"]