Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker Image for Grav based on NGINX #34

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions grav-nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
FROM nginx:latest
LABEL maintainer="gushmazuko <gushmazuko@protonmail.com>"
LABEL description="Docker Image for Grav based on NGINX"

# Install dependencies
RUN apt update && apt install -y --no-install-recommends \
vim\
zip \
unzip \
git \
php-fpm \
php-cli \
php-gd \
php-curl \
php-mbstring \
php-xml \
php-zip \
php-apcu \
cron

# Configure PHP FPM
# https://learn.getgrav.org/17/webservers-hosting/vps/digitalocean#configure-php7-2-fpm
RUN sed -i "s/.*cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g" /etc/php/7.*/fpm/php.ini

# Set user to www-data
RUN chown www-data:www-data /usr/share/nginx
RUN rm -rf /usr/share/nginx/html
USER www-data

# Define a specific version of Grav or use latest stable
ENV GRAV_VERSION latest

# Install grav
WORKDIR /usr/share/nginx
RUN curl -o grav-admin.zip -SL https://getgrav.org/download/core/grav-admin/${GRAV_VERSION} && \
unzip grav-admin.zip && \
mv -T /usr/share/nginx/grav-admin /usr/share/nginx/html && \
rm grav-admin.zip

# Create cron job for Grav maintenance scripts
# https://learn.getgrav.org/17/advanced/scheduler
RUN (crontab -l; echo "* * * * * cd /usr/share/nginx/html;/usr/bin/php bin/grav scheduler 1>> /dev/null 2>&1") | crontab -

# Return to root user
USER root

# Add nginx to www-data group
RUN usermod -aG www-data nginx

# Replace dafault config files by provided by Grav
# https://learn.getgrav.org/17/webservers-hosting/vps/digitalocean#configure-nginx-connection-pool
RUN rm /etc/php/7.3/fpm/pool.d/www.conf
RUN rm /etc/nginx/conf.d/default.conf
COPY conf/php/grav.conf /etc/php/7.3/fpm/pool.d/
COPY conf/nginx/grav.conf /etc/nginx/conf.d/

# Provide container inside image for data persistence
VOLUME ["/usr/share/nginx/html"]

