15.2. Установка CKAN в CentOS 7¶
За основу взята инструкция по установке из официальной документации.
15.2.1. Установка системных пакетов¶
Устанавливаем необходимые пакеты:
sudo yum install epel-release
sudo yum install python-pip python-virtualenv python-devel
sudo yum install git gcc-c++ java-1.8.0-openjdk unzip lsof libxml2-devel libxslt-devel mailcap
sudo yum install postgresql postgresql-server postgresql-libs postgresql-contrib postgresql-devel
Предупреждение
Если на сервере, куда устанавливается CKAN, уже установлен NextGIS Web, то пакеты для PostgreSQL ставить не нужно. В этом случае PostgreSQL уже должен быть установлен и настроен.
15.2.2. Установка CKAN¶
Создаём пользователя CKAN:
sudo useradd -m -s /sbin/nologin -d /usr/lib/ckan -c "CKAN User" ckan
Домашняя папка пользователя CKAN остальным пользователям системы доступна только на чтение:
sudo chmod 755 /usr/lib/ckan
Переключаемся на только что созданного пользователя:
sudo su -s /bin/bash - ckan
Устанавливаем виртуальное окружение default
:
virtualenv --no-site-packages default
И активируем его:
. default/bin/activate
Скачиваем и устанавливаем последнюю версию CKAN. На момент написания данной инструкции это версия CKAN 2.5.2. Если вы устанавливаете другую версию, то измените URL в следующей команде:
pip install -e git+https://github.com/okfn/ckan.git@ckan-2.5.2#egg=ckan
Устанавливаем пакеты Python, от которых зависит CKAN:
pip install -r default/src/ckan/requirements.txt
15.2.3. Настройка PostgreSQL¶
Инициализируем базу данных и включаем автоматический запуск PostgreSQL при старте системы:
sudo postgresql-setup initdb
systemctl start postgresql
systemctl enable postgresql
Предупреждение
В ходе работы с CKAN размер базы будет увеличиваться, поэтому в случае необходимости кластер базы данных должен быть вынесен в папку с достаточным объёмом дискового пространства.
Создаём пользователя базы данных ckan_default
и
саму базу также названную ckan_default
:
sudo -u postgres createuser -S -D -R -P ckan_default
sudo -u postgres createdb -O ckan_default ckan_default -E utf-8
Отредактируем параметры аутентификации в соответствующем файле:
sudo nano /var/lib/pgsql/data/pg_hba.conf
Отредактируем его таким образом, чтобы в нём присутствовали следующие
строки (исправим метод аутентификации на md5
, если указан иной):
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
Предупреждение
Предполагается, что CKAN и PostgreSQL установлены на одном хосте. Если это не так, то потребуется дополнительная настройка PostgreSQL.
Не забудьте перезапустить PostgreSQL:
systemctl restart postgresql
Предупреждение
Если вы устанавливали PostgreSQL из стороннего репозитория,
например отсюда, то может
потребоваться дополнительная настройка переменной PATH
,
либо придётся писать полный путь до команд, например,
/usr/pgsql-9.5/bin/psql
.
15.2.4. Создание конфигурационного файла CKAN¶
sudo mkdir -p /etc/ckan/default
sudo chown -R ckan /etc/ckan/
Переключаемся на пользователя CKAN и создаём конфигурационный файл:
sudo su -s /bin/bash - ckan
. default/bin/activate
cd /usr/lib/ckan/default/src/ckan
paster make-config ckan /etc/ckan/default/development.ini
Отредактируйте файл development.ini
, указав пароль пользователя
ckan_default
и URL сайта, по которому будет доступен CKAN:
sqlalchemy.url = postgresql://ckan_default:pass@localhost/ckan_default
ckan.site_url = http://82.162.194.216
ckan.root_path = /ckan/{{LANG}}
15.2.5. Установка Solr5¶
Скачиваем Solr. На текущий момент последняя версия - 5.5.0:
wget http://apache-mirror.rbc.ru/pub/apache/lucene/solr/5.5.0/solr-5.5.0.zip
unzip solr-5.5.0.zip
cd solr-5.5.0/bin
Устанавливаем Solr в /opt/solr5
:
unzip solr-5.5.0.zip
cd solr-5.5.0/bin
sudo mkdir /opt/solr5
sudo ./install_solr_service.sh ../../solr-5.5.0.zip -i /opt/solr5
После установки сервиса он будет запускаться автоматически при старте
системы. Скрипт запуска находится в файле /etc/init.d/solr
.
Создадим отдельное ядро Solr для CKAN:
sudo su solr
cd /opt/solr5/solr/bin
./solr create -c ckan
Настроим схему:
cd /var/solr/data/ckan/conf
ln -s /usr/lib/ckan/default/src/ckan/ckan/config/solr/schema.xml .
Удалим файл managed-schema
:
rm managed-schema
Откройте файл solrconfig.xml
. Найдите элемент
<schemaFactory class="ManagedIndexSchemaFactory">
и закомментируйте его:
<!--
<schemaFactory class="ManagedIndexSchemaFactory">
<bool name="mutable">true</bool>
<str name="managedSchemaResourceName">managed-schema</str>
</schemaFactory>
-->
Добавьте элемент:
<schemaFactory class="ClassicIndexSchemaFactory"/>
Найдите элемент <initParams>
, ссылающийся на
add-unknown-fields-to-the-schema
и закомментируйте его:
<!--
<initParams path="/update/**">
<lst name="defaults">
<str name="update.chain">add-unknown-fields-to-the-schema</str>
</lst>
</initParams>
-->
Также закомментируйте этот элемент:
<!--
<processor class="solr.AddSchemaFieldsUpdateProcessorFactory">
<str name="defaultFieldType">strings</str>
<lst name="typeMapping">
<str name="valueClass">java.lang.Boolean</str>
<str name="fieldType">booleans</str>
</lst>
<lst name="typeMapping">
<str name="valueClass">java.util.Date</str>
<str name="fieldType">tdates</str>
</lst>
<lst name="typeMapping">
<str name="valueClass">java.lang.Long</str>
<str name="valueClass">java.lang.Integer</str>
<str name="fieldType">tlongs</str>
</lst>
<lst name="typeMapping">
<str name="valueClass">java.lang.Number</str>
<str name="fieldType">tdoubles</str>
</lst>
</processor>
-->
Перезапускаем Solr:
sudo service solr restart
Отредактируем файл /etc/ckan/default/development.ini
, раскомментировав
соответствующую строку и указав URL Solr:
solr_url = http://127.0.0.1:8983/solr/ckan
15.2.6. Инициализация базы данных¶
sudo su -s /bin/bash - ckan
. default/bin/activate
cd default/src/ckan
paster db init -c /etc/ckan/default/development.ini
15.2.7. Установка DataStore¶
Откроём файл development.ini
и в список плагинов добавим
datastore
:
ckan.plugins = stats text_view image_view recline_view datastore
В базе данных создадим пользователя datastore_default
, который
не будет имет прав на запись, только на чтение:
sudo -u postgres createuser -S -D -R -P -l datastore_default
Создадим базу данных datastore_default
, владельцем которой будет
пользователь ckan_default
:
sudo -u postgres createdb -O ckan_default datastore_default -E utf-8
Откроем файл development.ini
, расскомментируем и отредактируем
следующие строки, указав соответствующие пароли:
ckan.datastore.write_url = postgresql://ckan_default:pass@localhost/datastore_default
ckan.datastore.read_url = postgresql://datastore_default:pass@localhost/datastore_default
Выставим права в базе данных:
cd /usr/lib/ckan
. default/bin/activate
cd default/src/ckan
paster --plugin=ckan datastore set-permissions -c /etc/ckan/default/development.ini | sudo -u postgres psql --set ON_ERROR_STOP=1
15.2.8. Установка DataPusher¶
За основу взята инструкция по установке из официальной документации.
sudo su -s /bin/bash - ckan
virtualenv --no-site-packages datapusher
. datapusher/bin/activate
mkdir datapusher/src
cd datapusher/src
git clone -b stable https://github.com/ckan/datapusher.git
cd datapusher
pip install -r requirements.txt
В файле development.ini
добавим соответствующий плагин:
ckan.plugins = <прочие плагины> datapusher
Также раскомментируйте следующие строки:
ckan.datapusher.formats = csv xls xlsx tsv application/csv application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
ckan.datapusher.url = http://127.0.0.1:8800/
15.2.9. Ссылка на who.ini¶
Файл who.ini
(конфигурационный файл Repoze.who) должен располагаться
в той же папке, что и конфигурационный файл CKAN:
ln -s /usr/lib/ckan/default/src/ckan/who.ini /etc/ckan/default/who.ini
15.2.10. Установка темы¶
В файл development.ini
добавьте плагин с темой:
ckan.plugins = <прочие плагины> fareast_theme
И установите саму тему:
sudo su -s /bin/bash - ckan
. default/bin/activate
cd default/src
git clone https://github.com/nextgis/ckanext-fareast_theme.git
pip install -e ./ckanext-fareast_theme
15.2.11. Дополнительные настройки¶
В файлe development.ini
:
ckan.auth.create_user_via_web = false
ckan.locale_default = ru
ckan.locales_offered = en ru
ckan.locales_filtered_out = ru_RU
# Убрать '/ckan', если приложение монтируется в '/'
ckan.favicon = /ckan/base/images/ckan.ico
# На данный каталог у пользователя, под которым будет
# запускаться CKAN, должны быть права на запись
ckan.storage_path = /mnt/portal/ckan/default
15.2.12. Развёртывание CKAN¶
За основу взята инструкция по развёртыванию из официальной документации.
Переходим в папку /etc/ckan/default
:
sudo su -s /bin/bash - ckan
cd /etc/ckan/default
И создаём файл uwsgiapp.py
со следующим содержимым:
import os
activate_this = os.path.join('/usr/lib/ckan/default/bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
from paste.deploy import loadapp
config_filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'development.ini')
from paste.script.util.logging_config import fileConfig
fileConfig(config_filepath)
application = loadapp('config:%s' % config_filepath)
Устанавливаем Nginx и uWSGI:
sudo yum install uwsgi uwsgi-plugin-python
Переходим в папку /etc/uwsgi.d
и создаём файл ckan.ini
следующего содержания:
[uwsgi]
plugins = python
lazy-apps = true
master = true
workers = 4
no-orphans = true
pidfile = /run/uwsgi/%n.pid
socket = /run/uwsgi/%n.sock
chmod-socket = 666
logto = /var/log/uwsgi/%n.log
log-date = true
harakiri = 6000
mount = /ckan=/etc/ckan/default/uwsgiapp.py
manage-script-name = true
Поскольку uWSGI запущен в режиме Tyrant
, то необходимо изменить
владельца конфигурационного файла ckan.ini
:
sudo chown uwsgi:uwsgi ckan.ini
Создадим папку, куда будут писаться логи:
sudo mkdir /var/log/uwsgi
sudo touch /var/log/uwsgi/ckan.log
sudo chown uwsgi:uwsgi /var/log/uwsgi/ckan.log
Для ротации логов в папке /etc/logrotate.d
создадим файл
uwsgi
следующего содержания:
/var/log/uwsgi/*.log {
copytruncate
daily
rotate 5
compress
delaycompress
missingok
notifempty
}
Запускаем uWSGI:
sudo systemctl start uwsgi
sudo systemctl enable uwsgi
В папке /etc/nginx/conf.d
создадим файл ckan.conf
следующего содержания:
uwsgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=ckan:30m max_size=250m;
server {
listen 80;
server_name 82.162.194.216;
client_max_body_size 100M;
location /ckan {
uwsgi_read_timeout 600s;
uwsgi_send_timeout 600s;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/ckan.sock;
# Cache stuff
uwsgi_cache ckan;
uwsgi_cache_methods GET HEAD;
uwsgi_cache_bypass $cookie_auth_tkt;
uwsgi_no_cache $cookie_auth_tkt;
uwsgi_cache_valid 30m;
uwsgi_cache_key $host$scheme$proxy_host$request_uri;
}
}
Создадим папку под кэш:
sudo mkdir /var/lib/nginx/cache
sudo chown nginx:nginx /var/lib/nginx/cache
Запускаем Nginx:
sudo systemctl start nginx
sudo systemctl enable nginx
Предупреждение
Если приложение при попытке его открыть возвращает 502 Bad Gateway
,
а в логах Nginx
connect() to unix:/run/uwsgi/ckan.sock failed (13: Permission denied)
,
то причина в SELinux - либо настройте его, либо отключите.
15.2.13. Развёртывание DataPusher¶
sudo cp /usr/lib/ckan/datapusher/src/datapusher/deployment/datapusher.wsgi /etc/ckan/
sudo cp /usr/lib/ckan/datapusher/src/datapusher/deployment/datapusher_settings.py /etc/ckan/
sudo chown ckan:ckan /etc/ckan/datapusher.wsgi
sudo chown ckan:ckan /etc/ckan/datapusher_settings.py
В файле datapusher_settings.py
допишите строку:
MAX_CONTENT_LENGTH = 1073741824
Подготавливаем uWSGI:
sudo touch /etc/uwsgi.d/datapusher.ini
sudo chown uwsgi:uwsgi /etc/uwsgi.d/datapusher.ini
sudo touch /var/log/uwsgi/datapusher.log
sudo chown uwsgi:uwsgi /var/log/uwsgi/datapusher.log
В файл datapusher.ini
помещаем следующее содержимое:
[uwsgi]
plugins = python
master = true
workers = 1
threads = 5
no-orphans = true
pidfile = /run/uwsgi/%n.pid
http-socket = 127.0.0.1:8800
logto = /var/log/uwsgi/%n.log
log-date = true
harakiri = 6000
wsgi-file = /etc/ckan/datapusher.wsgi
15.2.14. Установка расширения ckanext-geoview¶
Данное расширение предоставляет набор плагинов, позволяющих осуществлять предпросмотр опубликованных ресурсов прямо в браузере.
Оригинальная версия данного расширения не содержит некоторых нужных нам возможностей, поэтому была выполнена его доработка. В связи с этим устанавливать его мы будем из собственного репозитория:
sudo su -s /bin/bash - ckan
. default/bin/activate
cd default/src
git clone https://github.com/nextgis/ckanext-geoview.git
pip install -e ./ckanext-geoview
Изменим стандартную подложку, для этого в файл development.ini
добавим
следующие строки:
# Settings for ckanext-geoview extension
ckanext.spatial.common_map.type = custom
ckanext.spatial.common_map.custom.url = http://tiles.maps.sputnik.ru/{z}/{x}/{y}.png
ckanext.spatial.common_map.custom.name = Карта Спутник
ckanext.spatial.common_map.attribution = © <a href="http://sputnik.ru">Спутник</a> | © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>
15.2.15. Исправление текущего кода CKAN¶
В последующих релизах эти ошибки будут устранены, но пока они не выпущены, то приходится модифицировать код самостоятельно. Это необходимо сделать в соответствии со следующими коммитами: #9cf0369, #a63de1b, #a76da0c.
15.2.16. Исправления текущего кода DataStore и DataPusher¶
Откроем файл commas.py
:
cd /usr/lib/ckan/datapusher/lib/python2.7/site-packages/messytables
nano commas.py
И отредактируем следующую строку. Вместо:
# Fix the maximum field size to something a little larger
csv.field_size_limit(256000)
должно быть:
# Fix the maximum field size to something a little larger
csv.field_size_limit(100 * 1024 * 1024)
На данный момент в CKAN DataStore нет возможности исключить поле из
индекса на основе его имени,
см. #2837, поэтому
(как временное решение) отключим текстовые поля для индексации.
В противном случае DataStore пытается построить индекс для поля
с WKT геометрией (если такое поле есть в CSV) и падает.
Откроем файл helpers.py
:
cd /usr/lib/ckan/default/src/ckan/ckanext/datastore
nano helpers.py
И отредактируем следующий фрагмент. Вместо:
def should_fts_index_field_type(field_type):
return field_type.lower() in ['tsvector', 'text', 'number']
должно быть:
def should_fts_index_field_type(field_type):
return field_type.lower() in ['tsvector', 'number']
Сделаем ещё одно исправление для отключения включения WKT в
полнотекстовый поиск. Откроем файл db.py
:
cd /usr/lib/ckan/default/src/ckan/ckanext/datastore
nano db.py
И отредактируем функцию _to_full_text
:
def _to_full_text(fields, record):
full_text = []
ft_types = ['int8', 'int4', 'int2', 'float4', 'float8', 'date', 'time',
'timetz', 'timestamp', 'numeric', 'text']
for field in fields:
value = record.get(field['id'])
if not value:
continue
if 'POINT' in unicode(value) or \
'LINESTRING' in unicode(value) or \
'POLYGON' in unicode(value):
continue
if field['type'].lower() in ft_types and unicode(value):
full_text.append(unicode(value))
else:
full_text.extend(json_get_values(value))
return ' '.join(set(full_text))
Увеличим таймаут в файле jobs.py
:
cd /usr/lib/ckan/datapusher/src/datapusher/datapusher
nano jobs.py
Вместо DOWNLOAD_TIMEOUT = 30
выставьте DOWNLOAD_TIMEOUT = 5 * 60
.
Предупреждение
Проблемы, с которыми мы столкнулись при загрузке CSV в DataStore.
В некоторых полях был текст NULL
, но по первой записи DataStore
определял, что это numeric
, и когда доходил до NULL
- падал.
В некоторых полях в качестве разделителя разрядов была ,
.
Исправляется путём редактирования соответствующих ресурсов NextGIS Web.
При загрузке данных всегда сверяйте количество загруженных объектов и фактическое количество объектов в слое. Количество объектов в слое можно получить по API (подставьте свой идентификатор ресурса):
http://82.162.194.216/ngw/api/resource/167/feature_count
15.2.17. Открытие портов¶
Откроем 80
порт:
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
sudo firewall-cmd --reload
Если с локального хоста CKAN недоступен по своему публичному адресу, то это может быть исправлено, например, так:
sudo firewall-cmd --direct --add-rule ipv4 nat OUTPUT 0 -d 82.162.194.216 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:80 --permanent
sudo firewall-cmd --reload
15.2.18. Backup и Restore¶
Данные процедуры описаны в разделе db: Manage databases официальной документации.
Если CKAN и NextGIS Web были развёрнуты на одной машине, то при переносе этой связки на другой адрес, необходимо изменить адреса ресурсов NextGIS Web на новые. Проще всего это сделать, отредактировав файл с бэкапом CKAN до момента его восставновления, например:
sed -i 's:78.46.100.76/opendata_ngw:82.162.194.216/ngw:g' ckan.pg_dump
Если вы используете DataStore, то помимо переноса базы самого CKAN,
необходимо переносить и базу данных DataStore, datastore_default
в нашем случае.
Предупреждение
Если после восстановления данных из архива отображается, что
число наборов данных равно 0
, то поможет
переиндексация.
15.2.19. Дополнительно¶
Конфигурационный файл uWSGI для NextGIS Web:
[uwsgi]
plugins = python
lazy-apps = true
master = true
workers = 4
no-orphans = true
pidfile = /run/uwsgi/%n.pid
socket = /run/uwsgi/%n.sock
chmod-socket = 666
logto = /var/log/uwsgi/%n.log
log-date = true
limit-post = 7516192768
harakiri = 6000
socket-timeout = 6000
env = PASTE_CONFIG=/opt/ngw/development.ini
env = LANG=ru_RU.UTF-8
home = /opt/ngw/env
mount = /ngw=/opt/ngw/nextgisweb/nextgisweb/uwsgiapp.py
manage-script-name = true
Конфигурационный файл Nginx:
uwsgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=ckan:30m max_size=250m;
uwsgi_cache_path /mnt/portal/ngw/cache levels=1:2 keys_zone=ngw:30m max_size=10g inactive=7d;
server {
listen 80;
server_name 82.162.194.216;
client_max_body_size 6G;
large_client_header_buffers 8 32k;
location /ckan {
uwsgi_read_timeout 600s;
uwsgi_send_timeout 600s;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/ckan.sock;
# Cache stuff
uwsgi_cache ckan;
uwsgi_cache_methods GET HEAD;
uwsgi_cache_bypass $cookie_auth_tkt;
uwsgi_no_cache $cookie_auth_tkt;
uwsgi_cache_valid 30m;
uwsgi_cache_key $host$scheme$proxy_host$request_uri;
}
location /ngw {
uwsgi_read_timeout 600s;
uwsgi_send_timeout 600s;
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/ngw.sock;
# Cache stuff
uwsgi_cache ngw;
uwsgi_cache_methods GET HEAD;
uwsgi_cache_bypass $cookie_tkt;
uwsgi_no_cache $cookie_tkt;
uwsgi_cache_valid 7d;
uwsgi_ignore_headers Expires Cache-Control Set-Cookie;
uwsgi_cache_key $host$scheme$proxy_host$request_uri;
add_header X-uWSGI-Cache $upstream_cache_status;
}
location /opendata_map {
index index.html index.htm;
root /var/www;
}
}
Пример удаления записей из кэша Nginx по маске:
grep -lr 'ngw/api/resource/604*' /mnt/portal/ngw/cache/* | xargs rm -rf