0

I'm attempting to spin up a docker container for a laravel app:-

Edit

Dockerfile.nginx

FROM nginx:alpine

COPY ./nginx/my-site-config.conf /etc/nginx/conf.d/default.conf

nginx/my-site-config.conf

server {
 listen       8027;
 server_name  localhost;

 # handle .php
 location ~ \.php$ {
    # 404
    try_files                     $fastcgi_script_name =404;

    # default fastcgi_params
    include                       fastcgi_params;

    # fastcgi settings
    fastcgi_pass                  php-fpm-container:9000;
    fastcgi_index                 index.php;
    fastcgi_buffers               8 16k;
    fastcgi_buffer_size           32k;

    # fastcgi params
    fastcgi_param DOCUMENT_ROOT   $realpath_root;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
 }
}

docker-compose.yml

#Nginx Service <-- doesn't work
 #  webserver:
 #    build:
 #      context: .
 #      dockerfile: Dockerfile.nginx
 #    container_name: webserver
 #    restart: unless-stopped
 #    tty: true
 #    ports:
 #      - "8027:80"
 #      - "443:443"
 #    networks:
 #      - app-network

# works
webserver:
 image: nginx:alpine
 container_name: webserver
 restart: unless-stopped
 tty: true
 ports:
  - "8027:80"
  - "443:443"
 networks:
  - app-network

The commented-out code fails to launch with:-

enter image description here

Using the un-commented code and nginx:alpine as an image - the server hosts the nginx splash screen. There is a problem with my Dockerfile.nginx it appears.

11
  • You are using the php:7-fpm Docker image and that does not appear to have anything listening on port 80 to be forwarded to localhost:8638. It looks like php-fpm from that image runs on port 9000 by default. – GracefulRestart Jan 6 at 7:54
  • So what's the solution. Use a docker image which handles alternative port numbers? – cookie Jan 6 at 9:01
  • You have only stated that you wanted to run Laravel inside Docker. That will require at least php. If you are planning on serving the Laravel application to web browsers, you would also need a web server. If I were doing this, I would likely have one Docker image for php-fpm on port 9000 and another Docker image with a web server on port 80 and link them together. You could then forward port 80 on the web server to localhost:8638. – GracefulRestart Jan 6 at 17:49
  • Please see my edits. It's still not serving Laravel? – cookie Jan 6 at 18:47
  • You need to make sure that nginx will forward the request for .php to php-fpm, can you pull the nginx.conf and conf.d/ config content and add them to the question please? – Rabin Jan 6 at 20:57
2

Check you nginx:alpine config for nginx

docker run -it --rm nginx:alpine /bin/sh
/ # cd /etc/nginx
/etc/nginx # ls -l
total 44
drwxr-xr-x    2 root     root            24 Dec 17 15:01 conf.d
-rw-r--r--    1 root     root          1077 Dec 15 14:55 fastcgi.conf
-rw-r--r--    1 root     root          1007 Dec 15 14:55 fastcgi_params
-rw-r--r--    1 root     root          2837 Dec 15 14:55 koi-utf
-rw-r--r--    1 root     root          2223 Dec 15 14:55 koi-win
-rw-r--r--    1 root     root          5231 Dec 15 14:55 mime.types
lrwxrwxrwx    1 root     root            22 Dec 17 15:01 modules -> /usr/lib/nginx/modules
-rw-r--r--    1 root     root           646 Dec 15 14:55 nginx.conf
-rw-r--r--    1 root     root           636 Dec 15 14:55 scgi_params
-rw-r--r--    1 root     root           664 Dec 15 14:55 uwsgi_params
-rw-r--r--    1 root     root          3610 Dec 15 14:55 win-utf

This is the default nginx.conf

/etc/nginx # cat nginx.conf 

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

And inside conf.d folder, there is a default server config

/etc/nginx # ls -l conf.d/
total 4
-rw-r--r--    1 root     root          1093 Dec 15 14:55 default.conf

which have a very basic server section

/etc/nginx # grep -vE " *#|^ *$" conf.d/default.conf 
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

As you can see it's only configure to server static content and there is no section to forward request to *.php to the php-fpm backed.

Usually you will need to replace this file (or if you need more control, overwrite nginx.conf all together).

At the minimum you need a section in the server config to redirect request to PHP to the backend.

    # handle .php
    location ~ \.php$ {
# 404
try_files                     $fastcgi_script_name =404;

# default fastcgi_params
include                       fastcgi_params;

# fastcgi settings
fastcgi_pass                  php-fpm-container:9000; # <--- this is the PHP-FPM container
fastcgi_index                 index.php;
fastcgi_buffers               8 16k;
fastcgi_buffer_size           32k;

# fastcgi params
fastcgi_param DOCUMENT_ROOT   $realpath_root;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
    }

You can use the site NGINX Configuration Tool from DO to help you with creating a good starting point overall conf for your application, which you can then overwrite in the nginx:apline container.

Please note that both the nginx container and the the php container need to have access to your PHP application files.

EDIT1

Customize the nginx image

FROM nginx:alpine

# If you have a bundle of config created by DO config file, 
# you can copy them all to overwrite all the settings.
# or use
# to overwrite a single file
# COPY my-site-config.conf /etc/nginx/conf.d/default.conf

Update your docker-compose to use your customized version of the nginx image

version: '3'
services:

 #PHP Service
 app:
  build:
   context: .
   dockerfile: Dockerfile
  image: digitalocean.com/php
  container_name: app
  restart: unless-stopped
  tty: true
  environment:
    SERVICE_NAME: app
    SERVICE_TAGS: dev
  working_dir: /var/www
  networks:
   - app-network

 #Nginx Service
 webserver:
  build:
    context: .
    dockerfile: Dockerfile.nginx
  container_name: webserver
  restart: unless-stopped
  tty: true
  ports:
   - "8027:80"
   - "443:443"
  networks:
   - app-network

EDIT2

Seems you are missing some key parts of how Docker works and how to work with multi-container environment, for starter, I suggest you start with a working template like this one (read all the page to understand the meaning of the bind mount point) as you can see both the app (PHP container) and the webserver have access to the files via bind mounts, and this template also give you the option to overwrite the php configuration and the nginx without building a new container.

version: '3'
services:

  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: digitalocean.com/php
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

  #Nginx Service
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network

  #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge
#Volumes
volumes:
  dbdata:
    driver: local
5
  • How do I edit the default.conf within the running container? I'm attempting:- COPY nginx/default.conf /etc/nginx/conf.d/default.conf within my Dockerfile but cant see the updates when I'm inside container? Further, the splash page persists. I'm a total novice with docker. Thanks. – cookie Jan 11 at 9:30
  • Based on docker-compose file content you are adding/COPY the file to the wrong image (php-fpm), you need to add it to the nginx image (nginx:alpine), create another file called e.g Dockerfile.nginx and add your customization there. See my edit's in the answer – Rabin Jan 12 at 7:54
  • Are you able to advise on my latest edit above? The webserver fails to start completely now. – cookie Jan 21 at 9:23
  • you need to have 2 containers, one for the nginx and the 2nd for php-fpm process, and you need to have the same name in the config, so in the above example if we set the php-fpm container as "php-fpm-container" this is the name of the container. Also, you can use "Laravel sail" to run your laravel code in dev – Rabin Jan 23 at 16:52
  • See my EDIT2 section @cookie – Rabin Jan 24 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.