-
Notifications
You must be signed in to change notification settings - Fork 11
Production Environment
↑ Parent: More
← Previous: Migrate from MagiCircles1 to MagiCircles2
- Ensure that the following Website settings are properly set:
- The following Website settings are not required, but highly recommended:
-
CORNER_POPUP_IMAGE
-
DONATE_IMAGE
-
DONATORS_STATUS_CHOICES
-
ABOUT_PHOTO
-
HASHTAGS
-
- Check that you don't have any polluting file in your static files folder
- Generate your flaticons here and add the following to the root of the static folder:
-
apple-touch-icon.png
-
favicon-16x16.png
-
favicon-32x32.png
-
favicon.ico
-
safari-pinned-tab.svg
-
- The following images are set up:
-
avatar.png
,game.png
,404.png
,500.png
,403.png
- Banner for users birthdays (
birthday.png
) - Talking character in the corner (
CORNER_POPUP_IMAGE
andCORNER_POPUP_IMAGE_OVERFLOW
)
-
- Populate default staff configurations in
${PROJECT}/management/commands/populate_staffconfigurations_${PROJECT}.py
from django.core.management.base import BaseCommand from magi.management.commands.populate_staffconfigurations import create from magi import models as magi_models class Command(BaseCommand): can_import_settings = True def handle(self, *args, **options): # Set up defaults for existing configurations magi_models.StaffConfiguration.objects.filter(key='about_image').update(value='about.png') magi_models.StaffConfiguration.objects.filter(key='about_the_website', i_language='en').update(value=""" """) magi_models.StaffConfiguration.objects.filter(key='about_us', i_language='en').update(value=""" """)
- Link translations POEditor → GitHub
- Commit empty files for all languages:
NEWLANGS='es zh_Hans ru it fr de pl ja kr id vi zh_Hant pt pt_BR tr uk' for lang in $NEWLANGS; do mkdir -p $PROJECT/locale/$lang/LC_MESSAGES/ && touch $PROJECT/locale/$lang/LC_MESSAGES/django.po; done for lang in $NEWLANGS; do git add $PROJECT/locale/$lang/LC_MESSAGES/django.po; done git commit -m "Add new language(s) $NEWLANGS"
- Go to POEditor setup page
- For each language, link with POEditor:
Make sure you check the box "Also get a .mo file with the same filename on export."
- Commit empty files for all languages:
- Set up
contact@
email address:- Go to Gandi domains and add a forwarding address to all the managers + users who do "support"
- Go to SES and verify the email address
- Edit
${PROJECT}_project/settings.py
to set theAWS_SES_RETURN_PATH
- Edit
${PROJECT}/settings.py
to set theCONTACT_EMAIL
- All managers + users who do support should set up their Gmail to send from the contact address:
- In the top right, click ⚙️ and then Settings.
- Click the Accounts and import tab.
- In the "Send mail as" section, click Add another email address.
- In
Name
set{username} from {site} staff
(example:db0 from Bandori Party staff
) - In address put
contact@{domain}
(example:contact@bandori.party
) - Check "Treat as an alias"
- For SMTP Server, put
smtp.gmail.com
- For Username, your full Gmail address including @gmail.com
- For password, provide an App Password generated in Google Accounts from here (for app select "Other (custom name)")
- Leave Secured connection using TLS selected as is.
- Make sure to test that everyone receives the email and can set from the email
ℹ️ This guide assumes you're using EC2, RDS, SES, Cloudflare and TinyPNG. You may need to do things differently if you want a different setup.
ℹ️ This guide can be used when a website is launched for the first time or when it's migrated to a different instance (different size for example). It can be used for a new EC2 instance or an existing EC2 instance used for other Circles websites.
ℹ️ This guide uses emacs, but any editor works. If you use emacs, you may want to M-x electric-indent-mode
before copy-pasting anything.
-
Go to the EC2 console and create your instance with ubuntu server.
-
Use ssh to connect to your instance.
ssh -i your_key.pem ubuntu@ec2-somethingsomething.compute-1.amazonaws.com
-
Set up your local environment variable corresponding to your project. See step 2 of Local setup.
-
Work in a screen to be able to come back later + set some aliases:
screen -S ${PROJECT} alias pm='python manage.py'
-
Install / update local packages:
sudo apt-get update sudo apt-get install git emacs mysql-client gcc nginx python-dev virtualenv uwsgi uwsgi-plugin-python libjpeg-dev libjpeg8-dev sudo apt-get install -f sudo apt-get autoremove
-
Clone and configure the repository:
git clone https://github.com/MagiCircles/${REPO}.git cd ${REPO}
-
Create a virtual environment to isolate the package dependencies locally and install packages:
virtualenv --python=`which python2` env source env/bin/activate pip install pip==9.0.1 pip install -r requirements.txt && pip install --no-deps django-ses==1.0.2 && pip install boto3
-
Configure NGINX:
sudo emacs /etc/nginx/sites-enabled/default
Copy-paste the following:
server { listen 80; listen [::]:80 default_server ipv6only=on; server_name your.domain; client_max_body_size 500M; charset utf-8; root /dev/null; location /favicon.ico { alias /home/ubuntu/RepoName/shortname/static/img/favicon.ico; } location / { include uwsgi_params; uwsgi_pass_header Server; uwsgi_param Host $http_host; uwsgi_intercept_errors off; uwsgi_param X-Real-IP $remote_addr; uwsgi_param X-Scheme $scheme; uwsgi_connect_timeout 20; uwsgi_read_timeout 300; uwsgi_pass 127.0.0.1:12345; add_header Cache-Control private; } }
After copy-pasting, you'll need to replace the following terms:
-
your.domain
with your domain name, such asbandori.party
-
12345
with the port you want to use -
RepoName
with the name of the repo (example:BanGDream
) -
shortname
with the short name of the project (example:bang
)
-
-
Configure uWSGI:
sudo emacs /etc/uwsgi/apps-enabled/${PROJECT}.ini
Copy-paste the following:
[uwsgi] chdir=/home/ubuntu/RepoName/ home=/home/ubuntu/RepoName/env/ module=shortname_project.wsgi:application master=True env=DJANGO_SETTINGS_MODULE=shortname_project.settings max-requests=300 socket = 127.0.0.1:12345 protocol=uwsgi harakiri=30 processes=4 lazy-apps=True queue=200 listen=128 buffer-size=7000 plugins=python
After copy-pasting, you'll need to replace the following terms:
-
12345
with the port you want to use -
RepoName
with the name of the repo (example:BanGDream
) -
shortname
with the short name of the project (example:bang
)
-
-
Delete any polluting file accidentally created by emacs:
sudo rm /etc/nginx/sites-enabled/default~ /etc/uwsgi/apps-enabled/${PROJECT}.ini~
-
Configure your website:
emacs ${PROJECT}_project/local_settings.py
Copy-paste the following:
STATIC_FILES_VERSION = '0' CONN_MAX_AGE = 100 import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) DEBUG = False STATIC_UPLOADED_FILES_PREFIX = 'u/' STATIC_URL = '//i.your.domain/static/' SECRET_KEY = 'secretkey' ALLOWED_HOSTS = ['your.domain'] DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' AWS_ACCESS_KEY_ID = 'aws_key' AWS_SECRET_ACCESS_KEY = 'aws_secret' AWS_STORAGE_BUCKET_NAME = 'i.your.domain' from boto.s3.connection import OrdinaryCallingFormat AWS_S3_CALLING_FORMAT = OrdinaryCallingFormat() EMAIL_BACKEND = 'django_ses.SESBackend' AWS_SES_REGION_NAME = 'aws_region' AWS_SES_REGION_ENDPOINT = 'email.aws_region.amazonaws.com' SERVER_EMAIL = 'emails-log@schoolido.lu' TINYPNG_API_KEY = 'tinpng_key' GITHUB_API_KEY = 'github_key' TWITTER_API_KEY = 'twitter_api_key' TWITTER_API_SECRET = 'twitter_api_secret' RECAPTCHA_PRIVATE_KEY = 'recaptcha_private_key' RECAPTCHA_PUBLIC_KEY = 'recaptcha_public_key' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'shortname', 'OPTIONS': {'charset': 'utf8mb4'}, 'USER': 'db_username', 'PASSWORD': 'db_password', 'HOST': 'db_host', 'PORT': '3306', } } LOGGING = { 'disable_existing_loggers': False, 'version': 1, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'level': 'DEBUG', }, 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler' }, }, 'loggers': { '': { 'handlers': ['console', 'mail_admins'], 'level': 'DEBUG', 'propagate': False, }, 'django.request': { 'handlers': ['console', 'mail_admins'], 'level': 'DEBUG', 'propagate': True, }, 'django.db.backends.mysql': { 'handlers': ['console', 'mail_admins'], 'level': 'DEBUG', }, 'django.db': { 'handlers': ['mail_admins'], 'level': 'DEBUG', }, }, }
After copy-pasting, you'll need to replace the following terms:
-
your.domain
with your domain name, such asbandori.party
-
secretkey
with a secret key which you can generate here -
aws_key
andaws_secret
with your AWS key and secret -
aws_region
with the AWS region you use (example:us-east-1
) -
tinpng_key
with your TinyPNG developer key -
github_key
with a GitHub token (can be retrieved here) - 'twitter_api_key' with a Twitter API key (A Twitter developer account is required, see here)
- twitter_api_secret' (A Twitter developer account is required, see here)
- 'recaptcha_private_key' (can be retrieved here)
- 'recaptcha_public_key' (can be retrieved here)
-
shortname
with the short name of the project (example:bang
) -
db_username
with the database username you configured on RDS -
db_password
with your database password -
db_host
with your RDS host (example: something.abcdfefhr.us-east-1.rds.amazonaws.com)
-
-
Install MySQL client:
sudo apt-get install libmysqlclient-dev pip install mysql-python
-
[Only if it's a new EC2 instance]
*Assuming you have a security group configured in AWS
-
Go to EC2 instance and change security group to the security group (right click / networking / change security group)
-
Go to the security group and add mysql inbound with server ip
-
Test if it worked:
mysql -h something.abcdfefhr.us-east-1.rds.amazonaws.com -u root -p
-
-
[Only if it's the first time a website is launched]
-
Create the database:
Replace
shortname
with the short name of the project (example:bang
):CREATE DATABASE shortname CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
Initialize the database:
pm migrate
-
Add an index on users page default ordering:
mysql -h something.abcdfefhr.us-east-1.rds.amazonaws.com -u root -p
Replace
shortname
with the short name of the project (example:bang
):USE shortname; CREATE INDEX manual_auth_user_date_joined ON auth_user (date_joined);
-
Configure Cloudflare domain to point to the server IP.
Add a new record of type "A" with name
your.domain
and value the IP of the server.Configure important settings on CloudFlare:
- Caching / Browser Cache Expiration / 1 year - SSL/TLS / Edge Certificates / Always Use HTTPS / On
-
Create a new S3 bucket with the name
i.your.domain
whereyour.domain
is your domain name, such asbandori.party
-
Unselect all options that block public access.
-
After creating the bucket, go to "Permissions" then "CORS configuration" and change to the following:
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>HEAD</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <ExposeHeader>Content-Length</ExposeHeader> <AllowedHeader>Authorization</AllowedHeader> </CORSRule> </CORSConfiguration>
If it asks for JSON:
[ { "AllowedHeaders": [ "Authorization" ], "AllowedMethods": [ "GET", "HEAD", "POST" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [ "Content-Length" ], "MaxAgeSeconds": 3000 } ]
-
-
Generate the static files and upload them to the newly created S3 instance. This needs to be done on your local instance on your own computer. If you don't have one, follow Local setup.
pm generate_css emacs ${PROJECT}_project/local_settings.py # ↑ add: STATIC_ROOT = 'collected' python manage.py collectstatic find . -name '.DS_Store' -type f -delete # Delete files created by OS X rm -r collected/uploaded # Delete uploaded files meant for tests
Upload the content of the
collected
folder to the new S3 bucket in a folder calledstatic
.*All further commands will be once again on the production server, unless specified.
-
-
Configure the static domain on Cloudflare to point to the URL of the S3 bucket.
Add a new record with type "CNAME", name "i" and target the full URL of the S3 bucket (`i.your.domain.s3.amazonaws.com`).
-
Perform some website commands to create some required local files:
pm generate_settings pm latlong
-
Test if the website works on the production server:
pm runserver
-
If Staff configurations are enabled, populate the staff configurations:
pm populate_staffconfigurations
-
Load the configurations:
sudo /etc/init.d/nginx restart sudo service uwsgi restart
-
[Only if a site is moved to a different instance]
-
Configure Cloudflare domain to point to the new server IP.
-
Check that the traffic goes to the new instance:
sudo tail -n 100 -f /var/log/uwsgi/app/${PROJECT}.log
-
-
Try to access your new website to see if everything worked!
-
Set up cron jobs to:
- Check for images that need to be compressed and markdown that need to be rendered to HTML every minute (cron that acts like a queue)
- Send email for unread notifications, every 2 hours
- Generate the map with locations of the users, every day at midnight
- Generate settings, every day at midnight
- Reload the website with the new generated settings, every day at midnight + 10 minutes
crontab -e
# RepoName * * * * * /home/ubuntu/RepoName/env/bin/python /home/ubuntu/RepoName/manage.py async_db_updates >> /home/ubuntu/RepoName/async_cronjob.log 2>&1 0 */2 * * * /home/ubuntu/RepoName/env/bin/python /home/ubuntu/RepoName/manage.py cron_notifications >> /home/ubuntu/RepoName/cronjob.log 2>&1 0 0 * * * /home/ubuntu/RepoName/env/bin/python /home/ubuntu/RepoName/manage.py generate_settings >> /home/ubuntu/RepoName/settings_cronjob.log 2>&1 0 0 1 * * rm /home/ubuntu/RepoName/cronjob.log /home/ubuntu/RepoName/async_cronjob.log /home/ubuntu/RepoName/settings_cronjob.log # All sites 0 0 * * 0 sudo rm /tmp/tmp* 10 0 * * * root service uwsgi reload
After copy-pasting, you'll need to replace the following terms:
-
RepoName
with the name of the repo (example:BanGDream
)
If you have multiple websites on the same EC2 instance, the last line only needs to be here once for all the website.
-
Update this page to change the details of the "Current setup" section below.
-
Done!
- Add the site to
raw.py
in MagiCircles repository - Edit the Patreon page to add the new site
- Add to rewards
- Add to milestones
# Updating a site
pip install -r requirements.txt --upgrade && pip install --no-deps django-ses==1.0.2 && pip install boto3
git pull
# Update static files version
emacs ${PROJECT}_project/local_settings.py
# Reload a site after updating
sudo service uwsgi reload ${PROJECT}
# Check incoming requests log (uwsgi level)
sudo tail -n 100 -f /var/log/uwsgi/app/${PROJECT}.log
# Check incoming requests log (nginx level)
sudo tail -f /var/log/nginx/access.log
# Check asynchronous log
tail -n 2000 -f async_cronjob.log | \grep Info
# Connect to prod MySQL server from local computer through a prod server tunnel
# DB_HOST = your RDS host (example: something.abcdfefhr.us-east-1.rds.amazonaws.com)
# SERVER_HOST = ec2-somethingsomething.compute-1.amazonaws.com
ssh -i PEM_FILE_HERE -N -L 3306:DB_HOST:3306 ubuntu@SERVER_HOST
mysql -u root -p -h 127.0.0.1
- Local:
pm generate_css
- S3: upload generated CSS
- S3: Check if the Javascript files for MagiCircles have been updated, upload them again if needed
- S3: Check if the Javascript files for the site have been updated, upload them again if needed
- S3: Check if new images have been added or updated for MagiCircles, upload them
- S3: Check if new images have been added or updated for the site, upload them
- Prod server:
pip install -r requirements.txt --upgrade && pip install --no-deps django-ses==1.0.2 && pip install boto3
- Prod server:
git pull
- Prod server: Update
${PROJECT}_project/local_settings.py
to update theSTATIC_FILES_VERSION
- Prod server:
pm migrate
- Prod server:
pm generate_settings
- Prod server:
sudo service uwsgi reload ${PROJECT}
- Prod server:
sudo tail -n 100 -f /var/log/uwsgi/app/${PROJECT}.log
Domain | Server code name | Size | Region | MagiCircles version |
---|---|---|---|---|
bandori.party | kasumi | t2.large | us-east-1d | 2 |
bandori.org | kasumi | t2.large | us-east-1d | 2 |
starlight.academy | ichie | t2.large | us-east-1b | 2 |
idol.st | ichie | t2.large | us-east-1b | 2 |
schoolido.lu | ichie | t2.large | us-east-1b | N/A |
cinderella.pro | layla | t2.small | us-east-1b | 1 |
frgl.db0.company | layla | t2.small | us-east-1b | 0 |
stardust.run | layla | t2.small | us-east-1b | 1 |
maji.love | layla | t2.small | us-east-1b | 2 |
shiny.schoolido.lu | layla | t2.small | us-east-1b | 2 |
ac.db0.company | layla | t2.small | us-east-1b | 2 |
starlet.db0.company | layla | t2.small | us-east-1b | 2 |
All buckets are in US East (N. Virginia).
Domain | Storage used |
---|---|
i.bandori.party | 131.7G |
i.idol.st | 89.2G |
i.schoolido.lu | 32.4G |
i.cinderella.pro | 5.0G |
i.starlight.academy | 4.6G |
i-frgl.db0.company | 1.2G |
i-starlet.db0.company | 922.7M |
i-ac.db0.company | 406.2M |
i.stardust.run | 52.1M |
i.maji.love | 29.5M |
DB name | DB Size |
---|---|
schoolidolapi | 4.6G |
bang | 1.7G |
cpro | 280M |
idolstory | 257M |
stardustrun | 120M |
starlight | 52M |
starlet | 24M |
frgl | 11M |
ac | 3M |
majilove | 3M |
sukutomo | 1M |
→ Next: Flaticon
screen -S schoolidolu
alias pm='python manage.py'
git clone https://github.com/MagiCircles/SchoolIdolAPI.git
cd SchoolIdolAPI
virtualenv env
source env/bin/activate
pip install pip==9.0.1
pip install -r requirements.txt
pip install --no-deps django-ses==1.0.2
pip install boto3
pip install mysql-python
sudo emacs /etc/nginx/sites-enabled/default
server {
listen 80;
server_name schoolido.lu www.schoolido.lu;
client_max_body_size 500M;
root /dev/null;
location /favicon.ico {
alias /home/ubuntu/SchoolIdolAPI/web/static/favicon.ico;
}
location /robots.txt {
alias /home/ubuntu/SchoolIdolAPI/web/static/robots.txt;
}
location /contest/ {
if ($http_user_agent = "") { return 403; }
if ($http_user_agent = "python-requests") { return 403; }
if ($http_user_agent = "python-requests/2.10.0") { return 403; }
include uwsgi_params;
uwsgi_pass_header Server;
uwsgi_param Host $http_host;
uwsgi_intercept_errors off;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Scheme $scheme;
uwsgi_connect_timeout 20;
uwsgi_read_timeout 300;
uwsgi_pass 127.0.0.1:12346;
add_header Cache-Control private;
}
location / {
include uwsgi_params;
uwsgi_pass_header Server;
uwsgi_param Host $http_host;
uwsgi_intercept_errors off;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Scheme $scheme;
uwsgi_connect_timeout 20;
uwsgi_read_timeout 300;
uwsgi_pass 127.0.0.1:12346;
add_header Cache-Control private;
}
location /static/ {
root /home/ubuntu/SchoolIdolAPI/web/;
}
location /contest/static/ {
alias /home/ubuntu/SchoolIdolContest/schoolidolcontest/static/;
autoindex on;
}
}
sudo emacs /etc/uwsgi/apps-enabled/schoolidolu.ini
[uwsgi]
chdir=/home/ubuntu/SchoolIdolAPI/
home=/home/ubuntu/SchoolIdolAPI/env/
module=schoolidolapi.wsgi:application
master=True
env=DJANGO_SETTINGS_MODULE=schoolidolapi.settings
max-requests=1200
socket = 127.0.0.1:12346
protocol=uwsgi
harakiri=60
processes=6
lazy-apps=True
queue=900
listen=128
buffer-size=9000
plugins=python
sudo rm /etc/nginx/sites-enabled/default~ /etc/uwsgi/apps-enabled/schoolidolu.ini~
scp EXISTING_LOCAL_SETTINGS.py NEWSERVER:schoolidolapi/local_settings.py
pm generate_settings
pm latlong
# Test:
pm runserver
crontab -e
# Schoolido.lu
0 */2 * * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py cron_notifications >> /home/ubuntu/cronjob.log 2>&1
# 0 * * * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py drown_negativity >> /home/ubuntu/cronjob.log 2>&1
0 0 * * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py latlong >> /home/ubuntu/latlong_cronjob.log 2>&1
0 0 * * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py update_cards_owners >> /home/ubuntu/cronjob.log 2>&1
0 0 * * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py update_accounts_rankings >> /home/ubuntu/cronjob.log 2>&1
0 0 * * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py generate_settings >> /home/ubuntu/settings_cronjob.log 2>&1
0 0 1 * * /home/ubuntu/SchoolIdolAPI/env/bin/python /home/ubuntu/SchoolIdolAPI/manage.py update_cards_join_cache >> /home/ubuntu/update_cards_join_cache.log 2>&1
0 0 1 * * rm -f /home/ubuntu/cronjob.log /home/ubuntu/latlong_cronjob.log /home/ubuntu/settings_cronjob.log /home/ubuntu/update_cards_join_cache.log
# Reload:
sudo /etc/init.d/nginx restart
sudo service uwsgi restart
# Update Cloudflare then check for traffic:
sudo tail -n 100 -f /var/log/uwsgi/app/schoolidolu.log
screen -S frgl
alias pm='python manage.py'
git clone https://github.com/MagiCircles/frgl.git
cd frgl
virtualenv env
source env/bin/activate
pip install pip==9.0.1
pip install -r requirements.txt
sudo emacs /etc/nginx/sites-enabled/default
# EITHER
npm install -g bower
bower install
# OR
scp -r frgl/web/static/bower NEWSERVER:frgl/web/static/
# EITHER
lessc frgl/web/static/less/style.less frgl/web/static/css/style.css
# OR
scp frgl/web/static/css/style.css NEWSERVER:frgl/web/static/css/style.css
server {
listen 80;
server_name fr.gl frgl.db0.company;
location / {
include uwsgi_params;
uwsgi_pass_header Server;
uwsgi_param Host $http_host;
uwsgi_intercept_errors off;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Scheme $scheme;
uwsgi_connect_timeout 20;
uwsgi_read_timeout 20;
uwsgi_pass 127.0.0.1:12347;
add_header Cache-Control private;
}
location /static/ {
root /home/ubuntu/frgl/web/;
}
}
sudo emacs /etc/uwsgi/apps-enabled/frgl.ini
[uwsgi]
chdir=/home/ubuntu/frgl/
home=/home/ubuntu/frgl/env/
module=frgl.wsgi:application
master=True
env=DJANGO_SETTINGS_MODULE=frgl.settings
vacuum=True
max-requests=5000
socket = 127.0.0.1:12347
protocol=uwsgi
harakiri=15
processes=2
sudo rm /etc/nginx/sites-enabled/default~ /etc/uwsgi/apps-enabled/frgl.ini~
scp EXISTING_LOCAL_SETTINGS.py NEWSERVER:schoolidolapi/local_settings.py
# Test:
pm runserver
I. Introduction
II. Tutorials
III. References
- Files tree
- Default collections
- Default pages
- Website settings
- MagiCollection settings
- Abstract models
- Abstract collections
- MagiForm settings
- MagiFiltersForm settings
- Single pages settings
IV. Utils
-
MagiModel utils
- MagiModel images and files
- DateTime fields
- BaseAccount model
- Save choices values as integer rather than strings
- Store comma separated values
- Store dictionaries
- Store Markdown texts
- Translate fields values in multiple languages
- Store JSON
- More model field types
- Transform images before saving them
- Check choices at form level instead of model level
- Use an internal cache for foreign keys in models
- Customize views with MagiModel properties
- Events
- Form utils
- Python utils
- Templates utils
- Javascript utils
- Enable and disable existing collections and pages
- Translations
- Page titles and descriptions
- Characters
- Seasons
- Roles and permissions
- Allow your staff team to change configurations
- Custom users preferences and settings
- Background illustrations
- Activities tabs
- Corner popups
VI. More