Skip to content

Commit

Permalink
Merge pull request #1001 from jonocodes/docker-refresh
Browse files Browse the repository at this point in the history
Docker refresh
  • Loading branch information
marclaporte authored May 25, 2024
2 parents d1c727e + 2869597 commit cc52d46
Show file tree
Hide file tree
Showing 16 changed files with 463 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/data/
.git
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/config/dynamic.php
/config/app.php
/site.js
/site.css
/site/
Expand All @@ -9,6 +8,8 @@
/tests/selenium/remote_creds.py
*.pyc
/.env
/.env.*
!.env.example
apigen4.sh
testuser.txt
website/docs
Expand All @@ -25,3 +26,4 @@ scripts/test.php
composer.phar
lib/hm3/users/
.env
/data/
35 changes: 35 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.PHONY: docker-up
docker-up: ## start docker stack in foreground for development
docker compose -f docker-compose.dev.yaml up --build || true # --abort-on-container-exit

.PHONY: docker-push
.ONESHELL:
docker-push: ## build, tag, and push image to dockerhub. presumes you are logged in. run with a version like tag:1.2.3
@username=$$(docker info | sed '/Username:/!d;s/.* //')
@[ "$(tag)" = "" ] && (echo "Tag required. Example tag=1.2.3" ; exit 1)
@image=$${username}/cypht:$(tag)
@echo "Building image $${image}"
@docker buildx build . --platform linux/amd64 \
-t $${image} -f docker/Dockerfile --push
# TODO: build for arm architectures

.PHONY: dockerhub-push-readme
.ONESHELL:
dockerhub-push-readme: ## upload readme to dockerhub
@username=$$(docker info | sed '/Username:/!d;s/.* //')
@docker pushrm --file docker/DOCKERHUB-README.md $${username}/cypht
@echo docker pushrm --file docker/DOCKERHUB-README.md $${username}/cypht

.PHONY: setup
.ONESHELL:
setup: ## locally setup app and users. presumes env vars are set
set -e
echo "Installing dependencies"
composer install
echo "Creating tables and user"
./scripts/setup_database.php
echo "Creating directories and configs"
./scripts/setup_system.sh

help: ## get help
@grep -E '^[a-zA-Z_-]+:.*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
1 change: 0 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

# this file should be used for development, not production

services:
db:
image: mariadb:10
ports:
- "3306:3306"
volumes:
- ./data/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=cypht
- MYSQL_USER=cypht
- MYSQL_PASSWORD=cypht_password
cypht:
build:
context: .
dockerfile: ./docker/Dockerfile
args:
WITH_DEBUG: true
volumes:
- ./data/users:/var/lib/hm3/users
- ./data/attachments:/var/lib/hm3/attachments
- ./data/app_data:/var/lib/hm3/app_data
- ./data/sqlite:/var/lib/hm3/sqlite
# The following allow for some live code updates during development
- ./lib:/usr/local/share/cypht/lib
- ./modules:/usr/local/share/cypht/modules
ports:
- "80:80"
environment:
- AUTH_USERNAME=admin
- AUTH_PASSWORD=admin
- DB_CONNECTION_TYPE=host
- DB_DRIVER=mysql
- DB_HOST=db
- DB_NAME=cypht
- DB_USER=cypht
- DB_PASS=cypht_password
- SESSION_TYPE=DB
- USER_CONFIG_TYPE=DB
extra_hosts:
host.docker.internal: host-gateway # for xdebug
48 changes: 48 additions & 0 deletions docker/DOCKERHUB-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Cypht

