Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

oliverbusk's avatar

Deploying Laravel application to production - files/app not deployed

I have a standard Laravel application which I have developed locally using Laravel Herd, that I am trying to deploy to my production environment. I am using Portainer, and I only have access to the Portainer ui.

I have the following files in my app's root folder:

Dockerfile:

# Use the official PHP image with FPM
FROM php:8.3-fpm

# Set working directory
WORKDIR /var/www/html

# Install dependencies
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    locales \
    zip \
    unzip \
    git \
    curl \
    libpq-dev

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install pdo pdo_pgsql gd

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Copy existing application directory contents
COPY . /var/www/html

# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www/html

# Change the owner of the application directory to www-data
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache

EXPOSE 8010

docker-compose.yml:

version: '3.8'
services:
  laravel.test:
    build:
      context: .
      dockerfile: Dockerfile
    image: athena
    container_name: athena-app
    restart: unless-stopped
    pull_policy: always
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html
    networks:
      - athena-network
    depends_on:
      - pgsql
  nginx:
    image: nginx:alpine
    container_name: athena-nginx
    restart: unless-stopped
    ports:
      - ${APP_PORT:-80}:80
    volumes:
      - ./:/var/www/html
      - ./docker/nginx:/etc/nginx/conf.d
    networks:
      - athena-network

  pgsql:
    image: 'postgres:15'
    ports:
      - '${FORWARD_DB_PORT:-5432}:5432'
    environment:
      PGPASSWORD: '${DB_PASSWORD:-secret}'
      POSTGRES_DB: '${DB_DATABASE}'
      POSTGRES_USER: '${DB_USERNAME}'
      POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
    volumes:
      - 'sail-pgsql:/var/lib/postgresql/data'
      - './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
    networks:
      - athena-network
    healthcheck:
      test:
        - CMD
        - pg_isready
        - '-q'
        - '-d'
        - '${DB_DATABASE}'
        - '-U'
        - '${DB_USERNAME}'
      retries: 3
      timeout: 5s
networks:
  athena-network:
    driver: bridge
volumes:
  sail-pgsql:
    driver: local

In Portainer, I simply create a stack which pulls from my GitHub repo's docker-compose.yml file.

The stack deploys succesfully, but when I try to access the webserver on port 8010, I am not able to connect (error: "ERR_CONNECTION_REFUSED").

When I go to the app container's console in Portainer and check the file content, I don't see any of my Laravel app files?

/var/www/html# ls
docker  vendor
0 likes
2 replies
LaryAI's avatar
Level 58

It looks like there are a few potential issues with your setup that could be causing the problem. Let's go through them step-by-step:

  1. Volume Mounting Issue: The volume mounting in your docker-compose.yml might be causing the issue where your application files are not being copied correctly into the container. When you use volumes: - ./:/var/www/html, it overrides the files copied during the build process with the files from your host machine. If the host directory is empty or doesn't contain the application files, the container will also be empty.

  2. Port Configuration: You mentioned trying to access the webserver on port 8010, but your nginx service is configured to expose port 80. This might be causing the connection issue.

  3. Nginx Configuration: Ensure that your Nginx configuration is correctly set up to serve your Laravel application.

Let's address these issues:

Step 1: Fix Volume Mounting

First, ensure that your application files are correctly copied during the build process. You can remove the volume mount for the application directory in the laravel.test service to avoid overriding the files copied during the build.

Step 2: Correct Port Configuration

Ensure that the port configuration matches your expectations. If you want to access the application on port 8010, you need to map the Nginx service to that port.

Step 3: Verify Nginx Configuration

Ensure that your Nginx configuration is correctly set up to serve your Laravel application. You should have a configuration file in ./docker/nginx that points to the correct root directory.

Here is the updated docker-compose.yml:

version: '3.8'
services:
  laravel.test:
    build:
      context: .
      dockerfile: Dockerfile
    image: athena
    container_name: athena-app
    restart: unless-stopped
    pull_policy: always
    working_dir: /var/www/html
    networks:
      - athena-network
    depends_on:
      - pgsql
  nginx:
    image: nginx:alpine
    container_name: athena-nginx
    restart: unless-stopped
    ports:
      - "8010:80"  # Map port 8010 on the host to port 80 in the container
    volumes:
      - ./:/var/www/html
      - ./docker/nginx:/etc/nginx/conf.d
    networks:
      - athena-network

  pgsql:
    image: 'postgres:15'
    ports:
      - '${FORWARD_DB_PORT:-5432}:5432'
    environment:
      PGPASSWORD: '${DB_PASSWORD:-secret}'
      POSTGRES_DB: '${DB_DATABASE}'
      POSTGRES_USER: '${DB_USERNAME}'
      POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
    volumes:
      - 'sail-pgsql:/var/lib/postgresql/data'
      - './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
    networks:
      - athena-network
    healthcheck:
      test:
        - CMD
        - pg_isready
        - '-q'
        - '-d'
        - '${DB_DATABASE}'
        - '-U'
        - '${DB_USERNAME}'
      retries: 3
      timeout: 5s
networks:
  athena-network:
    driver: bridge
volumes:
  sail-pgsql:
    driver: local

Step 4: Nginx Configuration

Ensure your Nginx configuration file (e.g., ./docker/nginx/default.conf) is correctly set up to serve your Laravel application. Here is an example configuration:

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/html/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass laravel.test:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

Step 5: Redeploy the Stack

After making these changes, redeploy your stack in Portainer. This should ensure that your application files are correctly copied, the ports are correctly mapped, and Nginx is correctly configured to serve your Laravel application.

If you still encounter issues, check the logs of your containers for any errors and ensure that all services are running correctly.

vincent15000's avatar

At the moment, I'm working on an Laravel dockerized application.

In developpement I'm using sail, but I recommand you to not use sail in production.

Please or to participate in this conversation.