Table of Contents
KingCon 4.0 - Neues Event aufsetzen
Variables
{PROJECT_NAME} : eec
{DOMAIN} : event.eec-2024.com
{DOMAIN_SLUG} : event-eec-2024-com
{WEBSITE_TITLE} : EEC (European Electric Steelmaking)
{EMAIL} : event@mail.eec-2024.com
{EMAIL_SERVER} : srv03.tema-hosting.de
{EMAIL_PASS} : ***
{NODE_PORT} : 15165
{PROJECT_NAME_TO_COPY_FROM} : startup-the-future
{NEXT_FREE_REDIS_INSTANCE_ID_FOR_CELERY} : 5
{NEXT_FREE_REDIS_INSTANCE_ID_FOR_CACHING} : 6
<note important>Everywhere these placeholders are used, they need to be replaced with the variable content</note>
Prepare new Event
1. Log in to the server as root
ssh root@193.254.190.30 -p 12035
enter password, if prompted
2. Setup domain in nginx
cd /etc/nginx/conf.d
nano {PROJECT_NAME}.conf
Enter the following, and save the file:
server {
listen 80;
listen [::]:80;
server_name {DOMAIN} ;
location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}
location / {
return 301 https://{DOMAIN}$request_uri;
}
}
Check if your config is valid:
nginx -t
should return
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
restart nginx
service nginx reload
3. Get Let's Encrypt certificates
create directory for certificates
mkdir /etc/ssl/{PROJECT_NAME}
chown root:www-data /etc/ssl/{PROJECT_NAME}
chmod -R 755 /etc/ssl/{PROJECT_NAME}
acme.sh --issue -w /var/www/letsencrypt -d {DOMAIN} --keylength ec-384 --key-file /etc/ssl/{PROJECT_NAME}/{DOMAIN_SLUG}.key --fullchain-file /etc/ssl/{PROJECT_NAME}/{DOMAIN_SLUG}.crt --reloadcmd "systemctl reload nginx"
Should end with
[...] Installing key to: /etc/ssl/{PROJECT_NAME}/{DOMAIN_SLUG}.key
[...] Installing full chain to: /etc/ssl/{PROJECT_NAME}/{DOMAIN_SLUG}.crt
[...] Run reload cmd: systemctl reload nginx
[...] Reload success
4. Generate dhparams
openssl dhparam -out /etc/ssl/{PROJECT_NAME}/ffdhe4096 4096
5. Setup uWSGI for KingCon 4.0
create new wsgi config
nano /etc/uwsgi-{PROJECT_NAME}.ini
[uwsgi]
uid = {PROJECT_NAME}
gid = nginx
umask = 027
processes = 4
enable-threads = true
chmod-socket = 770
chown-socket = {PROJECT_NAME}:nginx
socket = /opt/{PROJECT_NAME}/web/uwsgi.sock
stats = /opt/{PROJECT_NAME}/web/uwsgi-stats.sock
protocol = uwsgi
master = true
auto-procname = true
procname-prefix-spaced = {PROJECT_NAME}
disable-logging = true
single-interpreter = true
touch-reload = /opt/{PROJECT_NAME}/web/indico.wsgi
wsgi-file = /opt/{PROJECT_NAME}/web/indico.wsgi
virtualenv = /opt/{PROJECT_NAME}/.venv
vacuum = true
buffer-size = 20480
memory-report = true
max-requests = 2500
harakiri = 900
harakiri-verbose = true
reload-on-rss = 2048
evil-reload-on-rss = 8192
create Service
nano /etc/systemd/system/{PROJECT_NAME}-uwsgi.service
[Unit]
Description={WEBSITE_TITLE} uWSGI
After=network.target
[Service]
ExecStart=/opt/{PROJECT_NAME}/.venv/bin/uwsgi --ini /etc/uwsgi-{PROJECT_NAME}.ini
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
SyslogIdentifier={PROJECT_NAME}-uwsgi
User={PROJECT_NAME}
Group=nginx
UMask=0027
Type=notify
NotifyAccess=all
KillMode=mixed
KillSignal=SIGQUIT
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
6. Create Celery Service for KingCon 4.0
create Service
nano /etc/systemd/system/{PROJECT_NAME}-celery.service
[Unit]
Description={WEBSITE_TITLE} Celery
After=network.target
[Service]
ExecStart=/opt/{PROJECT_NAME}/.venv/bin/indico celery worker -B
Restart=always
SyslogIdentifier={PROJECT_NAME}-celery
User={PROJECT_NAME}
Group=nginx
UMask=0027
Type=simple
KillMode=mixed
TimeoutStopSec=300
[Install]
WantedBy=multi-user.target
7. Create user and SWITCH to it
useradd -rm -g nginx -d /opt/{PROJECT_NAME} -s /bin/bash {PROJECT_NAME}
su - {PROJECT_NAME}
8. Create virtual env
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
cat >> ~/.bashrc <<'EOF'
export PATH="/opt/{PROJECT_NAME}/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
EOF
source ~/.bashrc
9. Install latest Python 3.9
List the latest available Version of Python 3.9
pyenv install --list | egrep '^\s*3\.9\.'
Install latest version
pyenv install 3.9.x pyenv global 3.9.x
Verify installation worked
python -V
Configuration/Updates/Dependancies
python -m venv --upgrade-deps --prompt kingcon ~/.venv source ~/.venv/bin/activate echo 'source ~/.venv/bin/activate' >> ~/.bashrc pip install wheel pip install uwsgi
10. Create Directories
mkdir ~/archive mkdir ~/cache mkdir ~/container mkdir ~/custom mkdir ~/etc mkdir ~/log mkdir ~/log/nginx mkdir ~/packages mkdir ~/tmp mkdir ~/web chmod go-rwx ~/* ~/.[^.]* chmod 710 ~/ ~/archive ~/cache ~/log ~/tmp chmod 750 ~/web ~/.venv chmod g+w ~/log/nginx
Copy packages + container to server
open a new terminal and switch to your indico development directory
scp -P 12035 -r deployment/docker/indico-base/packages/ root@193.254.190.30:/opt/{PROJECT_NAME}/
Copy custom templates from other event
cp -r /opt/{PROJECT_NAME_TO_COPY_FROM}/custom/* /opt/{PROJECT_NAME}/custom/
chown -R {PROJECT_NAME}:nginx /opt/{PROJECT_NAME}/custom
find /opt/{PROJECT_NAME}/custom -type d -exec chmod 755 {} \;
find /opt/{PROJECT_NAME}/custom -type f -exec chmod 644 {} \;
Setup Database
Execute the following commands to create a new database as root on the server
su - postgres -c 'createuser {PROJECT_NAME}'
su - postgres -c 'createdb -E UTF8 -T template0 -O {PROJECT_NAME} {PROJECT_NAME}'
su - postgres -c 'psql {PROJECT_NAME} -c "CREATE EXTENSION unaccent; CREATE EXTENSION pg_trgm;"'
Install and configure Indico
Go back to the server terminal and log in with the user for the project {PROJECT_NAME}
1. Install Indico
install the latest indico package
pip install -U packages/indico-3.*-py3-none-any.whl
2. Install all Plugins
install the latest default Indico plugins
pip install indico-plugins
install the latest TEMA plugin packages
pip install -U packages/indico_plugin_*-py3-none-any.whl
3. Run setup wizard
indico setup wizard
Please answer everything according to the following script
Enter the base directory where Indico will be installed.
Indico root path: /opt/{PROJECT_NAME}
Indico will use the following directories
/opt/eec/archive *
/opt/eec/cache *
/opt/eec/log *
/opt/eec/tmp *
/opt/eec/etc *
/opt/eec/web *
The directories marked with a * already exist. We strongly recommend installing Indico in a new directory that contains nothing but the Python virtualenv. If you are upgrading from Indico v1.2, please move its data to a different location.
Continue anyway? [y/N]: y
Indico needs to know the URL through which it is accessible. We strongly recommend using an https:// URL and a subdomain, e.g.
https://indico.yourdomain.com
Indico URL: https://{DOMAIN}
Enter the SQLAlchemy connection string to connect to your PostgreSQL database.
For a remote database, use postgresql://user:pass@host/dbname
PostgreSQL database URI: postgresql:///{PROJECT_NAME}
Indico uses Redis to manage scheduled/background tasks. Enter the URL to your
Redis server. Running one locally is usually the easiest option.
Redis URI (celery): redis://127.0.0.1:6379/{NEXT_FREE_REDIS_INSTANCE_ID_FOR_CELERY}
Redis is also used for caching. We recommend using a separate redis database,
which allows you to clear the cache without affecting celery
Redis URI (cache): redis://127.0.0.1:6379/{NEXT_FREE_REDIS_INSTANCE_ID_FOR_CACHING}
The Contact page displays this email address to users. If empty, the Contact
page will be hidden.
Contact email: {EMAIL}
If an error occurs Indico sends an email to the admin address. This should be the address of whoever is the technical manager of this Indico instance, i.e. most likely you.
Admin email: {EMAIL}
When Indico sends email notifications they are usually sent from the noreply email.
No-reply email: {EMAIL}
Indico needs an SMTP server to send emails.
SMTP host: {EMAIL_SERVER}
SMTP port: 25
If your SMTP server requires authentication, enter the username now.
SMTP username: {EMAIL}
SMTP password: ***
SMTP connection failed: [Errno -2] Name or service not known
Keep these settings anyway? [y/N]: y
Specify the default language/locale used by Indico.
Default locale: en_GB
Specify the default timezone used by Indico.
Default timezone: Europe/Berlin
Indico contains a room booking system. If you do not plan to maintain a list
of rooms available in your organization in Indico and use it to book them, it
is recommended to leave the room booking system disabled.
Enable room booking? [y/N]: N
Indico can show important system notices (e.g. about security issues) to
administrators. They are retrieved once a day without sending any data related
to your Indico instance. It is strongly recommended to enable them.
Enable system notices? [Y/n]: y
By creating a symlink to indico.conf in /opt/eec/.indico.conf, you can run
indico without having to set the INDICO_CONFIG environment variable
Create symlink? [Y/n]: Y
Creating /opt/{PROJECT_NAME}/etc/indico.conf
Copying /opt/{PROJECT_NAME}/.venv/lib/python3.9/site-packages/indico/logging.yaml.sample -> /opt/{PROJECT_NAME}/etc/logging.yaml
Linking /opt/{PROJECT_NAME}/web/static -> /opt/{PROJECT_NAME}/.venv/lib/python3.9/site-packages/indico/web/static
Copying /opt/{PROJECT_NAME}/.venv/lib/python3.9/site-packages/indico/web/indico.wsgi -> /opt/{PROJECT_NAME}/web/indico.wsgi
Linking /opt/{PROJECT_NAME}/.indico.conf -> /opt/{PROJECT_NAME}/etc/indico.conf
Indico has been configured successfully!
You can now run indico db prepare to initialize your Indico database
4. Append custom settings to config file
<note important> About locales: for only German use:
DEFAULT_LOCALE = 'de_DE'
CUSTOM_LANGUAGES = {'en_GB': None, 'de_DE': ('Deutsch', '')}
for only English use:
DEFAULT_LOCALE = 'en_GB'
CUSTOM_LANGUAGES = {'en_GB': ('English', ''), 'de_DE': None}
for English and German use:
DEFAULT_LOCALE = 'en_GB'
CUSTOM_LANGUAGES = {'en_GB': ('English', ''), 'de_DE': ('Deutsch', '')}
</note>
# General settings
SQLALCHEMY_DATABASE_URI = 'postgresql:///{PROJECT_NAME}'
SECRET_KEY = b'...'
BASE_URL = 'https://{DOMAIN}'
CELERY_BROKER = 'redis://127.0.0.1:6379/{NEXT_FREE_REDIS_INSTANCE_ID_FOR_CELERY}'
REDIS_CACHE_URL = 'redis://127.0.0.1:6379/{NEXT_FREE_REDIS_INSTANCE_ID_FOR_CACHING}'
DEFAULT_TIMEZONE = 'Europe/Berlin'
DEFAULT_LOCALE = {DEFAULT_LOCALE}
ENABLE_ROOMBOOKING = False
CACHE_DIR = '/opt/{PROJECT_NAME}/cache'
TEMP_DIR = '/opt/{PROJECT_NAME}/tmp'
LOG_DIR = '/opt/{PROJECT_NAME}/log'
STORAGE_BACKENDS = {'default': 'fs:/opt/{PROJECT_NAME}/archive'}
ATTACHMENT_STORAGE = 'default'
STATIC_FILE_METHOD = ('xaccelredirect', {'/opt/{PROJECT_NAME}': '/.xsf/{PROJECT_NAME}'})
# Email settings
SMTP_SERVER = ('{EMAIL_SERVER}', 25)
SMTP_USE_TLS = True
SMTP_LOGIN = '{EMAIL}'
SMTP_PASSWORD = '{EMAIL_PASS}'
SUPPORT_EMAIL = '{EMAIL}'
PUBLIC_SUPPORT_EMAIL = ''
NO_REPLY_EMAIL = '{EMAIL}'
# Plugins
PLUGINS = {'payment_manual','ursh', 'abstract_status', 'tema_theme', 'favicons', 'payment_invoice', 'emails', 'cookies'}
# Customization settings
CUSTOMIZATION_DIR = '/opt/{PROJECT_NAME}/custom'
CUSTOM_LANGUAGES = {CUSTOM_LANGUAGES}
5. Prepare the Database
indico db prepare indico db --all-plugins upgrade
Send HTTPs Traffic to indico instance
1. Create new config to route https traffic
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {DOMAIN};
ssl_certificate /etc/ssl/{PROJECT_NAME}/{DOMAIN_SLUG}.crt;
ssl_certificate_key /etc/ssl/{PROJECT_NAME}/{DOMAIN_SLUG}.key;
ssl_dhparam /etc/ssl/{PROJECT_NAME}/ffdhe4096;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
access_log /opt/{PROJECT_NAME}/log/nginx/access.log combined;
error_log /opt/{PROJECT_NAME}/log/nginx/error.log;
location ^~ /.well-known/acme-challenge {
default_type text/plain;
root /var/www/letsencrypt;
}
location /.xsf/{PROJECT_NAME}/ {
internal;
alias /opt/{PROJECT_NAME}/;
}
location ~ ^/(images|fonts)(.*)/(.+?)(__v[0-9a-f]+)?\.([^.]+)$ {
alias /opt/{PROJECT_NAME}/web/static/$1$2/$3.$5;
access_log off;
}
location ~ ^/(css|dist|images|fonts)/(.*)$ {
alias /opt/{PROJECT_NAME}/web/static/$1/$2;
access_log off;
}
location /robots.txt {
alias /opt/{PROJECT_NAME}/web/static/robots.txt;
access_log off;
}
# disable unwanted indico functions
location ~* ^\/event\/\d+\/registrations\/\d+\/\d+\/avatar {
# disable the avatar, because it could be used to know how many persons are already registered
return 301 /404;
}
# pass new stuff to node app
location ~* ^\/(_next|__nextjs|frontend-assets|404|unauthorized|admin\/(accounting-entities|tax-rates|cookies|invoices)).* {
proxy_pass http://127.0.0.1:{NODE_PORT};
}
# pass invoicing settings to node app
location ~* ^\/event\/\d+\/manage\/(invoicing|invoice|tickets).* {
proxy_pass http://127.0.0.1:{NODE_PORT};
}
# pass event pages to node app
location ~* "^\/event\/\d+(\/registrations|\/timetable){0,1}(\/){0,1}$" {
proxy_pass http://127.0.0.1:{NODE_PORT};
}
# pass public ticket view to node app
location ~* "^\/event\/\d+\/tickets\/[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\- [0-9a-fA-F]{12}$" {
proxy_pass http://127.0.0.1:{NODE_PORT};
}
# pass root url to node app
location = / {
proxy_pass http://127.0.0.1:{NODE_PORT};
}
location / {
root /var/empty/nginx;
include /etc/nginx/uwsgi_params;
uwsgi_pass unix:/opt/{PROJECT_NAME}/web/uwsgi.sock;
uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_read_timeout 15m;
uwsgi_buffers 32 32k;
uwsgi_busy_buffers_size 128k;
uwsgi_hide_header X-Sendfile;
client_max_body_size 1G;
}
}
2. Check that the config is valid
nginx -t
should return
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
3. Restart nginx
service nginx reload
Start Services and create default user
systemctl restart {PROJECT_NAME}-celery.service {PROJECT_NAME}-uwsgi.service
systemctl enable {PROJECT_NAME}-celery.service {PROJECT_NAME}-uwsgi.service
Open
https://{DOMAIN}/bootstrap
in your Browser
Start a container for the node frontend
Wie das Docker-Image für die Node-Anwendung entsteht (und auf den Indico-Server gelangt), steht beispielhaft hier: Node im Container
cd /opt/{PROJECT_NAME}/container
ls -l
Da sollte eine Datei {PROJECT_NAME}-production-DATESTAMP.tar liegen.
docker load < {PROJECT_NAME}-production-{DATESTAMP}.tar
docker image ls
docker container ls
Wir sehen unser geladenes Image. Und wir sehen, dass unser Image noch nicht “läuft”.
docker run -d -p 127.0.0.1:{NODE_PORT}:3000 --restart unless-stopped {PROJECT_NAME}-production
docker container ls
Jetzt sollte
https://{DOMAIN}/
keinen “bad gateway”-Fehler mehr liefern.
Für eine nutzbare Ansicht müssen nun Farben und Bilder in den Theme-Plugins definiert werden.
Siehe https://kingcon-docs.tema-hosting.de/
Unterprojekte
js doku
Neues Projekt anlegen: projekte:kingcon_register-me.org:kingcon_4.0_-_neues_event_aufsetzen