30 Commits
Author SHA1 Message Date
Hide_D 1ba6a551f2 memcached 제거 2024-05-17 17:23:54 +00:00
Hide_D dbee326c4d pecl 옵션 변경
- 왜 memcached가 안되나
2024-05-17 17:21:35 +00:00
Hide_D 2d507e501e php version up 2024-05-17 17:17:29 +00:00
Hide_D e6816b15ef php 버전업 2024-05-17 17:14:36 +00:00
Hide_D f358126cff php version upgrade 2024-05-17 16:53:06 +00:00
Hide_D 3d72603c26 build script 누락 2024-05-17 16:13:43 +00:00
Hide_D 526eb1bc2a docker db update for mariadb11 2023-06-19 16:58:50 +00:00
Hide_D ccf2a4a657 update backup entrypoint 2023-02-25 19:36:09 +09:00
Hide_D 40f15e7676 fix: api 로그인 호출 경로 수정 2023-02-20 01:43:56 +09:00
Hide_D 980cc41dfd misc: install 과정에서 에러시 출력 2023-02-20 01:26:40 +09:00
Hide_D 9fdf596463 fix: php zip, 7-zip 2023-02-20 00:23:02 +09:00
Hide_D d43b5e08e6 fix: example backup entrypoint 2023-02-20 00:22:48 +09:00
Hide_D 4980670450 fix: example. bbs->board 2023-02-20 00:15:11 +09:00
Hide_D 58b15e19b9 dep: php 8.2 2023-02-20 00:11:45 +09:00
Hide_D b73fc43e34 fix: pm.max_children 2022-08-17 01:53:38 +09:00
Hide_D b597377818 misc: max_children 증가 2022-08-17 01:27:37 +09:00
Hide_D 6ebe151858 docker compose에 백업 스크립트 구성 2022-07-25 00:14:46 +09:00
Hide_D afa45119e5 backup 스크립트 구성 2022-07-25 00:04:13 +09:00
Hide_D b6875f45ea DB 초기화 관련 설정 변경
- MariaDB 초기화시 Root host 지정
- 세부 DB 계정마다 생성된 비밀번호 안내
2022-06-03 22:26:21 +09:00
Hide_D 532c006fb4 override를 위해 기본 포트 제거 2022-06-03 21:48:19 +09:00
Hide_D 623ed878dc sysvmsg, sysvsem, sysvshm 추가 2022-05-15 03:14:36 +09:00
Hide_D 6f366e9592 php gd에 webp, jpg 누락 수정 2022-05-08 19:19:39 +09:00
Hide_D d3698fa2e4 memcached 설정, mcrypt 제거, ds 추가 2022-05-08 19:11:49 +09:00
Hide_D 1b26fcadbf doc: README.md 내용 수정
- gogs -> gitea
- 문법 경고 수정
2022-03-18 02:08:21 +09:00
Hide_D 4565620e30 fix: 과도하게 access 권한을 막는 문제 수정
- 사용자가 sam이 아닌 디렉토리를 쓸 경우에는...?
2022-03-15 23:06:07 +09:00
Hide_D c8fb5e120e fix: vendors.js가 필터에 걸리는 문제 수정 2022-03-14 01:33:37 +09:00
Hide_D 4ea00e6deb feat: .htaccess 내용 이식 2022-03-14 01:31:56 +09:00
Hide_D 22f37cbdec feat: for v0.29 2022-03-13 21:38:52 +09:00
Hide_D 3cad468335 app: php 버전 업그레이드 2022-03-13 11:57:38 +09:00
Hide_D db5b344168 for 0.26 2021-12-05 02:27:52 +09:00
17 changed files with 847 additions and 247 deletions
+21 -20
View File
@@ -8,9 +8,9 @@ Docker-compose를 지원하는 모든 환경 (Windows 10 Pro 포함)
Docker가 설치되지 않았다면 다음을 통해 설치합니다. Docker가 설치되지 않았다면 다음을 통해 설치합니다.
* POSIX - https://docs.docker.com/install/ 을 통해 Docker를, https://docs.docker.com/compose/install/ 를 통해 Docker-compose를 설치합니다. * POSIX - <https://docs.docker.com/install/> 을 통해 Docker를, <https://docs.docker.com/compose/install/> 를 통해 Docker-compose를 설치합니다.
* Windows 10 - https://docs.docker.com/docker-for-windows/install/ 를 통해 Docker Desktop on Windows 를 설치합니다. 회원 가입을 원하지 않는다면, https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe 를 통해 설치합니다. * Windows 10 - <https://docs.docker.com/docker-for-windows/install/> 를 통해 Docker Desktop on Windows 를 설치합니다. 회원 가입을 원하지 않는다면, <https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe> 를 통해 설치합니다.
> ⚠️**주의**: Docker Desktop on Windows는 Virtual Box, VMWare와 잘 호환되지 않는 것으로 알려져 있습니다. > ⚠️**주의**: Docker Desktop on Windows는 Virtual Box, VMWare와 잘 호환되지 않는 것으로 알려져 있습니다.
만약 Virtual Box나 Virtual Box를 이용하는 안드로이드 가상 머신을 이용할 경우 Docker Toolbox를 설치하십시오. 만약 Virtual Box나 Virtual Box를 이용하는 안드로이드 가상 머신을 이용할 경우 Docker Toolbox를 설치하십시오.
@@ -21,21 +21,22 @@ Docker가 설치되지 않았다면 다음을 통해 설치합니다.
docker, docker-compose를 사용 가능한 상황임을 가정합니다. docker, docker-compose를 사용 가능한 상황임을 가정합니다.
https://storage.hided.net/gogs/devsam/docker/archive/master.zip 링크를 통해 zip 파일을 다운받아 압축을 풉니다. <https://storage.hided.net/gitea/devsam/docker/archive/master.zip> 링크를 통해 zip 파일을 다운받아 압축을 풉니다.
### 기본 설정 ### 기본 설정
기본적으로 수정이 필요한 항목은 다음과 같습니다. 기본적으로 수정이 필요한 항목은 다음과 같습니다.
- `hidche/account.env` : 계정정보 설정, 공란으로 남겨진 공간을 적절하게 채웁니다. * `hidche/account.env` : 계정정보 설정, 공란으로 남겨진 공간을 적절하게 채웁니다.
- Password에 해당하는 항목들은 가급적 어렵게 지어주십시오. * Password에 해당하는 항목들은 가급적 어렵게 지어주십시오.
- 특히 `HIDCHE_PW_SALT`는 자동 설치 시 1회만 사용되므로 최대한 길고 어렵게 지어주십시오. * 특히 `HIDCHE_PW_SALT`는 자동 설치 시 1회만 사용되므로 최대한 길고 어렵게 지어주십시오.
- `HIDCHE_KAKAO_REST_KEY`, `HIDCHE_KAKAO_ADMIN_KEY`는 [KakaoTalk REST API](https://developers.kakao.com/docs/restapi/kakaotalk-api)를 통해 발급 받을 수 있습니다. 동의 항목으로는 카카오계정(이메일), 카카오톡 메시지 전송이 필요합니다. * `HIDCHE_KAKAO_REST_KEY`, `HIDCHE_KAKAO_ADMIN_KEY`는 [KakaoTalk REST API](https://developers.kakao.com/docs/restapi/kakaotalk-api)를 통해 발급 받을 수 있습니다. 동의 항목으로는 카카오계정(이메일), 카카오톡 메시지 전송이 필요합니다.
- `HIDCHE_IMAGE_REQUEST_KEY`는 이미지 서비스용 git과 게임 git repository를 연동하기위한 키입니다. 특히 이미지 서비스가 다른 서버에서 실행될 때 유용합니다. 이 값이 지정되지 않은 경우 `image/hook/git_pull.php`을 PHP CLI를 통해 직접 실행해야만 합니다. * `HIDCHE_IMAGE_REQUEST_KEY`는 이미지 서비스용 git과 게임 git repository를 연동하기위한 키입니다. 특히 이미지 서비스가 다른 서버에서 실행될 때 유용합니다. 이 값이 지정되지 않은 경우 `image/hook/git_pull.php`을 PHP CLI를 통해 직접 실행해야만 합니다.
- `hidche/game.env` : 게임 설치 정보 설정 공간입니다. 값 하나를 변경해야 합니다.
- `HIDCHE_GAME_PATH` : 외부 유저가 접속할 수 있는 경로입니다. 공인 IP 주소나 도메인 주소를 사용한 주소로 꼭 변경해야합니다. 변경하지 않을 경우 설치는 되지만, 외부 유저가 이용할 수 없습니다. 명확한 이유가 있는게 아니라면 `/sam` 까지 붙여주십시오. * `hidche/game.env` : 게임 설치 정보 설정 공간입니다. 값 하나를 변경해야 합니다.
- 이 주소를 이용하여 카카오 API의 로그인 Redirect URI를 설정해야 합니다. 주소가 https://sam.hided.net/sam 인 경우 https://sam.hided.net/sam/oauth_kakao/oauth.php 으로 입력합니다. * `HIDCHE_GAME_PATH` : 외부 유저가 접속할 수 있는 경로입니다. 공인 IP 주소나 도메인 주소를 사용한 주소로 꼭 변경해야합니다. 변경하지 않을 경우 설치는 되지만, 외부 유저가 이용할 수 없습니다. 명확한 이유가 있는게 아니라면 `/sam` 까지 붙여주십시오.
- 포트 주소는 8080으로 지정되어있으며, 다른 포트로 바꾸고자 한다면 `hidche/docker-compose.yml`와 동일하게 유지해야 합니다. * 이 주소를 이용하여 카카오 API의 로그인 Redirect URI를 설정해야 합니다. 주소가 <https://sam.hided.net/sam> 인 경우 <https://sam.hided.net/sam/oauth_kakao/oauth.php> 으로 입력합니다.
* 포트 주소는 8080으로 지정되어있으며, 다른 포트로 바꾸고자 한다면 `hidche/docker-compose.yml`와 동일하게 유지해야 합니다.
>Windows 환경에서 적절한 텍스트 에디터를 찾지 못하였다면 메모장에 해당 파일들을 드래그하여 수정하거나, [Notepad++](https://notepad-plus-plus.org/downloads/ )를 설치하여 수정하는 방법도 가능합니다. >Windows 환경에서 적절한 텍스트 에디터를 찾지 못하였다면 메모장에 해당 파일들을 드래그하여 수정하거나, [Notepad++](https://notepad-plus-plus.org/downloads/ )를 설치하여 수정하는 방법도 가능합니다.
@@ -43,19 +44,19 @@ https://storage.hided.net/gogs/devsam/docker/archive/master.zip 링크를 통해
고급 설정이 필요하다면 다음을 수정합니다. 고급 설정이 필요하다면 다음을 수정합니다.
- `hidche/docker-compose.yml` : 설치 옵션입니다. * `hidche/docker-compose.yml` : 설치 옵션입니다.
- `web/ports`: 8080 포트 대신 다른 포트를 선택하고자 할 경우 수정합니다. `hidche/game.env`의 내용도 변경해야합니다. * `web/ports`: 8080 포트 대신 다른 포트를 선택하고자 할 경우 수정합니다. `hidche/game.env`의 내용도 변경해야합니다.
- `build/args` : nginx/www-data의 UID와 GID를 변경할 수 있습니다. `web`, `app`, `board` 셋을 동시에 지정해야합니다. * `build/args` : nginx/www-data의 UID와 GID를 변경할 수 있습니다. `web`, `app`, `board` 셋을 동시에 지정해야합니다.
- `hidche/game.env` * `hidche/game.env`
- `gameGitPath`, `imgGitPath`: 개발을 위해 다른 git repository를 사용해야한다면 수정합니다. ssh 주소인 경우 `hidche/app/id_ecdsa``hidche/app/known_hosts` 또한 수정해야 합니다. * `gameGitPath`, `imgGitPath`: 개발을 위해 다른 git repository를 사용해야한다면 수정합니다. ssh 주소인 경우 `hidche/app/id_ecdsa``hidche/app/known_hosts` 또한 수정해야 합니다.
- `HIDCHE_IMAGE_USE_INTERNAL`, `HIDCHE_IMAGE_PATH`는 CDN 등 외부 이미지 경로를 사용할 경우 수정합니다. * `HIDCHE_IMAGE_USE_INTERNAL`, `HIDCHE_IMAGE_PATH`는 CDN 등 외부 이미지 경로를 사용할 경우 수정합니다.
- 기타 적절한 용도에 맞게 수정하여 사용합니다. * 기타 적절한 용도에 맞게 수정하여 사용합니다.
### Docker-compose 실행 ### Docker-compose 실행
파일 설정이 모두 끝났다면, 콘솔에서 hidche 폴더로 이동하여 다음을 실행합니다. 파일 설정이 모두 끝났다면, 콘솔에서 hidche 폴더로 이동하여 다음을 실행합니다.
``` ```bash
docker-compose up -d docker-compose up -d
``` ```
+7 -7
View File
@@ -1,14 +1,14 @@
#MYSQL 비밀번호. (필수) #MARIADB 비밀번호. (필수)
MYSQL_ROOT_PASSWORD= MARIADB_ROOT_PASSWORD=
MYSQL_USER=hidche #MARIADB ROOT 접근 주소(선택, 외부 접근 시 % 입력)
MYSQL_PASSWORD= MARIADB_ROOT_HOST=
HIDCHE_PW_SALT= HIDCHE_PW_SALT=
HIDCHE_DB_PREFIX=hidche HIDCHE_DB_PREFIX=hidche
#MYSQL 게시판 비밀번호. (필수) #게시판 DB 비밀번호.
MYSQL_BBS_USER=board HIDCHE_DB_BBS_USER=board
MYSQL_BBS_PASSWORD= HIDCHE_DB_BBS_PASSWORD=
#이미지 동기화 키. (16글자 이상, 빈칸인 경우 랜덤) #이미지 동기화 키. (16글자 이상, 빈칸인 경우 랜덤)
HIDCHE_IMAGE_REQUEST_KEY= HIDCHE_IMAGE_REQUEST_KEY=
+14 -6
View File
@@ -1,17 +1,17 @@
FROM php:8.0-fpm-bullseye FROM php:8.3-fpm-bookworm
#debian #debian
ENV LC_ALL=C.UTF-8 ENV LC_ALL=C.UTF-8
RUN apt -y update ;\ RUN apt -y update ;\
apt -y install \ apt -y install \
bzip2 git rsync \ bzip2 zip unzip p7zip-full git rsync \
libmemcached-dev libcurl4-openssl-dev libmcrypt-dev \ libmemcached-dev libcurl4-openssl-dev \
libicu-dev libjpeg-dev libpng-dev libwebp-dev libfreetype6-dev \ libicu-dev libjpeg-dev libpng-dev libwebp-dev libavif-dev libfreetype6-dev \
libzip-dev libxml2-dev libsqlite3-dev gosu build-essential; libzip-dev libxml2-dev libsqlite3-dev gosu build-essential;
RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
docker-php-ext-configure gd --with-freetype-dir=/usr --with-png-dir=/usr --with-jpeg-dir=/usr --with-webp-dir=/usr; \ docker-php-ext-configure gd --with-freetype --with-webp --with-avif --with-jpeg --with-png ; \
docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd; \ docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd; \
docker-php-ext-configure mysqli --with-mysqli=mysqlnd; \ docker-php-ext-configure mysqli --with-mysqli=mysqlnd; \
docker-php-ext-install -j "$(nproc)" \ docker-php-ext-install -j "$(nproc)" \
@@ -19,11 +19,14 @@ RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
gd \ gd \
intl \ intl \
opcache \ opcache \
sysvmsg \
sysvsem \
sysvshm \
pcntl \ pcntl \
pdo_mysql \ pdo_mysql \
mysqli \ mysqli \
zip; zip;
RUN pecl install memcached mcrypt; RUN pecl install ds;
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \ RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
apt install -yq nodejs apt install -yq nodejs
@@ -58,5 +61,10 @@ RUN if [ "$UID" != 33 ]; then \
COPY sam_conf.ini /usr/local/etc/php/conf.d/sam_conf.ini COPY sam_conf.ini /usr/local/etc/php/conf.d/sam_conf.ini
# SETUP PHP-FPM CONFIG SETTINGS (max_children / max_requests)
RUN echo 'pm.max_children = 15' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'pm.max_requests = 500' >> /usr/local/etc/php-fpm.d/zz-docker.conf && \
echo 'request_terminate_timeout = 600' >> /usr/local/etc/php-fpm.d/zz-docker.conf
ENTRYPOINT ["entrypoint.sh"] ENTRYPOINT ["entrypoint.sh"]
CMD ["php-fpm"] CMD ["php-fpm"]
+3
View File
@@ -14,6 +14,9 @@ if [ ! -f "$samRoot/index.php" ]; then
mkdir -p $samRoot mkdir -p $samRoot
chown -R www-data:www-data $wwwRoot chown -R www-data:www-data $wwwRoot
gosu www-data git clone $gameGitPath $samRoot gosu www-data git clone $gameGitPath $samRoot
pushd $samRoot
gosu www-data git checkout $gameGitBranch
popd
fi fi
if [ "$HIDCHE_IMAGE_USE_INTERNAL" = "yes" ] && [ ! -d "$imageRoot" ]; then if [ "$HIDCHE_IMAGE_USE_INTERNAL" = "yes" ] && [ ! -d "$imageRoot" ]; then
+4 -1
View File
@@ -1,5 +1,5 @@
expose_php = Off expose_php = Off
max_execution_time = 300
pdo_mysql.cache_size = 2000 pdo_mysql.cache_size = 2000
mysqli.cache_size = 2000 mysqli.cache_size = 2000
memory_limit=512M memory_limit=512M
@@ -15,3 +15,6 @@ opcache.memory_consumption=128
opcache.save_comments=1 opcache.save_comments=1
opcache.revalidate_freq=1 opcache.revalidate_freq=1
opcache.file_cache="/var/www/opcache" opcache.file_cache="/var/www/opcache"
opcache.jit="function"
extension=ds.so
+10
View File
@@ -0,0 +1,10 @@
FROM python:3-alpine
#alpine + python3 + cron(from alpine) + mariadb-client
RUN apk add --no-cache mariadb-client rsync
COPY run_backup.py /usr/local/bin/
RUN chmod +x /usr/local/bin/run_backup.py && \
echo '0 5 * * * python3 /usr/local/bin/run_backup.py' > /etc/crontabs/root
ENTRYPOINT []
CMD ["crond", "-f" , "-L", "/dev/stdout"]
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
import os
import os.path
from subprocess import Popen, PIPE, run as subprocess_run
from datetime import datetime
from multiprocessing.dummy import Pool as ThreadPool
def backup_table(db_name, table_name, output_prefix):
sql_path = '{}/{}/{}.sql.gz'.format(output_prefix, db_name, table_name)
#print(sql_path)
with open(sql_path, 'wb') as sql_out:
sqldump = Popen(['mysqldump', '-f', '--skip-comments', '-h', 'db', '-u', 'root', '--password={}'.format(root_pw), db_name, table_name], stdout=PIPE)
gzdump = Popen(['gzip', '-c'], stdin=sqldump.stdout, stdout=sql_out)
sqldump.wait()
gzdump.wait()
os.chmod(sql_path, 0o644)
print('sql done {}, {}'.format(db_name, table_name))
def backup_files(src_path, output_path):
subprocess_run(['rsync', '-au', src_path, output_path])
print('file done {}'.format(src_path))
now = datetime.now()
print('> backup begin', now.isoformat())
weekday = now.weekday()
hour = now.hour
store_path = '/var/backup'
output_prefix = '{}/hidche_backup_w{}-{:02}'.format(store_path, weekday, hour)
os.makedirs(output_prefix, exist_ok=True)
db_prefix = os.environ['HIDCHE_DB_PREFIX']
server_list = os.environ['HIDCHE_SERVER_LIST'].strip(' ,').split(',')
server_list.append('root')
board_db_name = os.environ['HIDCHE_DB_BBS_USER']
server_list.append(board_db_name)
#print(server_list)
root_pw = os.environ['MARIADB_ROOT_PASSWORD']
board_files_path = os.environ.get('HIDCHE_BOARD_FILES_PATH', '/var/www/board/files')
with ThreadPool(4) as pool:
waiters = []
waiters.append(pool.apply_async(backup_files, ('/var/www/html/sam/d_pic', '{}/sam_image'.format(output_prefix))))
print(board_files_path)
if os.path.exists(board_files_path):
waiters.append(pool.apply_async(backup_files, (board_files_path, '{}/board_files'.format(output_prefix))))
for server_name in server_list:
db_name = '{}_{}'.format(db_prefix, server_name)
raw_tables = subprocess_run(['mysql', '-NBA' , '-h' ,'db', '-u', 'root' ,'--password={}'.format(root_pw), '-D', db_name, '-e', 'show tables'], stdout=PIPE)
raw_tables = raw_tables.stdout.decode('utf-8').strip(' \n\t')
if raw_tables == '':
continue
tables = raw_tables.split('\n')
d_setting_path = '/var/www/html/sam/{}/d_setting'.format(server_name)
if os.path.exists(d_setting_path):
waiters.append(pool.apply_async(backup_files, (d_setting_path, '{}/{}'.format(output_prefix, db_name))))
os.makedirs('{}/{}'.format(output_prefix, db_name), exist_ok=True)
for table_name in tables:
waiters.append(pool.apply_async(backup_table, (db_name, table_name, output_prefix)))
for waiter in waiters:
waiter.wait()
print('> backup finish', datetime.now().isoformat())
+7 -19
View File
@@ -1,17 +1,17 @@
FROM php:7.4-fpm-bullseye FROM php:8.3-fpm-bookworm
#debian #debian
ENV LC_ALL=C.UTF-8 ENV LC_ALL=C.UTF-8
RUN apt -y update ;\ RUN apt -y update ;\
apt -y install \ apt -y install \
bzip2 git rsync \ bzip2 zip unzip p7zip-full git rsync \
libmemcached-dev libcurl4-openssl-dev libmcrypt-dev \ libmemcached-dev libcurl4-openssl-dev \
libicu-dev libjpeg-dev libpng-dev libwebp-dev libfreetype6-dev \ libicu-dev libjpeg-dev libpng-dev libwebp-dev libavif-dev libfreetype6-dev \
libzip-dev libxml2-dev libsqlite3-dev gosu build-essential; libzip-dev libxml2-dev libsqlite3-dev gosu build-essential;
RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
docker-php-ext-configure gd --with-freetype-dir=/usr --with-png-dir=/usr --with-jpeg-dir=/usr --with-webp-dir=/usr; \ docker-php-ext-configure gd --with-freetype --with-webp --with-avif --with-jpeg --with-png ; \
docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd; \ docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd; \
docker-php-ext-configure mysqli --with-mysqli=mysqlnd; \ docker-php-ext-configure mysqli --with-mysqli=mysqlnd; \
docker-php-ext-install -j "$(nproc)" \ docker-php-ext-install -j "$(nproc)" \
@@ -23,21 +23,9 @@ RUN debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
pdo_mysql \ pdo_mysql \
mysqli \ mysqli \
zip; zip;
RUN pecl install memcached mcrypt; RUN pecl install ds;
#from nextcloud setting #from nextcloud setting
RUN { \ RUN mkdir -p /var/www/board; \
echo 'opcache.enable=1'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=10000'; \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini; \
\
echo 'apc.enable_cli=1' >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini; \
\
echo 'memory_limit=512M' > /usr/local/etc/php/conf.d/memory-limit.ini; \
mkdir -p /var/www/board; \
mkdir -p /var/www/.ssh; mkdir -p /var/www/.ssh;
COPY entrypoint.sh /usr/local/bin/ COPY entrypoint.sh /usr/local/bin/
+2 -2
View File
@@ -1,4 +1,4 @@
FROM mariadb FROM mariadb:11
#ubuntu #ubuntu
COPY entrypoint.sh /usr/local/bin/ COPY entrypoint.sh /usr/local/bin/
@@ -7,4 +7,4 @@ ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3306 EXPOSE 3306
CMD ["mysqld"] CMD ["mariadbd"]
Executable → Regular
+573 -176
View File
@@ -1,25 +1,22 @@
#!/bin/bash #!/bin/bash
# from https://github.com/docker-library/mariadb/blob/master/10.4/Dockerfile
set -eo pipefail set -eo pipefail
shopt -s nullglob shopt -s nullglob
# logging functions
# if command starts with an option, prepend mysqld mysql_log() {
if [ "${1:0:1}" = '-' ]; then local type="$1"; shift
set -- mysqld "$@" printf '%s [%s] [Entrypoint]: %s\n' "$(date --rfc-3339=seconds)" "$type" "$*"
fi }
mysql_note() {
# skip setup if they want an option that stops mysqld mysql_log Note "$@"
wantHelp= }
for arg; do mysql_warn() {
case "$arg" in mysql_log Warn "$@" >&2
-'?'|--help|--print-defaults|-V|--version) }
wantHelp=1 mysql_error() {
break mysql_log ERROR "$@" >&2
;; exit 1
esac }
done
# usage: file_env VAR [DEFAULT] # usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example' # ie: file_env 'XYZ_DB_PASSWORD' 'example'
@@ -30,8 +27,7 @@ file_env() {
local fileVar="${var}_FILE" local fileVar="${var}_FILE"
local def="${2:-}" local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)" mysql_error "Both $var and $fileVar are set (but are exclusive)"
exit 1
fi fi
local val="$def" local val="$def"
if [ "${!var:-}" ]; then if [ "${!var:-}" ]; then
@@ -43,18 +39,25 @@ file_env() {
unset "$fileVar" unset "$fileVar"
} }
_check_config() { # set MARIADB_xyz from MYSQL_xyz when MARIADB_xyz is unset
toRun=( "$@" --verbose --help --log-bin-index="$(mktemp -u)" ) # and make them the same value (so user scripts can use either)
if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then _mariadb_file_env() {
cat >&2 <<-EOM local var="$1"; shift
ERROR: mysqld failed while attempting to check config local maria="MARIADB_${var#MYSQL_}"
command was: "${toRun[*]}" file_env "$var" "$@"
$errors file_env "$maria" "${!var}"
EOM if [ "${!maria:-}" ]; then
exit 1 export "$var"="${!maria}"
fi fi
} }
# check to see if this file is being run or sourced from another script
_is_sourced() {
# https://unix.stackexchange.com/a/215279
[ "${#FUNCNAME[@]}" -ge 2 ] \
&& [ "${FUNCNAME[0]}" = '_is_sourced' ] \
&& [ "${FUNCNAME[1]}" = 'source' ]
}
#modifed #modifed
file_env 'TZ' file_env 'TZ'
@@ -63,161 +66,555 @@ ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#modifed #modifed
hidcheDBList=("root" "che" "kwe" "pwe" "twe" "nya" "pya" "hwe") hidcheDBList=("root" "che" "kwe" "pwe" "twe" "nya" "pya" "hwe")
# Fetch value from server config # usage: docker_process_init_files [file [file [...]]]
# We use mysqld --verbose --help instead of my_print_defaults because the # ie: docker_process_init_files /always-initdb.d/*
# latter only show values present in config files, and not server defaults # process initializer files, based on file extensions
_get_config() { docker_process_init_files() {
local conf="$1"; shift # mysql here for backwards compatibility "${mysql[@]}"
"$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null \ # ShellCheck: mysql appears unused. Verify use (or export if used externally)
| awk '$1 == "'"$conf"'" && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }' # shellcheck disable=SC2034
# match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)" mysql=( docker_process_sql )
}
# allow the container to be started with `--user`
if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
_check_config "$@"
DATADIR="$(_get_config 'datadir' "$@")"
mkdir -p "$DATADIR"
find "$DATADIR" \! -user mysql -exec chown mysql '{}' +
exec gosu mysql "$BASH_SOURCE" "$@"
fi
if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
# still need to check config, container may have started with --user
_check_config "$@"
# Get config
DATADIR="$(_get_config 'datadir' "$@")"
if [ ! -d "$DATADIR/mysql" ]; then
file_env 'MYSQL_ROOT_PASSWORD'
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
echo >&2 'error: database is uninitialized and password option is not specified '
echo >&2 ' You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
exit 1
fi
mkdir -p "$DATADIR"
echo 'Initializing database'
installArgs=( --datadir="$DATADIR" --rpm )
if { mysql_install_db --help || :; } | grep -q -- '--auth-root-authentication-method'; then
# beginning in 10.4.3, install_db uses "socket" which only allows system user root to connect, switch back to "normal" to allow mysql root without a password
# see https://github.com/MariaDB/server/commit/b9f3f06857ac6f9105dc65caae19782f09b47fb3
# (this flag doesn't exist in 10.0 and below)
installArgs+=( --auth-root-authentication-method=normal )
fi
# "Other options are passed to mysqld." (so we pass all "mysqld" arguments directly here)
mysql_install_db "${installArgs[@]}" "${@:2}"
echo 'Database initialized'
SOCKET="$(_get_config 'socket' "$@")"
"$@" --skip-networking --socket="${SOCKET}" &
pid="$!"
mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
for i in {30..0}; do
if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
break
fi
echo 'MySQL init process in progress...'
sleep 1
done
if [ "$i" = 0 ]; then
echo >&2 'MySQL init process failed.'
exit 1
fi
if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
# sed is for https://bugs.mysql.com/bug.php?id=20545
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
fi
if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
fi
rootCreate=
# default root to listen for connections from anywhere
file_env 'MYSQL_ROOT_HOST' '%'
if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
# no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MYSQL_ROOT_HOST}' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
GRANT ALL ON *.* TO 'root'@'${MYSQL_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL
fi
"${mysql[@]}" <<-EOSQL
-- What's done in this file shouldn't be replicated
-- or products like mysql-fabric won't work
SET @@SESSION.SQL_LOG_BIN=0;
DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
${rootCreate}
DROP DATABASE IF EXISTS test ;
FLUSH PRIVILEGES ;
EOSQL
if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
fi
#modifed
file_env 'HIDCHE_DB_PREFIX'
for dbName in "${hidcheDBList[@]}"; do
fullDBName="${HIDCHE_DB_PREFIX}_${dbName}"
echo "CREATE DATABASE IF NOT EXISTS \`$fullDBName\` ;" | "${mysql[@]}"
done
file_env 'MYSQL_USER'
file_env 'MYSQL_PASSWORD'
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[@]}"
for dbName in "${hidcheDBList[@]}"; do
fullDBName="${HIDCHE_DB_PREFIX}_${dbName}"
subPW=`echo -n ${dbName}${HIDCHE_PW_SALT}${MYSQL_USER}${MYSQL_PASSWORD}${dbName}${HIDCHE_PW_SALT} | shasum -a 512`
subPW=${subPW:0:32}
echo "CREATE USER '$fullDBName'@'%' IDENTIFIED BY '$subPW' ;" | "${mysql[@]}"
echo "GRANT ALL ON \`$fullDBName\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
echo "GRANT ALL ON \`$fullDBName\`.* TO '$fullDBName'@'%' ;" | "${mysql[@]}"
done
fi
file_env 'MYSQL_BBS_USER'
file_env 'MYSQL_BBS_PASSWORD'
if [ "$MYSQL_BBS_USER" -a "$MYSQL_BBS_PASSWORD" ]; then
echo "CREATE USER '$MYSQL_BBS_USER'@'%' IDENTIFIED BY '$MYSQL_BBS_PASSWORD' ;" | "${mysql[@]}"
fullDBName="${HIDCHE_DB_PREFIX}_board"
echo "CREATE DATABASE IF NOT EXISTS \`$fullDBName\` ;" | "${mysql[@]}"
echo "GRANT ALL ON \`$fullDBName\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
echo "GRANT ALL ON \`$fullDBName\`.* TO '$MYSQL_BBS_USER'@'%' ;" | "${mysql[@]}"
fi
echo echo
for f in /docker-entrypoint-initdb.d/*; do local f
for f; do
case "$f" in case "$f" in
*.sh) echo "$0: running $f"; . "$f" ;; *.sh)
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;; # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;; # https://github.com/docker-library/postgres/pull/452
*) echo "$0: ignoring $f" ;; if [ -x "$f" ]; then
mysql_note "$0: running $f"
"$f"
else
mysql_note "$0: sourcing $f"
# ShellCheck can't follow non-constant source. Use a directive to specify location.
# shellcheck disable=SC1090
. "$f"
fi
;;
*.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
*.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
*.sql.xz) mysql_note "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;;
*.sql.zst) mysql_note "$0: running $f"; zstd -dc "$f" | docker_process_sql; echo ;;
*) mysql_warn "$0: ignoring $f" ;;
esac esac
echo echo
done done
}
if ! kill -s TERM "$pid" || ! wait "$pid"; then # arguments necessary to run "mariadbd --verbose --help" successfully (used for testing configuration validity and for extracting default/configured values)
echo >&2 'MySQL init process failed.' _verboseHelpArgs=(
exit 1 --verbose --help
)
mysql_check_config() {
local toRun=( "$@" "${_verboseHelpArgs[@]}" ) errors
if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then
mysql_error $'mariadbd failed while attempting to check config\n\tcommand was: '"${toRun[*]}"$'\n\t'"$errors"
fi
}
# Fetch value from server config
# We use mariadbd --verbose --help instead of my_print_defaults because the
# latter only show values present in config files, and not server defaults
mysql_get_config() {
local conf="$1"; shift
"$@" "${_verboseHelpArgs[@]}" 2>/dev/null \
| awk -v conf="$conf" '$1 == conf && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
# match "datadir /some/path with/spaces in/it here" but not "--xyz=abc\n datadir (xyz)"
}
# Do a temporary startup of the MariaDB server, for init purposes
docker_temp_server_start() {
"$@" --skip-networking --default-time-zone=SYSTEM --socket="${SOCKET}" --wsrep_on=OFF \
--expire-logs-days=0 \
--loose-innodb_buffer_pool_load_at_startup=0 &
declare -g MARIADB_PID
MARIADB_PID=$!
mysql_note "Waiting for server startup"
# only use the root password if the database has already been initialized
# so that it won't try to fill in a password file when it hasn't been set yet
extraArgs=()
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
extraArgs+=( '--dont-use-mysql-root-password' )
fi
local i
for i in {30..0}; do
if docker_process_sql "${extraArgs[@]}" --database=mysql <<<'SELECT 1' &> /dev/null; then
break
fi
sleep 1
done
if [ "$i" = 0 ]; then
mysql_error "Unable to start server."
fi
}
# Stop the server. When using a local socket file mariadb-admin will block until
# the shutdown is complete.
docker_temp_server_stop() {
kill "$MARIADB_PID"
wait "$MARIADB_PID"
}
# Verify that the minimally required password settings are set for new databases.
docker_verify_minimum_env() {
if [ -z "$MARIADB_ROOT_PASSWORD" ] && [ -z "$MARIADB_ROOT_PASSWORD_HASH" ] && [ -z "$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" ] && [ -z "$MARIADB_RANDOM_ROOT_PASSWORD" ]; then
mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MARIADB_ROOT_PASSWORD, MARIADB_ROOT_PASSWORD_HASH, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD and MARIADB_RANDOM_ROOT_PASSWORD'
fi
# More preemptive exclusions of combinations should have been made before *PASSWORD_HASH was added, but for now we don't enforce due to compatibility.
if [ -n "$MARIADB_ROOT_PASSWORD" ] || [ -n "$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" ] || [ -n "$MARIADB_RANDOM_ROOT_PASSWORD" ] && [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
mysql_error "Cannot specify MARIADB_ROOT_PASSWORD_HASH and another MARIADB_ROOT_PASSWORD* option."
fi
if [ -n "$MARIADB_PASSWORD" ] && [ -n "$MARIADB_PASSWORD_HASH" ]; then
mysql_error "Cannot specify MARIADB_PASSWORD_HASH and MARIADB_PASSWORD option."
fi
if [ -n "$MARIADB_REPLICATION_USER" ]; then
if [ -z "$MARIADB_MASTER_HOST" ]; then
# its a master, we're creating a user
if [ -z "$MARIADB_REPLICATION_PASSWORD" ] && [ -z "$MARIADB_REPLICATION_PASSWORD_HASH" ]; then
mysql_error "MARIADB_REPLICATION_PASSWORD or MARIADB_REPLICATION_PASSWORD_HASH not found to create replication user for master"
fi
else
# its a replica
if [ -z "$MARIADB_REPLICATION_PASSWORD" ] ; then
mysql_error "MARIADB_REPLICATION_PASSWORD is mandatory to specify the replication on the replica image."
fi
if [ -n "$MARIADB_REPLICATION_PASSWORD_HASH" ] ; then
mysql_warn "MARIADB_REPLICATION_PASSWORD_HASH cannot be specified on a replica"
fi
fi
fi
if [ -n "$MARIADB_MASTER_HOST" ] && { [ -z "$MARIADB_REPLICATION_USER" ] || [ -z "$MARIADB_REPLICATION_PASSWORD" ] ; }; then
mysql_error "For a replica, MARIADB_REPLICATION_USER and MARIADB_REPLICATION is mandatory."
fi
}
# creates folders for the database
# also ensures permission for user mysql of run as root
docker_create_db_directories() {
local user; user="$(id -u)"
# TODO other directories that are used by default? like /var/lib/mysql-files
# see https://github.com/docker-library/mysql/issues/562
mkdir -p "$DATADIR"
if [ "$user" = "0" ]; then
# this will cause less disk access than `chown -R`
find "$DATADIR" \! -user mysql -exec chown mysql: '{}' +
# See https://github.com/MariaDB/mariadb-docker/issues/363
find "${SOCKET%/*}" -maxdepth 0 \! -user mysql -exec chown mysql: '{}' \;
fi
}
_mariadb_version() {
local mariaVersion="${MARIADB_VERSION##*:}"
mariaVersion="${mariaVersion%%[-+~]*}"
echo -n "${mariaVersion}-MariaDB"
}
# initializes the database directory
docker_init_database_dir() {
mysql_note "Initializing database files"
installArgs=( --datadir="$DATADIR" --rpm --auth-root-authentication-method=normal )
# "Other options are passed to mariadbd." (so we pass all "mysqld" arguments directly here)
mariadb-install-db "${installArgs[@]}" "${@:2}" \
--skip-test-db \
--old-mode='UTF8_IS_UTF8MB3' \
--default-time-zone=SYSTEM --enforce-storage-engine= \
--skip-log-bin \
--expire-logs-days=0 \
--loose-innodb_buffer_pool_load_at_startup=0 \
--loose-innodb_buffer_pool_dump_at_shutdown=0
mysql_note "Database files initialized"
}
# Loads various settings that are used elsewhere in the script
# This should be called after mysql_check_config, but before any other functions
docker_setup_env() {
# Get config
declare -g DATADIR SOCKET
DATADIR="$(mysql_get_config 'datadir' "$@")"
SOCKET="$(mysql_get_config 'socket' "$@")"
# Initialize values that might be stored in a file
_mariadb_file_env 'MYSQL_ROOT_HOST' '%'
_mariadb_file_env 'MYSQL_DATABASE'
_mariadb_file_env 'MYSQL_USER'
_mariadb_file_env 'MYSQL_PASSWORD'
_mariadb_file_env 'MYSQL_ROOT_PASSWORD'
# No MYSQL_ compatibility needed for new variables
file_env 'MARIADB_PASSWORD_HASH'
file_env 'MARIADB_ROOT_PASSWORD_HASH'
# env variables related to replication
file_env 'MARIADB_REPLICATION_USER'
file_env 'MARIADB_REPLICATION_PASSWORD'
file_env 'MARIADB_REPLICATION_PASSWORD_HASH'
# env variables related to master
file_env 'MARIADB_MASTER_HOST'
file_env 'MARIADB_MASTER_PORT' 3306
# set MARIADB_ from MYSQL_ when it is unset and then make them the same value
: "${MARIADB_ALLOW_EMPTY_ROOT_PASSWORD:=${MYSQL_ALLOW_EMPTY_PASSWORD:-}}"
export MYSQL_ALLOW_EMPTY_PASSWORD="$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" MARIADB_ALLOW_EMPTY_ROOT_PASSWORD
: "${MARIADB_RANDOM_ROOT_PASSWORD:=${MYSQL_RANDOM_ROOT_PASSWORD:-}}"
export MYSQL_RANDOM_ROOT_PASSWORD="$MARIADB_RANDOM_ROOT_PASSWORD" MARIADB_RANDOM_ROOT_PASSWORD
: "${MARIADB_INITDB_SKIP_TZINFO:=${MYSQL_INITDB_SKIP_TZINFO:-}}"
export MYSQL_INITDB_SKIP_TZINFO="$MARIADB_INITDB_SKIP_TZINFO" MARIADB_INITDB_SKIP_TZINFO
declare -g DATABASE_ALREADY_EXISTS
if [ -d "$DATADIR/mysql" ]; then
DATABASE_ALREADY_EXISTS='true'
fi
}
# Execute the client, use via docker_process_sql to handle root password
docker_exec_client() {
# args sent in can override this db, since they will be later in the command
if [ -n "$MYSQL_DATABASE" ]; then
set -- --database="$MYSQL_DATABASE" "$@"
fi
mariadb --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
}
# Execute sql script, passed via stdin
# usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args]
# ie: docker_process_sql --database=mydb <<<'INSERT ...'
# ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql
docker_process_sql() {
if [ '--dont-use-mysql-root-password' = "$1" ]; then
shift
MYSQL_PWD='' docker_exec_client "$@"
else
MYSQL_PWD=$MARIADB_ROOT_PASSWORD docker_exec_client "$@"
fi
}
# SQL escape the string $1 to be placed in a string literal.
# escape, \ followed by '
docker_sql_escape_string_literal() {
local newline=$'\n'
local escaped=${1//\\/\\\\}
escaped="${escaped//$newline/\\n}"
echo "${escaped//\'/\\\'}"
}
# Creates replication user
create_replica_user() {
if [ -n "$MARIADB_REPLICATION_PASSWORD_HASH" ]; then
echo "CREATE USER '$MARIADB_REPLICATION_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_REPLICATION_PASSWORD_HASH';"
else
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_REPLICATION_PASSWORD}" )
echo "CREATE USER '$MARIADB_REPLICATION_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
fi
echo "GRANT REPLICATION REPLICA ON *.* TO '$MARIADB_REPLICATION_USER'@'%';"
}
# Initializes database with timezone info and root password, plus optional extra db/user
docker_setup_db() {
# Load timezone info into database
if [ -z "$MARIADB_INITDB_SKIP_TZINFO" ]; then
# --skip-write-binlog usefully disables binary logging
# but also outputs LOCK TABLES to improve the IO of
# Aria (MDEV-23326) for 10.4+.
mariadb-tzinfo-to-sql --skip-write-binlog /usr/share/zoneinfo \
| docker_process_sql --dont-use-mysql-root-password --database=mysql
# tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet
fi
# Generate random root password
if [ -n "$MARIADB_RANDOM_ROOT_PASSWORD" ]; then
MARIADB_ROOT_PASSWORD="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
export MARIADB_ROOT_PASSWORD MYSQL_ROOT_PASSWORD=$MARIADB_ROOT_PASSWORD
mysql_note "GENERATED ROOT PASSWORD: $MARIADB_ROOT_PASSWORD"
fi fi
echo # Creates root users for non-localhost hosts
echo 'MySQL init process with HIDCHE done. Ready for start up.' local rootCreate=
echo local rootPasswordEscaped=
if [ -n "$MARIADB_ROOT_PASSWORD" ]; then
# Sets root password and creates root users for non-localhost hosts
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
fi fi
# default root to listen for connections from anywhere
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
# ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then
read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL
else
read -r -d '' rootCreate <<-EOSQL || true
CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
EOSQL
fi
fi
local mysqlAtLocalhost=
local mysqlAtLocalhostGrants=
# Install mysql@localhost user
if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ]; then
read -r -d '' mysqlAtLocalhost <<-EOSQL || true
CREATE USER mysql@localhost IDENTIFIED VIA unix_socket;
EOSQL
if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then
if [ "$MARIADB_MYSQL_LOCALHOST_GRANTS" != USAGE ]; then
mysql_warn "Excessive privileges ON *.* TO mysql@localhost facilitates risks to the confidentiality, integrity and availability of data stored"
fi
mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;";
fi
fi
local rootLocalhostPass=
if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then
# handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d
rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');"
fi
local createDatabase=
# Creates a custom database and user if specified
if [ -n "$MARIADB_DATABASE" ]; then
mysql_note "Creating database ${MARIADB_DATABASE}"
createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;"
fi
local createUser=
local userGrants=
#modifed
for dbName in "${hidcheDBList[@]}"; do
local fullDBName
local subPW
fullDBName="${HIDCHE_DB_PREFIX}_${dbName}"
mysql_note "Creating database ${fullDBName}"
subPW=`echo -n ${dbName}${HIDCHE_PW_SALT}${MARIADB_ROOT_PASSWORD}${dbName}${HIDCHE_PW_SALT} | shasum -a 512`
subPW=${subPW:0:32}
mysql_note "GENERATED ${fullDBName} PASSWORD: $subPW"
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${subPW}" )
createDatabase+="CREATE DATABASE IF NOT EXISTS \`$fullDBName\` ;"
createUser+="CREATE USER '$fullDBName'@'%' IDENTIFIED BY '$userPasswordEscaped';"
userGrants+="GRANT ALL ON \`${fullDBName//_/\\_}\`.* TO '$fullDBName'@'%' ;"
done
if [ -n "$HIDCHE_DB_BBS_USER" ] && [ -n "$HIDCHE_DB_BBS_PASSWORD" ]; then
local fullBBS_DBName
fullBBS_DBName="${HIDCHE_DB_PREFIX}_board"
mysql_note "Creating database ${fullBBS_DBName}"
createDatabase+="CREATE DATABASE IF NOT EXISTS \`$fullBBS_DBName\` ;"
mysql_note "Creating user ${HIDCHE_DB_BBS_USER}"
# SQL escape the user password, \ followed by '
local userPasswordEscaped
userPasswordEscaped=$( docker_sql_escape_string_literal "${HIDCHE_DB_BBS_PASSWORD}" )
createUser+="CREATE USER '$HIDCHE_DB_BBS_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';"
userGrants+="GRANT ALL ON \`${fullBBS_DBName//_/\\_}\`.* TO '$HIDCHE_DB_BBS_USER'@'%' ;"
fi
# To create replica user
local createReplicaUser=
local changeMasterTo=
local startReplica=
if [ -n "$MARIADB_REPLICATION_USER" ] ; then
if [ -z "$MARIADB_MASTER_HOST" ]; then
# on master
mysql_note "Creating user ${MARIADB_REPLICATION_USER}"
createReplicaUser=$(create_replica_user)
else
# on replica
local rplPasswordEscaped
rplPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_REPLICATION_PASSWORD}" )
# SC cannot follow how MARIADB_MASTER_PORT is assigned a default value.
# shellcheck disable=SC2153
changeMasterTo="CHANGE MASTER TO MASTER_HOST='$MARIADB_MASTER_HOST', MASTER_USER='$MARIADB_REPLICATION_USER', MASTER_PASSWORD='$rplPasswordEscaped', MASTER_PORT=$MARIADB_MASTER_PORT, MASTER_CONNECT_RETRY=10;"
startReplica="START REPLICA;"
fi
fi
mysql_note "Securing system users (equivalent to running mysql_secure_installation)"
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL
-- Securing system users shouldn't be replicated
SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN=0;
-- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set
SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', '');
DROP USER IF EXISTS root@'127.0.0.1', root@'::1';
EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\'');
${rootLocalhostPass}
${rootCreate}
${mysqlAtLocalhost}
${mysqlAtLocalhostGrants}
-- end of securing system users, rest of init now...
SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin;
-- create users/databases
${createDatabase}
${createUser}
${createReplicaUser}
${userGrants}
${changeMasterTo}
${startReplica}
EOSQL
}
# backup the mysql database
docker_mariadb_backup_system()
{
if [ -n "$MARIADB_DISABLE_UPGRADE_BACKUP" ] \
&& [ "$MARIADB_DISABLE_UPGRADE_BACKUP" = 1 ]; then
mysql_note "MariaDB upgrade backup disabled due to \$MARIADB_DISABLE_UPGRADE_BACKUP=1 setting"
return
fi
local backup_db="system_mysql_backup_unknown_version.sql.zst"
local oldfullversion="unknown_version"
if [ -r "$DATADIR"/mariadb_upgrade_info ]; then
read -r -d '' oldfullversion < "$DATADIR"/mariadb_upgrade_info || true
if [ -n "$oldfullversion" ]; then
backup_db="system_mysql_backup_${oldfullversion}.sql.zst"
fi
fi
mysql_note "Backing up system database to $backup_db"
if ! mariadb-dump --skip-lock-tables --replace --databases mysql --socket="${SOCKET}" | zstd > "${DATADIR}/${backup_db}"; then
mysql_error "Unable backup system database for upgrade from $oldfullversion."
fi
mysql_note "Backing up complete"
}
# perform mariadb-upgrade
# backup the mysql database if this is a major upgrade
docker_mariadb_upgrade() {
if [ -z "$MARIADB_AUTO_UPGRADE" ] \
|| [ "$MARIADB_AUTO_UPGRADE" = 0 ]; then
mysql_note "MariaDB upgrade (mariadb-upgrade) required, but skipped due to \$MARIADB_AUTO_UPGRADE setting"
return
fi
mysql_note "Starting temporary server"
docker_temp_server_start "$@" --skip-grant-tables \
--loose-innodb_buffer_pool_dump_at_shutdown=0 \
--skip-slave-start
mysql_note "Temporary server started."
docker_mariadb_backup_system
mysql_note "Starting mariadb-upgrade"
mariadb-upgrade --upgrade-system-tables
mysql_note "Finished mariadb-upgrade"
mysql_note "Stopping temporary server"
docker_temp_server_stop
mysql_note "Temporary server stopped"
}
_check_if_upgrade_is_needed() {
if [ ! -f "$DATADIR"/mariadb_upgrade_info ]; then
mysql_note "MariaDB upgrade information missing, assuming required"
return 0
fi
local mariadbVersion
mariadbVersion="$(_mariadb_version)"
IFS='.-' read -ra newversion <<<"$mariadbVersion"
IFS='.-' read -ra oldversion < "$DATADIR"/mariadb_upgrade_info || true
if [[ ${#newversion[@]} -lt 2 ]] || [[ ${#oldversion[@]} -lt 2 ]] \
|| [[ ${oldversion[0]} -lt ${newversion[0]} ]] \
|| [[ ${oldversion[0]} -eq ${newversion[0]} && ${oldversion[1]} -lt ${newversion[1]} ]]; then
return 0
fi
mysql_note "MariaDB upgrade not required"
return 1
}
# check arguments for an option that would cause mariadbd to stop
# return true if there is one
_mysql_want_help() {
local arg
for arg; do
case "$arg" in
-'?'|--help|--print-defaults|-V|--version)
return 0
;;
esac
done
return 1
}
_main() {
# if command starts with an option, prepend mariadbd
if [ "${1:0:1}" = '-' ]; then
set -- mariadbd "$@"
fi
#ENDOFSUBSTITUTIONS
# skip setup if they aren't running mysqld or want an option that stops mysqld
if [ "$1" = 'mariadbd' ] || [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then
mysql_note "Entrypoint script for MariaDB Server ${MARIADB_VERSION} started."
mysql_check_config "$@"
# Load various environment variables
docker_setup_env "$@"
docker_create_db_directories
# If container is started as root user, restart as dedicated mysql user
if [ "$(id -u)" = "0" ]; then
mysql_note "Switching to dedicated user 'mysql'"
exec gosu mysql "${BASH_SOURCE[0]}" "$@"
fi
# there's no database, so it needs to be initialized
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
docker_verify_minimum_env
# check dir permissions to reduce likelihood of half-initialized database
ls /docker-entrypoint-initdb.d/ > /dev/null
docker_init_database_dir "$@"
mysql_note "Starting temporary server"
docker_temp_server_start "$@"
mysql_note "Temporary server started."
docker_setup_db
docker_process_init_files /docker-entrypoint-initdb.d/*
# Wait until after /docker-entrypoint-initdb.d is performed before setting
# root@localhost password to a hash we don't know the password for.
if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then
mysql_note "Setting root@localhost password hash"
docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL
SET @@SESSION.SQL_LOG_BIN=0;
SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}';
EOSQL
fi
mysql_note "Stopping temporary server"
docker_temp_server_stop
mysql_note "Temporary server stopped"
echo
mysql_note "MariaDB init process done. Ready for start up."
echo
# MDEV-27636 mariadb_upgrade --check-if-upgrade-is-needed cannot be run offline
#elif mariadb-upgrade --check-if-upgrade-is-needed; then
elif _check_if_upgrade_is_needed; then
docker_mariadb_upgrade "$@"
fi
fi
exec "$@"
}
# If we are sourced from elsewhere, don't perform any further actions
if ! _is_sourced; then
_main "$@"
fi fi
exec "$@"
+19 -2
View File
@@ -13,8 +13,8 @@ services:
web: web:
build: ./web build: ./web
restart: always restart: always
ports: #ports:
- 8080:80 # - 8080:80
volumes: volumes:
- hidche:/var/www/html:ro - hidche:/var/www/html:ro
- board:/var/www/board:ro - board:/var/www/board:ro
@@ -54,6 +54,22 @@ services:
- db - db
- web - web
backup:
build: ./backup
restart: "no"
#restart: always
#command:
#- crond -f -L /dev/stdout
volumes:
- hidche:/var/www/html:ro
- backup:/var/backup
env_file:
- account.env
- game.env
depends_on:
- app
- db
cron: cron:
build: ./cron build: ./cron
restart: always restart: always
@@ -66,3 +82,4 @@ volumes:
db: db:
hidche: hidche:
board: board:
backup:
+16 -1
View File
@@ -25,7 +25,7 @@ services:
target: /var/www/html target: /var/www/html
#For DEV. Set app path as local directory #For DEV. Set app path as local directory
- type: bind - type: bind
source: ~/dev_sam/bbs source: ~/dev_sam/board
target: /var/www/board target: /var/www/board
app: app:
@@ -66,3 +66,18 @@ services:
target: /var/www/html target: /var/www/html
depends_on: depends_on:
- app - app
backup:
restart: "no"
volumes:
#- type: bind
# source: ~/dev_sam/backup
# target: /var/backup
- type: bind
read_only: true
source: ~/dev_sam/app
target: /var/www/html
- type: bind
read_only: true
source: ~/dev_sam/board
target: /var/www/board
+4
View File
@@ -2,6 +2,7 @@
#서버 git 주소. #서버 git 주소.
#만약 https:// 대신 ssh://로 시작하는 주소를 사용하는 경우 app/id_ecdsa, app/known_host 에 ecdsa 개인키와 ssh값을 추가할 것. #만약 https:// 대신 ssh://로 시작하는 주소를 사용하는 경우 app/id_ecdsa, app/known_host 에 ecdsa 개인키와 ssh값을 추가할 것.
gameGitPath=ssh://git@storage.hided.net:2525/devsam/core.git gameGitPath=ssh://git@storage.hided.net:2525/devsam/core.git
gameGitBranch=devel
imgGitPath=ssh://git@storage.hided.net:2525/devsam/image.git imgGitPath=ssh://git@storage.hided.net:2525/devsam/image.git
#게임 시간대. #게임 시간대.
@@ -18,3 +19,6 @@ HIDCHE_GAME_PATH=http://127.0.0.1:8080/sam
HIDCHE_IMAGE_USE_INTERNAL=yes HIDCHE_IMAGE_USE_INTERNAL=yes
#이미지 경로, HIDCHE_IMAGE_USE_INTERNAL이 yes인 경우 HIDCHE_GAME_PATH의 상대 경로. yes가 아닌 경우 전체 도메인 경로. #이미지 경로, HIDCHE_IMAGE_USE_INTERNAL이 yes인 경우 HIDCHE_GAME_PATH의 상대 경로. yes가 아닌 경우 전체 도메인 경로.
HIDCHE_IMAGE_PATH=../image HIDCHE_IMAGE_PATH=../image
#게시판 서버내 파일 백업 경로, /var/www/board/files 가 아니라면 직접 지정
#HIDCHE_BOARD_FILES_PATH=
+22 -12
View File
@@ -45,13 +45,17 @@ if not os.path.exists(indexPHP):
while True: while True:
try: try:
r = requests.head('http://web/sam/f_install/j_install_status.php') r = requests.head('http://web/sam/f_install/j_install_status.php')
if r.status_code == 200: if r.status_code == 503 or r.status_code == 500:
b = requests.get('http://web/sam/install.php', timeout=60000)
elif r.status_code == 200:
break break
except Exception: except Exception:
pass pass
print("Waiting for web connection...", flush=True) print("Waiting for web connection...", flush=True)
time.sleep(2) time.sleep(2)
requests.get('http://web/sam/install.php', timeout=60000) #NPM
while True: while True:
result = subprocess.call('nc -z -v -w30 db 3306'.split(' '), stderr=subprocess.STDOUT) result = subprocess.call('nc -z -v -w30 db 3306'.split(' '), stderr=subprocess.STDOUT)
if result == 0: if result == 0:
@@ -61,9 +65,10 @@ while True:
session = requests.session() session = requests.session()
db_root_pw = hash_password('root'+env['HIDCHE_PW_SALT'], env['MYSQL_USER']+env['MYSQL_PASSWORD'])[:32] db_root_pw = hash_password('root'+env['HIDCHE_PW_SALT'], env['MARIADB_ROOT_PASSWORD'])[:32]
db_root_name = '%s_root'%env['HIDCHE_DB_PREFIX'] db_root_name = '%s_root'%env['HIDCHE_DB_PREFIX']
print("Setup DB...", flush=True)
setupDBResult = session.post('http://web/sam/f_install/j_setup_db.php', { setupDBResult = session.post('http://web/sam/f_install/j_setup_db.php', {
'db_host':'db', 'db_host':'db',
'db_port':3306, 'db_port':3306,
@@ -76,8 +81,10 @@ setupDBResult = session.post('http://web/sam/f_install/j_setup_db.php', {
'kakao_rest_key':env['HIDCHE_KAKAO_REST_KEY'], 'kakao_rest_key':env['HIDCHE_KAKAO_REST_KEY'],
'kakao_admin_key':env['HIDCHE_KAKAO_ADMIN_KEY'], 'kakao_admin_key':env['HIDCHE_KAKAO_ADMIN_KEY'],
}, headers=headers) }, headers=headers)
if not setupDBResult.ok:
print(setupDBResult, flush=True)
setupDBJsonResult = json.loads(setupDBResult.text) setupDBJsonResult = json.loads(setupDBResult.text)
print(setupDBJsonResult) print(setupDBJsonResult, flush=True)
globalSalt = setupDBJsonResult['globalSalt'] globalSalt = setupDBJsonResult['globalSalt']
@@ -88,23 +95,26 @@ query = {
'password':hashPassword, 'password':hashPassword,
'nickname':'운영자' 'nickname':'운영자'
} }
print("Create Admin...", flush=True)
setupAdminResult = session.post('http://web/sam/f_install/j_create_admin.php', query, headers=headers) setupAdminResult = session.post('http://web/sam/f_install/j_create_admin.php', query, headers=headers)
setupAdminJsonResult = json.loads(setupAdminResult.text) setupAdminJsonResult = json.loads(setupAdminResult.text)
print(setupAdminJsonResult) print(setupAdminJsonResult, flush=True)
loginResult = session.post('http://web/sam/j_login.php', query, headers=headers) print("Login Admin...", flush=True)
print(loginResult.text) loginResult = session.post('http://web/sam/api.php?path=Login%2FLoginByID', json=query, headers=headers)
print(loginResult.text, flush=True)
serverList = str(env['HIDCHE_SERVER_LIST']).split(',') serverList = str(env['HIDCHE_SERVER_LIST']).split(',')
serverList.reverse() serverList.reverse()
for serverName in serverList: for serverName in serverList:
updateResult = session.post('http://web/sam/j_updateServer.php', { updateResult = session.post('http://web/sam/j_updateServer.php', {
'server':serverName, 'server':serverName,
'target':'origin/devel' 'target':'origin/'+env['gameGitBranch']
}, headers=headers) }, headers=headers, timeout=60000)
print(serverName, updateResult.text) print(serverName, updateResult.text, flush=True)
db_pw = hash_password(serverName+env['HIDCHE_PW_SALT'], env['MYSQL_USER']+env['MYSQL_PASSWORD'])[:32] db_pw = hash_password(serverName+env['HIDCHE_PW_SALT'], env['MARIADB_ROOT_PASSWORD'])[:32]
db_name = '%s_%s'%(env['HIDCHE_DB_PREFIX'], serverName) db_name = '%s_%s'%(env['HIDCHE_DB_PREFIX'], serverName)
resetResult = session.post('http://web/sam/%s/j_install_db.php'%serverName, { resetResult = session.post('http://web/sam/%s/j_install_db.php'%serverName, {
'db_host':'db', 'db_host':'db',
@@ -113,7 +123,7 @@ for serverName in serverList:
'db_pw':db_pw, 'db_pw':db_pw,
'db_name':db_name, 'db_name':db_name,
}, headers=headers) }, headers=headers)
print(serverName, resetResult.text) print(serverName, resetResult.text, flush=True)
if useWaitIndex: if useWaitIndex:
fp = open(indexPHP, 'wt', encoding='utf-8') fp = open(indexPHP, 'wt', encoding='utf-8')
@@ -121,4 +131,4 @@ if useWaitIndex:
fp.close() fp.close()
os.chown(indexPHP, 33, 33) os.chown(indexPHP, 33, 33)
print('Welcome to HIDCHE') print('Welcome to HIDCHE', flush=True)
+1
View File
@@ -14,6 +14,7 @@ RUN if [ "$UID" != 33 ]; then \
fi; fi;
COPY ./default.conf /etc/nginx/conf.d/default.conf COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ./sam.conf /etc/nginx/snippets/sam.conf
COPY ./rhymix.conf /etc/nginx/snippets/rhymix.conf COPY ./rhymix.conf /etc/nginx/snippets/rhymix.conf
VOLUME /var/www/html VOLUME /var/www/html
+3
View File
@@ -25,16 +25,19 @@ server {
include fastcgi_params; include fastcgi_params;
fastcgi_pass board:9000; fastcgi_pass board:9000;
fastcgi_index index.php; fastcgi_index index.php;
fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
} }
} }
location / { location / {
include snippets/sam.conf;
location ~ \.php$ { location ~ \.php$ {
include fastcgi_params; include fastcgi_params;
proxy_read_timeout 600; proxy_read_timeout 600;
fastcgi_pass app:9000; fastcgi_pass app:9000;
fastcgi_index index.php; fastcgi_index index.php;
fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
} }
} }
+68
View File
@@ -0,0 +1,68 @@
location ~ /\. {
return 404;
}
location ~ /composer {
return 404;
}
location ~ /package\.(json|lock) {
return 404;
}
location ~ /d_setting/ {
return 404;
}
location ~ /d_log/ {
return 404;
}
location ~ /logs/ {
return 404;
}
location ~ ^/sam/node_modules {
return 404;
}
location ~ ^/sam/vendor/ {
return 404;
}
location ~ /tests {
return 404;
}
location ~ /test-ts {
return 404;
}
location ~ /npm_recent {
return 404;
}
location ~ /composer_result {
return 404;
}
location ~ /tsconfig.json {
return 404;
}
location ~ /webpack.config.js {
return 404;
}
location ~ /src {
return 404;
}
location ~ ^/sam/[^/]+/sammo/ {
return 404;
}
location ~ ^/sam/[^/]+/data/ {
return 404;
}