This is the official docker image of [Cypht](https://cypht.org/).

## Features of this image

* Alpine linux based image
* Bundled nginx and PHP 7 provides everything in one image
* Performs same install steps as found on [Cypht install page](https://cypht.org/install.html)
* All Cypht mods and configuration options can be set via environment variables
* Automatic database setup (if configured to use database)

It recommended that you choose a specific version number tag instead of using 'latest' since 'latest' may represent master which may not be stable.

## Example docker-compose

See example file here:
https://github.com/jonocodes/cypht/blob/docker-refresh/docker/docker-compose.yaml

* Starts a database container to be for user authentication
* Starts the Cypht container available on port 80 of the host with ...
* A local volume declared for persisting user settings across container reboots
* An initial user account for authentication
* Environment variables for accessing the database container

*NOTE: Please change usernames and passwords before using this docker-compose in your environment*

## Environment variables

See all the environment variables you can set here:
https://github.com/cypht-org/cypht/blob/master/.env.example

To see the meaning of what each variable see descriptions here:
https://github.com/cypht-org/cypht/blob/master/config/app.php


It is recommended that in production you instead make a copy of this file:
```
cp .env.example /etc/cypht-prod.env
```

Make changes to it and source it in to the docker-compose via 'env_file':
```yaml
env_file:
- /etc/cypht-prod.env
```
In order to avoid confusion, it is best to use only the env file and not set addition env vars in the docker compose file if possilbe.
62 changes: 62 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
FROM php:7.4.33-fpm-alpine

WORKDIR "/usr/local/share/cypht"

RUN set -e \
&& apk add --no-cache \
supervisor nginx composer sqlite freetype libpng libjpeg-turbo \
php-session php-fileinfo php-dom php-xml libxml2-dev php-xmlwriter php-tokenizer \
&& apk add --no-cache --virtual .build-deps \
ca-certificates \
libpng-dev libjpeg-turbo-dev freetype-dev \
&& docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
&& docker-php-ext-install gd pdo pdo_mysql \
&& curl -sSL https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - | sh -s \
xdebug redis gnupg memcached \
&& composer self-update --2 \
&& apk del .build-deps \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini

COPY <<EOF /tmp/xdebug.ini
[xdebug]
zend_extension=xdebug.so

xdebug.mode=debug
xdebug.client_host=host.docker.internal
EOF

COPY <<EOF /usr/local/etc/php/conf.d/cypht.ini
post_max_size = 60M
upload_max_filesize = 50M
# the following is needed for sqlite access
open_basedir = /var/lib/hm3/:/usr/local/share/cypht/:/tmp
EOF

COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/supervisord.conf /etc/supervisord.conf
COPY composer.* .

ARG WITH_DEBUG=false

RUN [ "$WITH_DEBUG" = "true" ] && mv /tmp/xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini || true

RUN composer install

COPY config/ config/
COPY language/ language/
COPY lib/ lib/
COPY modules/ modules/
COPY scripts/ scripts/
COPY third_party/ third_party/
COPY index.php index.php

COPY docker/docker-entrypoint.sh docker/docker-entrypoint.sh
COPY .env.example .env

EXPOSE 80

HEALTHCHECK CMD curl --fail http://localhost || exit 1

ENTRYPOINT ["docker/docker-entrypoint.sh"]
32 changes: 32 additions & 0 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

# this is a demo of using the production cypht image

services:
db:
image: mariadb:10
ports:
- "3306:3306"
volumes:
- ./data/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=cypht
- MYSQL_USER=cypht
- MYSQL_PASSWORD=cypht_password
cypht:
image: jonocodes/cypht:2.0.1-docker-wip
ports:
- "80:80"
# env_file:
# - /etc/cypht-prod.env
environment:
- AUTH_USERNAME=admin
- AUTH_PASSWORD=admin
- DB_CONNECTION_TYPE=host
- DB_DRIVER=mysql
- DB_HOST=db
- DB_NAME=cypht
- DB_USER=cypht
- DB_PASS=cypht_password
- SESSION_TYPE=DB
- USER_CONFIG_TYPE=DB
37 changes: 37 additions & 0 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env sh

set -e

APP_DIR=/usr/local/share/cypht
cd ${APP_DIR}

# TODO: validate env var values here, perhaps in php or in Hm_Site_Config_File()

# TODO: source these defaults from an .env file or some other place?
USER_CONFIG_TYPE="${USER_CONFIG_TYPE:-file}"
USER_SETTINGS_DIR="${USER_SETTINGS_DIR:-/var/lib/hm3/users}"
ATTACHMENT_DIR="${ATTACHMENT_DIR:-/var/lib/hm3/attachments}"
APP_DATA_DIR="${APP_DATA_DIR:-/var/lib/hm3/app_data}"

# Wait for database to be ready then setup tables
./scripts/setup_database.php

# Setup filesystem and users
./scripts/setup_system.sh

# Enable the program in the web-server

if [ "${USER_CONFIG_TYPE}" = "file" ]
then
chown www-data:www-data ${USER_SETTINGS_DIR}
fi

chown www-data:www-data ${ATTACHMENT_DIR}
chown -R www-data:www-data /var/lib/nginx
chown www-data:www-data ${APP_DATA_DIR}

rm -r /var/www
ln -s $(pwd)/site /var/www

# Start services
/usr/bin/supervisord -c /etc/supervisord.conf
40 changes: 40 additions & 0 deletions docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile off;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
server {
listen 80;
server_name localhost;
index index.php;
root /var/www;
client_max_body_size 60M;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
}
22 changes: 22 additions & 0 deletions docker/supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[supervisord]
nodaemon=true
logfile=/var/log/supervisord.log
pidfile=/var/run/supervisord.pid

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:php-fpm]
command=php-fpm
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
1 change: 1 addition & 0 deletions lib/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public function create($user, $pass) {
$result = 0;
$res = Hm_DB::execute($this->dbh, 'select username from hm_user where username = ?', [$user]);
if (!empty($res)) {
print("user {$user} already exists\n");
$result = 1;
}
else {
Expand Down
2 changes: 2 additions & 0 deletions lib/framework.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
require APP_PATH.'lib/api.php';
require APP_PATH.'lib/webdav_formats.php';

require_once APP_PATH.'modules/core/functions.php';

/* load random bytes polyfill if needed */
if (!function_exists('random_bytes')) {
require VENDOR_PATH.'paragonie/random_compat/lib/random.php';
Expand Down
13 changes: 4 additions & 9 deletions scripts/create_account.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,12 @@

/* check config for db auth */
if ($config->get('auth_type') != 'DB') {
die("Incorrect usage\n\nThis script only works if DB auth is enabled in your site configuration\n\n");
print("Incorrect usage\n\nThis script only works if DB auth is enabled in your site configuration\n\n");
exit(1);
}

$auth = new Hm_Auth_DB($config);

if ($user && $pass) {
if ($auth->create($user, $pass) === 2) {
die("User '" . $user . "' created\n\n");
}
else {
print_r(Hm_Debug::get());
print_r(Hm_Msgs::get());
die("An error occured when creating user '" . $user . "'\n\n");
}
$auth->create($user, $pass);
}
Loading

0 comments on commit cc52d46

Please sign in to comment.