First version

This commit is contained in:
0chan 2023-02-19 01:32:19 +06:00
commit f4205753c0
11 changed files with 370 additions and 0 deletions

16
.env.example Normal file
View File

@ -0,0 +1,16 @@
APP_CODE_PATH_HOST=./app
APP_CODE_PATH_CONTAINER=/var/www/app
APP_FPM_PORT=9000
NGINX_HOST_LOG_PATH=./logs
NGINX_SITES_PATH=./docker/nginx/sites
NGINX_DEFAULT_CONF=./docker/nginx/sites/default.conf
NGINX_HOST_HTTP_PORT=127.0.0.1:8080
NGINX_HOST_HTTPS_PORT=127.0.0.1:8443
VARNISH_BACKEND_PORT=8081
MARIADB_PORT=127.0.0.1:3306
WORKSPACE_TIMEZONE=Europe/Moscow
MARIADB_DATABASE=0chan
MARIADB_USER=0chan
MARIADB_PASSWORD=changeme
MARIADB_ROOT_PASSWORD=changemeASAP
MARIADB_DATADIR=./datadir

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/.env

32
README.md Normal file
View File

@ -0,0 +1,32 @@
## Требования
* Debian 11 / Ubuntu 22.04
* Установленные nginx, docker и docker compose
* 1 GB RAM + хотя бы пару ядер CPU для нормальной работы
* аккаунт на cloudflare
## Установка
1. Создайте не рутового пользователя у себя на сервере `adduser nullchan && usermod -a -G sudo nullchan && usermod -aG docker nullchan && su nullchan`
2. Склонируйте этот репозиторий в любую папку (например, `/home/nullchan/instant-0chan-docker`)
3. Склонируйте инстант в папку app (например, `/home/nullchan/instant-0chan-docker/app`)
4. Зайдите в папку instant-0chan-docker (`cd instant-0chan-docker`)
5. Скопируйте .env.example с новым именем .env (`cp .env.example .env`)
6. Скопируйте конфиг nginx (не забудьте указать в нем свой домен вместо 0chan.tld) `sudo cp nginx/0chan.tld.conf /etc/nginx/sites-available/`
7. Поменяйте `server_name` в скопированном файле и создайте симлинк для активации домена (`sudo ln -s /etc/nginx/sites-available/0chan.tld.conf /etc/nginx/sites-enabled/`)
8. Проверим что ничего не поломалось (`sudo nginx -t`)
9. Если всё ок, то перезагружаем nginx (`sudo nginx -s reload`)
10. Возвращаемся к файлу `.env`
11. Обязательно поменяйте `MARIADB_PASSWORD` и `MARIADB_ROOT_PASSWORD` (иначе я лично приду и снесу вам базу)
12. Можно запустить `docker compose build && docker compose up -d`
13. Когда всё установится, вам вернется управление терминалом. Вводим команду `docker ps` чтобы удостовериться что всё поднялось. Запоминаем хэш контейнера `kusaba-docker-app`, например у меня он `cd9ea837d6b4`
14. Выполняем команду `docker exec -it cd9ea837d6b4 bash` (с вашим айди контейнера)
15. `cp app/instance-config.php.example cp app/instance-config.php`
16. Отредактируем `instance-config.php`, установим настройки базы (обратите внимание что в качестве хоста используем не localhost а `mariadb`)
17. `mkdir -p /var/www/dwoo/templates_c` на всякий случай
18. `chown -R www-data:www-data /var/www/app`, это необходимо чтобы были права на создание кэша шаблонов и аплоада картинок
19. Ctrl+D, чтобы выйти из контейнера
20. Выполняем установку инстанта по инструкции самого инстанта
21. Подключаем сайт в настройках dns cloudflare
22. Устанавливаем certbot по инструкции с официального сайта
23. Выполняем `sudo certbot --nginx`, следуем инструкции, получаем сертификат для нашего сайта
Если у вас что-то не получилось, отпишитесь в треде https://0chan.plus/0/res/1.html

39
docker-compose.yml Normal file
View File

@ -0,0 +1,39 @@
version: '2.1'
services:
app:
container_name: "app"
hostname: app
build: ./docker/php
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
- "./docker/php/99-custom.ini:/usr/local/etc/php/conf.d/99-custom.ini"
depends_on:
- mariadb
nginx:
container_name: "nginx"
image: "nginx"
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
- ${NGINX_HOST_LOG_PATH}:/var/log/nginx
- ${NGINX_SITES_PATH}:/etc/nginx/sites-available
- ${NGINX_SITES_PATH}:/etc/nginx/sites-enabled
- ${NGINX_DEFAULT_CONF}:/etc/nginx/conf.d/default.conf
ports:
- "${NGINX_HOST_HTTP_PORT}:80"
- "${NGINX_HOST_HTTPS_PORT}:443"
- "${VARNISH_BACKEND_PORT}:81"
depends_on:
- app
mariadb:
container_name: "mariadb"
image: "mariadb"
ports:
- "${MARIADB_PORT}:3306"
volumes:
- "${MARIADB_DATADIR}:/var/lib/mysql"
environment:
- TZ=${WORKSPACE_TIMEZONE}
- MYSQL_DATABASE=${MARIADB_DATABASE}
- MYSQL_USER=${MARIADB_USER}
- MYSQL_PASSWORD=${MARIADB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}

View File