# Run startup script
CMD bash -c "service php7.3-fpm start && nginx -g 'daemon off;'"
161 changes: 161 additions & 0 deletions grav-nginx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Docker Grav based on NGINX
![https://hub.docker.com/r/gushmazuko/docker-grav-nginx](https://img.shields.io/docker/cloud/build/gushmazuko/grav-nginx.svg) ![https://hub.docker.com/r/gushmazuko/docker-grav-nginx](https://img.shields.io/docker/cloud/automated/gushmazuko/grav-nginx.svg)

## Persisting data
To save the Grav site data to the host file system (so that it persists even after the container has been removed), simply map the container's `/usr/share/nginx/html` directory to a named Docker volume or to a directory on the host.

> If the mapped directory or named volume is empty, it will be automatically populated with a fresh install of Grav the first time that the container starts. However, once the directory/volume has been populated, the data will persist and will not be overwritten the next time the container starts.

## Building the image from Dockerfile
```
docker build -t gushmazuko/grav-nginx:latest .
```

## Running Grav Image with Latest Grav + Admin with a named volume (can be used in production)
```
docker run -d -p 8000:80 --restart always -v grav_data:/usr/share/nginx/html gushmazuko/grav-nginx:latest
```
Point browser to `http://localhost:8000` and create user account...

## Running Grav Image with docker-compose and a volume mapped to a local directory
Run `docker-compose up -d` with the following docker-compose configuration. Then the Grav container will be started with all of the site data persisted to a named volume (stored in the `./grav_data` directory).

```
version: "3.8"
services:
grav:
image: gushmazuko/grav-nginx:latest
container_name: ${SERVICE}_grav
restart: unless-stopped
environment:
TZ: ${TZ}
ports:
- 80:80
- 443:443
volumes:
- grav:/usr/share/nginx/html
# - ./conf/nginx/:/etc/nginx/conf.d/
# - ./conf/php/:/etc/php/7.3/fpm/pool.d/
networks:
- web
networks:
web:
external: true
volumes:
grav:
driver: local
driver_opts:
type: none
device: $PWD/grav_data
o: bind
```

* Edit `.env` environment file
```
SERVICE=mysite
DOMAIN_NAME=example.com
SERVICE_PORT=80
TZ=Europe/Berlin
```

## Editing `NGINX` & `FPM` configuration (Optional)

* Uncomment theses lines in `docker-compose.yml`
```
# - ./conf/nginx/:/etc/nginx/conf.d/
# - ./conf/php/:/etc/php/7.3/fpm/pool.d/
```

* Then modify `NGINX` site config `./conf/nginx/grav.conf`

```
server {
listen 80;
index index.html index.php;

## Begin - Server Info
root /usr/share/nginx/html;
server_name gravsite;
## End - Server Info

## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
try_files $uri $uri/ /index.php?$query_string;
}
## End - Index

## Begin - Security
# deny all direct access for these folders
location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
# deny running scripts inside core system folders
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny running scripts inside user folder
location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny access to specific files in the root folder
location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
## End - Security

## Begin - PHP
location ~ \.php$ {
# Choose either a socket or TCP/IP address
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
# fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy
# fastcgi_pass 127.0.0.1:9000;

fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
## End - PHP
}
```
* And `FPM` config `./conf/php/grav.conf`

```
[grav]

user = www-data
group = www-data

listen = /var/run/php/php7.3-fpm.sock

listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

chdir = /
````

## Using `Traefik` instead `port mapping` (Optional)
* Comment theses lines in `docker-compose.yml`

```
ports:
- 80:80
- 443:443
```

* And add `Traefik` labels into `docker-compose.yml` [More Info About](https://github.com/gushmazuko/dockers_template/tree/master/traefik)
```
labels:
- "traefik.enable=true"
# http
- "traefik.http.routers.${SERVICE}.rule=Host(`${DOMAIN_NAME}`)"
- "traefik.http.services.${SERVICE}.loadbalancer.server.port=${SERVICE_PORT}"
- "traefik.http.routers.${SERVICE}_redirect.rule=Host(`${DOMAIN_NAME}`)"
- "traefik.http.routers.${SERVICE}_redirect.entrypoints=web"
# redirect to https
- "traefik.http.routers.${SERVICE}.tls.certresolver=le"
- "traefik.http.routers.${SERVICE}.entrypoints=web-secure"
- "traefik.http.middlewares.${SERVICE}_https.redirectscheme.scheme=https"
- "traefik.http.routers.${SERVICE}_redirect.middlewares=${SERVICE}_https"
```
43 changes: 43 additions & 0 deletions grav-nginx/conf/nginx/grav.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
server {
listen 80;
index index.html index.php;

## Begin - Server Info
root /usr/share/nginx/html;
server_name gravsite;
## End - Server Info

## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
try_files $uri $uri/ /index.php?$query_string;
}
## End - Index

## Begin - Security
# deny all direct access for these folders
location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
# deny running scripts inside core system folders
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny running scripts inside user folder
location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny access to specific files in the root folder
location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
## End - Security

## Begin - PHP
location ~ \.php$ {
# Choose either a socket or TCP/IP address
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
# fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy
# fastcgi_pass 127.0.0.1:9000;

fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
## End - PHP
}
17 changes: 17 additions & 0 deletions grav-nginx/conf/php/grav.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[grav]

user = www-data
group = www-data

listen = /var/run/php/php7.3-fpm.sock

listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

chdir = /
39 changes: 39 additions & 0 deletions grav-nginx/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: "3.8"
services:
grav:
image: gushmazuko/grav-nginx:latest
container_name: ${SERVICE}_grav
restart: unless-stopped
environment:
TZ: ${TZ}
volumes:
- grav:/usr/share/nginx/html
# - ./conf/nginx/:/etc/nginx/conf.d/
# - ./conf/php/:/etc/php/7.3/fpm/pool.d/
labels:
- "traefik.enable=true"
# http
- "traefik.http.routers.${SERVICE}.rule=Host(`${DOMAIN_NAME}`)"
- "traefik.http.services.${SERVICE}.loadbalancer.server.port=${SERVICE_PORT}"
- "traefik.http.routers.${SERVICE}_redirect.rule=Host(`${DOMAIN_NAME}`)"
- "traefik.http.routers.${SERVICE}_redirect.entrypoints=web"
# redirect to https
- "traefik.http.routers.${SERVICE}.tls.certresolver=le"
- "traefik.http.routers.${SERVICE}.entrypoints=web-secure"
- "traefik.http.middlewares.${SERVICE}_https.redirectscheme.scheme=https"
- "traefik.http.routers.${SERVICE}_redirect.middlewares=${SERVICE}_https"
# auth with authelia
# - "traefik.http.routers.${SERVICE}.middlewares=authelia@file"
networks:
- web
networks:
web:
external: true

volumes:
grav:
driver: local
driver_opts:
type: none
device: $PWD/grav_data
o: bind
Empty file added grav-nginx/grav_data/.gitkeep
Empty file.