LiCMS (Li Xin (Justin Lee) Content Management System) is a content management system used for blogging, implemented with Flask.
- Python `3.14.0'
- Docker
28.5.2- DataBase depending on deployment method (default in
config.py, can be edited as you wish)- Heroku:
mysql(shifting topostgresql)- Docker:
mysql- Unix:
mysql- Test Env:
sqlite
- LiCMS is an all-in-one content management solution developed with the MVC design pattern, providing usage and management for posts, comments, and users.
- For the front-end, we provide both the
RESTful-APIsolution and website solution (based on Bootstrap). - For the back-end, we provide a Flask and Docker-based, automatic deployed and self-sustained solution with continuous-integration provided by Jenkins or Travis-CI.
- For database management, I used SQLAlchemy to simplify the complex SQL queries into object operations, which provided me with an object-oriented interface for all CRUD operations.
- For continuous integration, I integrated this project with Travis-CI and Jenkins.
- For auto-deploying and self-sustaining, thanks to docker. I achieved these with docker compose and a self-implemented flask CLI extension.
- For Tow Step Verification or 2FA, it's implemented via the
TOTP(Time-based One-time Password) algorithm. - For unexpected errors, LiCMS will email the
LICMS_ADMINconfigured in.env-licms. - For enhanced performance and let python use multiple CPUs, we enabled
gunicornWSGI HTTP server for multiprocessing, it takes (2 * physical_cpus + 1) CPUs by default, (hyper-threadis assumed to be enabled).
- iOS
- iPadOS
- macOS
- Linux
- Windows
- macOS
- Linux
- Unix
- Heroku
- Docker
- Windows (Supported via Docker)
If you would like to deploy LiCMS via other methods, you could refer to this guide
All Contents in the <> should math in each file
Example:
If you replaced<db_host>withexample.comin.env-licms, you should replace<db_host>withexample.comeverywhere.
- First thing first, clone this project.
git clone https://github.com/realJustinLee/LiCMS.git
- First thing first, you should compose a dot-env file named
.env-licms.cat>.env-licms<<EOF DB_USERNAME=<db_username> DB_PASSWORD=<db_password> DB_HOST=<db_host> DB_PORT=<db_port> DB_DATABASE=<db_database> SECRET_KEY=<a_super_strong_key> LICMS_ADMIN=<your@email.com> LICMS_POSTS_PER_PAGE=20 LICMS_USERS_PER_PAGE=50 LICMS_PASTES_PER_PAGE=40 LICMS_COMMENTS_PER_PAGE=30 LICMS_SLOW_DB_QUERY_TIME=0.5 MAIL_SERVER=smtp.googlemail.com MAIL_PORT=587 MAIL_USE_TLS=true MAIL_USERNAME=<your_separate_gmail_account> MAIL_PASSWORD=<your_separate_gmail_application_password> FLASK_APP=app.py FLASK_CONFIG=docker PREFERRED_URL_SCHEME=https EOF
- Then you will need to compose another dot-env file named
.env-mysql.cat>.env-mysql<<EOF MYSQL_RANDOM_ROOT_PASSWORD=yes MYSQL_DATABASE=<db_database> MYSQL_USER=<db_username> MYSQL_PASSWORD=<db_password> EOF
- After words, replace all the
licms.example.comwith your own host likesome-host.someone.com. In the Following file:.conf/nginx/app.confinit_letsencrypt.shplease replace
<your@email.com>in this file with the email you replaced<your@email.com>in.env-licmswith.
- Run the following code to deploy the project.
# install docker-ce for ubuntu ./init_ubuntu_dokcer_ce.sh reboot cd /path/to/LiCMS ./init_letsencrypt.sh ./post_reboot.sh
- POST
https://your.host/api/v1/tokens/with HTTP Basic Auth:Username:<email> Password:<password> - It will return a JSON body with
tokenandexpirationlike this:{ "expiration": 600, "token": "<token>" } - Before the token expires, you could visit other apis with HTTP Basic Auth via the token you requested.
The token takes the place of
Usernameand leavePasswordempty.Username:<token> Password:
If you wanna maintain your own impl of database, or you've altered the db models, you need to do db migrations or db inits.
- DB init:
flask db init
- DB upgrade:
flask db upgrade
- DB migrate:
flask db migrate
If you run LiCMS in development mode, and you would like to fake some users, posts, comments, etc. Do the following.
- First enter
Flask Shell:flask shell
- Fake some dev data
# Import fake form app_core: from app_core import fake # Fake 100 random Users: fake.users(100) # Fake 100 random Users: fake.posts(100) # Fake 100 random Comments for random Posts by random Users: fake.comments(100) # Fake 100 random Follows for random Users followed by random Users: fake.follows(100) # Fake 100 random Pastes by random Users: fake.pastes(100)
- Paste bin for Academic use.
- OAuth Sign In (Sign In with X/Meta/Google/Apple).
- Support for Physical Security Keys.
- User banning/blocking, post banning etc.
Made with ❤ by Justin Lee!
™ and © 1997-2025 Justin Lee. All Rights Reserved. License Agreement