@ -0,0 +1,14 @@
/var/log/nginx/*.log {
daily
missingok
rotate 32
compress
delaycompress
nodateext
notifempty
create 644 www-data root
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}

34
docker/nginx/nginx.conf Normal file
View File

@ -0,0 +1,34 @@
user www-data;
worker_processes 4;
pid /run/nginx.pid;
daemon off;
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
types_hash_max_size 2048;
client_max_body_size 70M;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr;
gzip on;
gzip_disable "msie6";
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-available/*.conf;
open_file_cache off; # Disabled for issue 619
charset UTF-8;
}

1
docker/nginx/sites/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
!default.conf

View File

@ -0,0 +1,36 @@
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
client_max_body_size 70M;
server_name localhost;
root /var/www/app;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fixes timeouts
fastcgi_read_timeout 600;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}

25
docker/php/99-custom.ini Normal file
View File

@ -0,0 +1,25 @@
[PHP]
short_open_tag = off
display_errors = On
html_errors = On
memory_limit = 256M
max_execution_time = 3000
max_file_uploads = 999
max_input_time = 999
upload_max_filesize = 51200M
post_max_size = 51200M
max_input_vars = 5000
always_populate_raw_post_data=-1
[Date]
date.timezone = "Europe/Moscow"
[Xdebug]
xdebug.default_enable = 0
xdebug.remote_enable = 0
xdebug.remote_connect_back = 1
xdebug.remote_handler = dbgp
xdebug.remote_mode = jit
xdebug.show_local_vars = 1
xdebug.max_nesting_level = 1000
;xdebug.remote_log=/tmp/xdebug.log

71
docker/php/Dockerfile Normal file
View File

@ -0,0 +1,71 @@
FROM php:7.1-fpm
MAINTAINER 0chan Initiative <0chan@disroot.org>
# PHP config
ADD ./99-custom.ini /usr/local/etc/php/
# Install modules
RUN apt-get update
RUN apt-get install -y \
apt-utils \
curl \
dnsutils \
git \
unzip \
wget \
zip \
ffmpeg \
libcurl4-gnutls-dev \
libmcrypt-dev \
libtidy-dev \
libbz2-dev \
libxml2-dev \
libjpeg-dev \
libfreetype6-dev \
libjpeg62 \
libpng-dev \
libssl-dev \
libicu-dev \
libc-client-dev \
libkrb5-dev \
jpegoptim
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-configure imap --with-kerberos --with-imap-ssl
RUN docker-php-ext-install \
bcmath \
bz2 \
calendar \
curl \
exif \
ftp \
gd \
gettext \
imap \
intl \
json \
mbstring \
mcrypt \
mysqli \
opcache \
pdo \
pdo_mysql \
shmop \
soap \
sockets \
sysvmsg \
sysvsem \
sysvshm \
tidy \
wddx \
zip
# Possible values for ext-name:
# bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap
# interbase intl json ldap mbstring mcrypt mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql
# pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml
# snmp soap sockets spl standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zip
WORKDIR /var/www/app
CMD php-fpm

101
nginx/0chan.tld.conf Normal file
View File

@ -0,0 +1,101 @@
server {
server_name 0chan.tld;
# Этот хэдер должен передаваться в том случае если вы не хотите чтобы ваш инстант можно было встроить в фрейм
# add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
include /etc/nginx/mime.types;
index index.html index.php;
# Если не хотите давать возможность загружать большие файлы - поставьте меньшее значение
client_max_body_size 70m;
# Раскомментируйте если хотите видеть реальные айпи посетителей. Но при этом нужно закомментировать все allow/deny блоки
# set_real_ip_from 173.245.48.0/20;
# set_real_ip_from 103.21.244.0/22;
# set_real_ip_from 103.22.200.0/22;
# set_real_ip_from 103.31.4.0/22;
# set_real_ip_from 141.101.64.0/18;
# set_real_ip_from 108.162.192.0/18;
# set_real_ip_from 190.93.240.0/20;
# set_real_ip_from 188.114.96.0/20;
# set_real_ip_from 197.234.240.0/22;
# set_real_ip_from 198.41.128.0/17;
# set_real_ip_from 162.158.0.0/15;
# set_real_ip_from 104.16.0.0/13;
# set_real_ip_from 104.24.0.0/14;
# set_real_ip_from 172.64.0.0/13;
# set_real_ip_from 131.0.72.0/22;
# # - IPv6
# set_real_ip_from 2400:cb00::/32;
# set_real_ip_from 2606:4700::/32;
# set_real_ip_from 2803:f800::/32;
# set_real_ip_from 2405:b500::/32;
# set_real_ip_from 2405:8100::/32;
# set_real_ip_from 2a06:98c0::/29;
# set_real_ip_from 2c0f:f248::/32;
# real_ip_header CF-Connecting-IP;
# закомментируйте если не используете Cloudflare
# local
allow 192.168.0.0/16;
allow 172.16.0.0/12;
allow 10.0.0.0/8;
allow fc00::/7;
# cloudflare
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 104.16.0.0/12;
allow 108.162.192.0/18;
allow 131.0.72.0/22;
allow 141.101.64.0/18;
allow 162.158.0.0/15;
allow 172.64.0.0/13;
allow 173.245.48.0/20;
allow 188.114.96.0/20;
allow 190.93.240.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 199.27.128.0/21;
allow 2400:cb00::/32;
allow 2405:8100::/32;
allow 2405:b500::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2c0f:f248::/32;
allow 2a06:98c0::/29;
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;
# IPv6
allow 2400:cb00::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2405:b500::/32;
allow 2405:8100::/32;
allow 2a06:98c0::/29;
allow 2c0f:f248::/32;
deny all;
location / {
autoindex on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_pass http://127.0.0.1:8080/;
}
}