🐍 Configuring Python Web Applications on Alpine Linux: Complete Guide
Let’s deploy Python web applications on Alpine Linux! 🚀 This comprehensive tutorial shows you how to set up Flask and Django applications with proper WSGI servers, database connections, and production optimizations. Perfect for lightweight, efficient web deployments! 😊
🤔 Why Python on Alpine Linux?
Alpine Linux is perfect for Python web applications! It provides a minimal, secure foundation with excellent performance for containerized and traditional deployments.
Python on Alpine Linux is like:
- 🪶 A lightweight sports car that delivers maximum performance with minimal overhead
- 🔒 A secure foundation that protects your applications from security vulnerabilities
- 💡 An efficient platform that maximizes resource utilization and reduces costs
🎯 What You Need
Before we start, you need:
- ✅ Alpine Linux system with internet access
- ✅ Basic knowledge of Python web development
- ✅ Understanding of web servers and WSGI
- ✅ Familiarity with Flask or Django frameworks
📋 Step 1: Install Python and Web Development Tools
Install Python Environment
Let’s set up a complete Python development environment! 😊
What we’re doing: Installing Python, pip, and essential development tools for web applications.
# Update package list
apk update
# Install Python and essential tools
apk add python3 py3-pip python3-dev
# Install build tools for Python packages
apk add build-base linux-headers
# Install database clients and libraries
apk add postgresql-dev sqlite-dev mariadb-dev
# Verify Python installation
python3 --version
pip3 --version
# Create Python virtual environment
python3 -m venv /opt/webapp-env
source /opt/webapp-env/bin/activate
# Upgrade pip
pip install --upgrade pip setuptools wheel
What this does: 📖 Sets up a complete Python environment optimized for web development.
Example output:
Python 3.11.6
pip 23.3.1 from /opt/webapp-env/lib/python3.11/site-packages/pip (python 3.11)
What this means: Python is ready for web application development! ✅
Install Web Application Dependencies
Let’s install essential Python packages for web development! 🎯
What we’re doing: Installing WSGI servers, web frameworks, and common dependencies.
# Activate virtual environment
source /opt/webapp-env/bin/activate
# Install WSGI servers
pip install gunicorn uwsgi
# Install web frameworks
pip install flask django
# Install database adapters
pip install psycopg2-binary pymysql sqlalchemy
# Install web application utilities
pip install redis celery requests
# Install development and debugging tools
pip install flask-debugtoolbar django-debug-toolbar
# Create requirements file
pip freeze > requirements.txt
echo "Python web development environment ready! 🐍"
What these packages provide:
gunicorn
: Production WSGI server for Python web appsuwsgi
: Alternative high-performance WSGI serverflask
/django
: Popular Python web frameworks- Database adapters for PostgreSQL, MySQL, and SQLite
- Background task processing with Celery
What this means: You have everything needed for Python web development! 🌟
💡 Important Tips
Tip: Always use virtual environments to isolate Python dependencies! 💡
Warning: Alpine uses musl libc - some Python packages may need compilation! ⚠️
🛠️ Step 2: Configure Flask Web Application
Create Flask Application
Let’s build a complete Flask web application! 😊
What we’re doing: Creating a Flask application with database integration, user authentication, and API endpoints.
# Create Flask project directory
mkdir -p /opt/flask-webapp
cd /opt/flask-webapp
# Activate virtual environment
source /opt/webapp-env/bin/activate
# Create Flask application
cat > app.py << 'EOF'
from flask import Flask, jsonify, request, render_template_string
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import os
# Initialize Flask app
app = Flask(__name__)
# Configuration
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-secret-key')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get(
'DATABASE_URL',
'sqlite:///flask_app.db'
)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Initialize database
db = SQLAlchemy(app)
# Database Models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def to_dict(self):
return {
'id': self.id,
'username': self.username,
'email': self.email,
'created_at': self.created_at.isoformat()
}
# Routes
@app.route('/')
def home():
template = '''
<h1>🐍 Flask on Alpine Linux!</h1>
<p>Welcome to your Python web application!</p>
<ul>
<li><a href="/api/health">Health Check</a></li>
<li><a href="/api/users">View Users</a></li>
<li><a href="/api/info">System Info</a></li>
</ul>
<p>🏔️ Powered by Alpine Linux • ⚡ Flask Framework</p>
'''
return render_template_string(template)
@app.route('/api/health')
def health_check():
return jsonify({
'status': 'healthy',
'application': 'flask-alpine-app',
'version': '1.0.0',
'timestamp': datetime.utcnow().isoformat(),
'database': 'connected' if db.engine.execute('SELECT 1').scalar() == 1 else 'disconnected'
})
@app.route('/api/info')
def system_info():
import platform
import sys
return jsonify({
'python_version': sys.version,
'platform': platform.platform(),
'alpine_release': open('/etc/alpine-release').read().strip() if os.path.exists('/etc/alpine-release') else 'unknown'
})
@app.route('/api/users', methods=['GET', 'POST'])
def users():
if request.method == 'POST':
data = request.get_json()
user = User(username=data['username'], email=data['email'])
db.session.add(user)
db.session.commit()
return jsonify(user.to_dict()), 201
users = User.query.all()
return jsonify([user.to_dict() for user in users])
@app.route('/api/users/<int:user_id>')
def get_user(user_id):
user = User.query.get_or_404(user_id)
return jsonify(user.to_dict())
# Initialize database tables
@app.before_first_request
def create_tables():
db.create_all()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
EOF
# Install additional Flask dependencies
pip install flask-sqlalchemy
echo "Flask application created! 🌶️"
What this creates: A complete Flask web application with database integration and REST API! ✅
Configure Flask for Production
Let’s configure Flask for production deployment! 🚀
What we’re doing: Setting up production configuration, environment variables, and WSGI server.
# Create production configuration
cat > config.py << 'EOF'
import os
from datetime import timedelta
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key-change-in-production'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ENGINE_OPTIONS = {
'pool_recycle': 3600,
'pool_pre_ping': True
}
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///dev_app.db'
class ProductionConfig(Config):
DEBUG = False
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///prod_app.db'
# Security settings
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
PERMANENT_SESSION_LIFETIME = timedelta(hours=1)
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig,
'default': DevelopmentConfig
}
EOF
# Update app.py to use configuration
cat > app_production.py << 'EOF'
from flask import Flask
from config import config
import os
def create_app(config_name=None):
if config_name is None:
config_name = os.environ.get('FLASK_ENV', 'default')
app = Flask(__name__)
app.config.from_object(config[config_name])
# Import and register blueprints here
from app import db, User
db.init_app(app)
# Register routes
from app import home, health_check, system_info, users, get_user
app.add_url_rule('/', 'home', home)
app.add_url_rule('/api/health', 'health_check', health_check)
app.add_url_rule('/api/info', 'system_info', system_info)
app.add_url_rule('/api/users', 'users', users, methods=['GET', 'POST'])
app.add_url_rule('/api/users/<int:user_id>', 'get_user', get_user)
return app
# For Gunicorn
app = create_app()
EOF
# Create Gunicorn configuration
cat > gunicorn.conf.py << 'EOF'
# Gunicorn configuration for Flask on Alpine Linux
# Server socket
bind = "0.0.0.0:5000"
backlog = 2048
# Worker processes
workers = 2
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 5
# Logging
accesslog = "/var/log/gunicorn/access.log"
errorlog = "/var/log/gunicorn/error.log"
loglevel = "info"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
# Process naming
proc_name = "flask-alpine-app"
# Server mechanics
daemon = False
pidfile = "/var/run/gunicorn/flask-app.pid"
user = "webapp"
group = "webapp"
tmp_upload_dir = None
# Security
limit_request_line = 0
limit_request_fields = 100
limit_request_field_size = 8190
# Performance
preload_app = True
max_requests = 1000
max_requests_jitter = 100
EOF
echo "Flask production configuration created! 🏭"
What this provides:
- Environment-specific configurations (dev/prod/test)
- Security settings for production deployment
- Optimized Gunicorn WSGI server configuration
- Proper logging and process management
What this means: Your Flask app is production-ready! 🌟
Deploy Flask with Gunicorn
Let’s deploy Flask using Gunicorn WSGI server! 🎮
What we’re doing: Setting up Gunicorn service and testing the production deployment.
# Create webapp user for security
addgroup -g 1001 -S webapp
adduser -u 1001 -S webapp -G webapp
# Create required directories
mkdir -p /var/log/gunicorn /var/run/gunicorn
chown webapp:webapp /var/log/gunicorn /var/run/gunicorn
# Set proper ownership
chown -R webapp:webapp /opt/flask-webapp
# Create systemd service file (if using OpenRC, skip this)
cat > /etc/systemd/system/flask-webapp.service << 'EOF'
[Unit]
Description=Flask Web Application
After=network.target
[Service]
Type=notify
User=webapp
Group=webapp
WorkingDirectory=/opt/flask-webapp
Environment=PATH=/opt/webapp-env/bin
Environment=FLASK_ENV=production
ExecStart=/opt/webapp-env/bin/gunicorn --config gunicorn.conf.py app_production:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Create OpenRC service file for Alpine Linux
cat > /etc/init.d/flask-webapp << 'EOF'
#!/sbin/openrc-run
name="Flask Web Application"
description="Flask Web Application with Gunicorn"
user="webapp"
group="webapp"
directory="/opt/flask-webapp"
command="/opt/webapp-env/bin/gunicorn"
command_args="--config gunicorn.conf.py app_production:app"
pidfile="/var/run/gunicorn/flask-app.pid"
depend() {
need net
after firewall
}
start_pre() {
export FLASK_ENV=production
export PATH=/opt/webapp-env/bin:$PATH
checkpath --directory --owner $user:$group --mode 0755 /var/run/gunicorn
checkpath --directory --owner $user:$group --mode 0755 /var/log/gunicorn
}
EOF
chmod +x /etc/init.d/flask-webapp
# Test Gunicorn directly
cd /opt/flask-webapp
source /opt/webapp-env/bin/activate
# Initialize database
python3 -c "from app import db; db.create_all()"
# Start Gunicorn (background process)
FLASK_ENV=production gunicorn --config gunicorn.conf.py app_production:app &
GUNICORN_PID=$!
# Test the application
sleep 3
curl http://localhost:5000/api/health
# Stop test instance
kill $GUNICORN_PID
echo "Flask with Gunicorn configured! 🦄"
What this does: Sets up a production-ready Flask deployment with proper process management! ✅
🔧 Step 3: Configure Django Web Application
Create Django Project
Let’s set up a Django web application! 😊
What we’re doing: Creating a Django project with database models, views, and API endpoints.
# Create Django project directory
mkdir -p /opt/django-webapp
cd /opt/django-webapp
# Activate virtual environment
source /opt/webapp-env/bin/activate
# Install Django and additional packages
pip install django djangorestframework django-cors-headers
# Create Django project
django-admin startproject alpine_project .
# Create Django app
python manage.py startapp webapp
# Configure Django settings
cat > alpine_project/settings_production.py << 'EOF'
from .settings import *
import os
# Production settings
DEBUG = False
ALLOWED_HOSTS = ['*'] # Configure properly for production
# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'production.sqlite3',
}
}
# Static files
STATIC_ROOT = '/opt/django-webapp/static'
MEDIA_ROOT = '/opt/django-webapp/media'
# Security settings
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# Session security
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True
# Logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': '/var/log/django/webapp.log',
},
},
'root': {
'handlers': ['file'],
},
}
# Add webapp to installed apps
INSTALLED_APPS.extend([
'webapp',
'rest_framework',
'corsheaders',
])
MIDDLEWARE.insert(0, 'corsheaders.middleware.CorsMiddleware')
# REST Framework settings
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
],
}
EOF
echo "Django project created! 🎸"
What this creates: A Django project with production-ready configuration! ✅
Create Django Models and Views
Let’s build Django models and API views! 🚀
What we’re doing: Creating Django models, serializers, and REST API endpoints.
# Create Django models
cat > webapp/models.py << 'EOF'
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField(auto_now=True)
published = models.BooleanField(default=False)
class Meta:
ordering = ['-created_at']
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return f'Comment by {self.author.username} on {self.post.title}'
EOF
# Create serializers
cat > webapp/serializers.py << 'EOF'
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Post, Comment
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'email', 'date_joined']
class CommentSerializer(serializers.ModelSerializer):
author = UserSerializer(read_only=True)
class Meta:
model = Comment
fields = ['id', 'content', 'author', 'created_at']
class PostSerializer(serializers.ModelSerializer):
author = UserSerializer(read_only=True)
comments = CommentSerializer(many=True, read_only=True)
comments_count = serializers.SerializerMethodField()
class Meta:
model = Post
fields = ['id', 'title', 'content', 'author', 'created_at', 'updated_at', 'published', 'comments', 'comments_count']
def get_comments_count(self, obj):
return obj.comments.count()
EOF
# Create views
cat > webapp/views.py << 'EOF'
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework import generics, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from django.contrib.auth.models import User
from .models import Post, Comment
from .serializers import PostSerializer, CommentSerializer, UserSerializer
import platform
import sys
def home(request):
return render(request, 'webapp/home.html')
@api_view(['GET'])
@permission_classes([AllowAny])
def health_check(request):
return JsonResponse({
'status': 'healthy',
'application': 'django-alpine-app',
'version': '1.0.0',
'django_version': sys.modules['django'].get_version(),
'python_version': sys.version.split()[0],
'platform': platform.platform()
})
@api_view(['GET'])
@permission_classes([AllowAny])
def system_info(request):
import os
alpine_release = 'unknown'
try:
with open('/etc/alpine-release', 'r') as f:
alpine_release = f.read().strip()
except FileNotFoundError:
pass
return JsonResponse({
'python_version': sys.version,
'django_version': sys.modules['django'].get_version(),
'platform': platform.platform(),
'alpine_release': alpine_release
})
class PostListCreateView(generics.ListCreateAPIView):
queryset = Post.objects.filter(published=True)
serializer_class = PostSerializer
permission_classes = [AllowAny]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
EOF
# Create URLs
cat > webapp/urls.py << 'EOF'
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('api/health/', views.health_check, name='health_check'),
path('api/info/', views.system_info, name='system_info'),
path('api/posts/', views.PostListCreateView.as_view(), name='posts'),
path('api/posts/<int:pk>/', views.PostDetailView.as_view(), name='post_detail'),
]
EOF
# Update main URLs
cat > alpine_project/urls.py << 'EOF'
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('webapp.urls')),
]
EOF
echo "Django models and views created! 🎯"
What this creates: Complete Django application with REST API and database models! 🌟
Deploy Django with uWSGI
Let’s deploy Django using uWSGI server! 🎮
What we’re doing: Setting up uWSGI configuration and Django deployment.
# Create templates directory and home template
mkdir -p webapp/templates/webapp
cat > webapp/templates/webapp/home.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Django on Alpine Linux</title>
<style>
body { font-family: Arial, sans-serif; margin: 50px; text-align: center; }
.container { max-width: 800px; margin: 0 auto; }
.api-links { margin: 20px 0; }
.api-links a { margin: 0 10px; padding: 8px 16px; background: #007cba; color: white; text-decoration: none; border-radius: 4px; }
</style>
</head>
<body>
<div class="container">
<h1>🎸 Django on Alpine Linux!</h1>
<p>Welcome to your Django web application running on Alpine Linux!</p>
<div class="api-links">
<a href="/api/health">Health Check</a>
<a href="/api/info">System Info</a>
<a href="/api/posts">View Posts</a>
<a href="/admin">Django Admin</a>
</div>
<p>🏔️ Powered by Alpine Linux • ⚡ Django Framework</p>
</div>
</body>
</html>
EOF
# Create uWSGI configuration
cat > uwsgi.ini << 'EOF'
[uwsgi]
# Application settings
module = alpine_project.wsgi:application
master = true
processes = 2
threads = 2
harakiri = 30
max-requests = 1000
# Socket settings
socket = /run/uwsgi/django-app.sock
chmod-socket = 666
vacuum = true
# Process settings
uid = webapp
gid = webapp
chdir = /opt/django-webapp
# Logging
logto = /var/log/uwsgi/django-app.log
log-maxsize = 50000000
log-backupname = /var/log/uwsgi/django-app.log.old
# Performance
enable-threads = true
single-interpreter = true
lazy-apps = true
# Security
disable-logging = false
memory-report = true
EOF
# Create directories
mkdir -p /run/uwsgi /var/log/uwsgi /var/log/django
chown webapp:webapp /run/uwsgi /var/log/uwsgi /var/log/django
# Run Django migrations and setup
cd /opt/django-webapp
source /opt/webapp-env/bin/activate
python manage.py makemigrations webapp
python manage.py migrate
python manage.py collectstatic --noinput
# Create superuser (interactive)
echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', '[email protected]', 'changeme123')" | python manage.py shell
# Create OpenRC service for uWSGI
cat > /etc/init.d/django-webapp << 'EOF'
#!/sbin/openrc-run
name="Django Web Application"
description="Django Web Application with uWSGI"
user="webapp"
group="webapp"
directory="/opt/django-webapp"
command="/opt/webapp-env/bin/uwsgi"
command_args="--ini uwsgi.ini"
pidfile="/run/uwsgi/django-app.pid"
depend() {
need net
after firewall
}
start_pre() {
export DJANGO_SETTINGS_MODULE=alpine_project.settings_production
export PATH=/opt/webapp-env/bin:$PATH
checkpath --directory --owner $user:$group --mode 0755 /run/uwsgi
checkpath --directory --owner $user:$group --mode 0755 /var/log/uwsgi
checkpath --directory --owner $user:$group --mode 0755 /var/log/django
}
EOF
chmod +x /etc/init.d/django-webapp
echo "Django with uWSGI configured! 🦄"
What this does: Sets up Django with uWSGI for high-performance production deployment! ✅
📊 Quick Python Web Commands Table
Command | Purpose | Result |
---|---|---|
🔧 gunicorn app:app | Start Flask with Gunicorn | ✅ Production Flask server |
🔍 uwsgi --ini uwsgi.ini | Start Django with uWSGI | ✅ Production Django server |
🚀 python manage.py runserver | Django development server | ✅ Development testing |
📋 pip freeze > requirements.txt | Save dependencies | ✅ Reproducible environment |
🎮 Practice Time!
Let’s practice what you learned! Try these web application examples:
Example 1: Flask REST API with Database 🟢
What we’re doing: Creating a complete Flask REST API with SQLite database and authentication.
# Create API project
mkdir flask-api-demo && cd flask-api-demo
source /opt/webapp-env/bin/activate
# Install additional packages
pip install flask-jwt-extended flask-bcrypt
# Create API application
cat > api_app.py << 'EOF'
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from flask_bcrypt import Bcrypt
from datetime import datetime, timedelta
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///api.db'
app.config['JWT_SECRET_KEY'] = 'jwt-secret-string'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=1)
db = SQLAlchemy(app)
jwt = JWTManager(app)
bcrypt = Bcrypt(app)
# Models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(128))
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text)
completed = db.Column(db.Boolean, default=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# Routes
@app.route('/api/register', methods=['POST'])
def register():
data = request.get_json()
hashed_password = bcrypt.generate_password_hash(data['password']).decode('utf-8')
user = User(username=data['username'], password_hash=hashed_password)
db.session.add(user)
db.session.commit()
return jsonify({'message': 'User created successfully'}), 201
@app.route('/api/login', methods=['POST'])
def login():
data = request.get_json()
user = User.query.filter_by(username=data['username']).first()
if user and bcrypt.check_password_hash(user.password_hash, data['password']):
access_token = create_access_token(identity=user.id)
return jsonify({'access_token': access_token})
return jsonify({'message': 'Invalid credentials'}), 401
@app.route('/api/tasks', methods=['GET', 'POST'])
@jwt_required()
def tasks():
user_id = get_jwt_identity()
if request.method == 'POST':
data = request.get_json()
task = Task(title=data['title'], description=data.get('description', ''), user_id=user_id)
db.session.add(task)
db.session.commit()
return jsonify({'id': task.id, 'title': task.title}), 201
tasks = Task.query.filter_by(user_id=user_id).all()
return jsonify([{
'id': task.id,
'title': task.title,
'description': task.description,
'completed': task.completed,
'created_at': task.created_at.isoformat()
} for task in tasks])
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)
EOF
# Test the API
python api_app.py &
API_PID=$!
sleep 2
# Test endpoints
curl -X POST http://localhost:5000/api/register -H "Content-Type: application/json" -d '{"username":"testuser","password":"testpass"}'
TOKEN=$(curl -X POST http://localhost:5000/api/login -H "Content-Type: application/json" -d '{"username":"testuser","password":"testpass"}' | python -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
curl -X GET http://localhost:5000/api/tasks -H "Authorization: Bearer $TOKEN"
kill $API_PID
echo "Flask REST API example completed! 🌟"
What this does: Shows you how to build secure REST APIs with Flask and JWT authentication! 🌟
Example 2: Django Performance Optimization 🟡
What we’re doing: Implementing Django performance optimizations and caching strategies.
# Create optimized Django project
mkdir django-optimized && cd django-optimized
source /opt/webapp-env/bin/activate
# Install optimization packages
pip install django-redis django-cachalot django-debug-toolbar
# Create optimized settings
cat > optimized_settings.py << 'EOF'
import os
from django.conf import settings
# Cache configuration
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
# Session engine
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
# Database optimization
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'optimized.db',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}
}
}
# ORM optimization
CACHALOT_ENABLED = True
CACHALOT_CACHE = 'default'
# Static files optimization
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
# Security and performance middleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.cache.UpdateCacheMiddleware', # Cache
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware', # Cache
]
# Template optimization
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'builtins': [
'django.templatetags.cache',
],
},
}]
# Logging configuration
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/var/log/django/performance.log',
'maxBytes': 1024*1024*10, # 10 MB
'backupCount': 5,
'formatter': 'verbose',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'INFO',
'propagate': True,
},
},
}
EOF
echo "Django performance optimization example completed! 📚"
What this does: Demonstrates advanced Django optimization techniques for production! 📚
🚨 Fix Common Problems
Problem 1: Python packages fail to build on Alpine ❌
What happened: Some Python packages can’t compile with musl libc. How to fix it: Install development packages and use Alpine-specific solutions.
# Install build dependencies
apk add build-base python3-dev linux-headers
# For specific packages that need glibc compatibility
apk add gcompat
# Use Alpine-specific packages when available
apk add py3-pillow py3-numpy py3-lxml
# Alternative: Use wheel packages
pip install --only-binary=all package_name
Problem 2: Django static files not serving ❌
What happened: Static files not loading in production deployment. How to fix it: Configure static file serving properly.
# Collect static files
python manage.py collectstatic --noinput
# Configure nginx for static files (if using nginx)
cat >> /etc/nginx/conf.d/django.conf << 'EOF'
location /static/ {
alias /opt/django-webapp/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
EOF
# Or serve with whitenoise in Django
pip install whitenoise
# Add to MIDDLEWARE in settings.py
Don’t worry! Python web application issues on Alpine are usually dependency or configuration related! 💪
💡 Simple Tips
- Use virtual environments 📅 - Keep Python dependencies isolated and manageable
- Pin package versions 🌱 - Use requirements.txt with exact versions for reproducibility
- Optimize for Alpine 🤝 - Use Alpine packages when available, compile when necessary
- Monitor performance 💪 - Use profiling tools and monitoring for production apps
✅ Check Everything Works
Let’s verify your Python web development environment is perfect:
# Complete Python web environment check
echo "=== Python Web Development Environment Check ==="
echo "1. Python and pip versions:"
python3 --version && pip3 --version
echo "2. Virtual environment status:"
source /opt/webapp-env/bin/activate
echo "Virtual environment: $VIRTUAL_ENV"
echo "3. Web frameworks installed:"
python -c "import flask; print(f'Flask: {flask.__version__}')" 2>/dev/null || echo "Flask: Not installed"
python -c "import django; print(f'Django: {django.get_version()}')" 2>/dev/null || echo "Django: Not installed"
echo "4. WSGI servers available:"
which gunicorn >/dev/null && echo "✅ Gunicorn available" || echo "❌ Gunicorn missing"
which uwsgi >/dev/null && echo "✅ uWSGI available" || echo "❌ uWSGI missing"
echo "5. Database adapters:"
python -c "import sqlite3; print('✅ SQLite support')" 2>/dev/null
python -c "import psycopg2; print('✅ PostgreSQL support')" 2>/dev/null || echo "❌ PostgreSQL adapter missing"
echo "6. Test Flask application:"
cat > test_flask.py << 'EOF'
from flask import Flask
app = Flask(__name__)
@app.route('/test')
def test(): return 'Flask working on Alpine!'
if __name__ == '__main__': app.run(port=5001)
EOF
python test_flask.py &
TEST_PID=$!
sleep 2
curl -s http://localhost:5001/test 2>/dev/null && echo "✅ Flask test successful" || echo "❌ Flask test failed"
kill $TEST_PID 2>/dev/null
rm test_flask.py
echo "7. System resources:"
echo "Memory: $(free -h | awk '/^Mem:/ {print $2}') total, $(free -h | awk '/^Mem:/ {print $7}') available"
echo "Disk: $(df -h / | awk 'NR==2 {print $4}') available"
echo "Python web development environment ready! ✅"
Good output shows:
=== Python Web Development Environment Check ===
1. Python and pip versions:
Python 3.11.6
pip 23.3.1
2. Virtual environment status:
Virtual environment: /opt/webapp-env
3. Web frameworks installed:
Flask: 2.3.3
Django: 4.2.7
4. WSGI servers available:
✅ Gunicorn available
✅ uWSGI available
6. Test Flask application:
✅ Flask test successful
Python web development environment ready! ✅
🏆 What You Learned
Great job! Now you can:
- ✅ Set up complete Python web development environment on Alpine Linux
- ✅ Create and deploy Flask applications with proper configuration
- ✅ Build Django projects with REST APIs and database integration
- ✅ Configure production WSGI servers (Gunicorn and uWSGI)
- ✅ Implement security best practices for Python web applications
- ✅ Optimize Python applications for Alpine Linux’s musl libc
- ✅ Handle database connections and ORM configurations
- ✅ Deploy scalable Python web applications in production
- ✅ Troubleshoot common Python web development issues on Alpine
🎯 What’s Next?
Now you can try:
- 📚 Implementing advanced caching strategies with Redis and Memcached
- 🛠️ Setting up containerized Python applications with Docker and Alpine
- 🤝 Deploying Python web applications with load balancers and reverse proxies
- 🌟 Exploring microservices architecture with Python and Alpine Linux!
Remember: Alpine Linux provides an excellent foundation for Python web applications! You’re now deploying web apps like a pro! 🎉
Keep developing and you’ll master Python web deployment on Alpine Linux! 💫