This project was created for homelab/VPS owners who want to deploy web applications quickly, simply, and efficiently. It solves a common problem: How to run a WordPress site for content management while serving a fast, secure static version to visitors.
Imagine you're running a personal blog, portfolio, or small business website. You want:
- The ease of WordPress for content creation and management
- The speed, security, and low resource usage of a static site for visitors
- A simple way to update your static site whenever you change content
- Automatic SSL certificates and domain management
- All with minimal setup and maintenance
That's exactly what this stack provides. Edit your content in WordPress, click a button to generate a static version, and the LiteSpeed server instantly serves the static site to your visitors - all behind Nginx Proxy Manager for easy domain and SSL management.
It's perfect for:
- Small business websites
- Personal blogs and portfolios
- Documentation sites
- Any site with content that doesn't change frequently
Rather than piecing together separate systems or writing your own deployment scripts, this project gives you everything in a single, easy-to-deploy Docker Compose stack.
This stack provides a complete, production-ready environment for hosting:
- WordPress websites with Nginx and MySQL database
- LiteSpeed web server for serving static content from WordPress static folder
- Nginx Proxy Manager for managing domain routing, SSL certificates, and access control
- phpMyAdmin for database management
The setup is configured to:
- Run all services in isolated containers
- Ensure proper networking between components
- Provide persistence for all important data
- Include health checks for all services
- Use fixed versions and credentials for consistency
├── docker-compose.yml # Main configuration file combining all services
├── database.yml # MySQL and phpMyAdmin configurations
├── wordpress.yml # WordPress service configuration
├── nginx.yml # Nginx web server configuration for WordPress
├── proxy.yml # Nginx Proxy Manager and its database configuration
├── fileserver.yml # Optional Nginx-based file server (commented out)
├── litespeed.yml # LiteSpeed web server configuration
├── nginx/ # Nginx configuration files
│ ├── nginx.conf # Default Nginx configuration for WordPress
│ └── ssl/ # SSL certificates for Nginx
├── uploads.ini # PHP upload configuration for WordPress
├── mysql-data/ # MySQL database files (persistent)
├── wordpress/ # WordPress files (persistent)
│ └── static/ # Static files generated by WordPress for LiteSpeed
├── nginx-proxy-manager/ # Nginx Proxy Manager data and certificates
│ ├── data/ # Configuration data
│ └── letsencrypt/ # SSL certificates
├── mysql-init/ # MySQL initialization scripts
└── cleanup_npm.sh # Script to clean up Nginx Proxy Manager if needed
- Clone or download this repository
- Create the network:
docker network create webapp_network - Start all services:
docker-compose up -d - Access WordPress at http://your-server-ip (through Nginx)
- Setup your WordPress site with your content, theme, and plugins
- Install a static site generator plugin in WordPress (like Simply Static)
- Generate your static site to the
/var/www/html/staticdirectory - Configure Nginx Proxy Manager at http://your-server-ip:81
- Create hosts for both your WordPress admin and static site
- Set up SSL certificates
- Done! Your static site is now served by LiteSpeed while you can continue to manage content in WordPress
- Docker Engine (20.10+)
- Docker Compose (2.0+)
- At least 2GB of RAM available for Docker
- Internet connection to download container images
-
Clone or download this repository to your server
git clone https://github.com/nityam2007/StaticPress-Docker.git cd StaticPress-Docker -
Create the network (only needed once)
docker network create webapp_network
-
Start all services
docker-compose up -d
-
Access the services:
- WordPress: http://your-server-ip (through Nginx)
- Nginx Proxy Manager: http://your-server-ip:81
- Default login: [email protected] / changeme
- phpMyAdmin: Configure access through Nginx Proxy Manager
- LiteSpeed static site: Configure access through Nginx Proxy Manager
The typical workflow for managing your website with this stack:
- Create and edit content in WordPress using the familiar admin interface
- Install and activate a static site generator plugin (Simply Static or WP2Static)
- Configure the plugin to output to the
/var/www/html/staticdirectory - Generate the static site whenever you make content changes
- Visitors access your static site which is served by LiteSpeed
- You access the WordPress admin when you need to make changes
This gives you the best of both worlds: the content management capabilities of WordPress with the performance and security benefits of a static site.
| Service | Username | Password | Notes |
|---|---|---|---|
| MySQL Root | root | rootpassword | Used for administrative access |
| MySQL WordPress | wordpress | wordpress_password | Used by WordPress |
| WordPress Admin | Set during setup | Set during setup | Created on first run |
| Nginx Proxy Manager | [email protected] | changeme | Changed on first login |
| phpMyAdmin | root | rootpassword | Uses MySQL credentials |
| LiteSpeed Admin | admin | litespeed123 | Currently commented out |
File upload and size limits have been configured for large files:
- PHP: 256MB (configured in uploads.ini)
- Nginx: 256MB (configured in nginx.conf)
- Nginx Proxy Manager: 256MB
- phpMyAdmin: 256MB
- LiteSpeed: Default settings
This stack includes a LiteSpeed server configured to serve static content from the WordPress static folder:
-
WordPress Static Folder: The LiteSpeed container is configured to serve content from
./wordpress/staticdirectory. This folder is where WordPress will store static site content. -
Static Site Generation:
- The static site content needs to be generated from within WordPress using a plugin like "Simply Static" or "WP2Static".
- Install and activate one of these plugins from the WordPress admin dashboard.
- Configure the plugin to generate static files into the
./wordpress/staticdirectory. - The generation process will create a static version of your WordPress site that can be served by LiteSpeed.
-
LiteSpeed Configuration:
- LiteSpeed is configured with the following volume mapping:
volumes: - ./wordpress/static:/var/www/vhosts/localhost/html
- This maps the WordPress static folder to LiteSpeed's document root.
- LiteSpeed is configured with the following volume mapping:
-
Install a Static Site Generator Plugin in WordPress:
- Log in to WordPress admin
- Go to Plugins > Add New
- Search for "Simply Static" or "WP2Static"
- Install and activate the plugin
-
Configure the Plugin:
- For Simply Static:
- Go to Simply Static > Settings
- In "Delivery Method" select "Local Directory"
- Set the local directory path to
/var/www/html/static(this is the path inside the WordPress container) - Click "Generate" to create your static site
- For Simply Static:
-
Access Your Static Site:
- Configure Nginx Proxy Manager to route a domain to the LiteSpeed container
- Or uncomment the port mappings in litespeed.yml for direct access:
ports: - "8888:80" - "7080:7080" # Admin panel
-
Create a directory structure for your new WordPress site:
mkdir -p wordpress-site2 nginx/site2
-
Create Nginx configuration for the new site:
# Create nginx/site2/nginx.conf cp nginx/nginx.conf nginx/site2/nginx.conf -
Edit the new Nginx configuration to update the server_name and other settings:
# File location: nginx/site2/nginx.conf server { listen 80; server_name site2.example.com; root /var/www/html; index index.php; # Increase upload size limit client_max_body_size 256M; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { fastcgi_pass wordpress-site2:9000; # Changed to new WordPress container fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_read_timeout 300; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; } # Deny access to .htaccess files location ~ /\.ht { deny all; } }
-
Create a new WordPress compose file (e.g.,
wordpress-site2.yml):# File location: wordpress-site2.yml services: wordpress-site2: image: wordpress:6.8.0-php8.4-fpm-alpine container_name: wp-app-site2 volumes: - ./wordpress-site2:/var/www/html - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress_password WORDPRESS_DB_NAME: wordpress_site2 WORDPRESS_TABLE_PREFIX: wp_ restart: unless-stopped networks: - webapp_network healthcheck: test: ["CMD", "curl", "--fail", "http://localhost"] interval: 10s timeout: 5s retries: 3 start_period: 30s nginx-site2: image: nginx:alpine container_name: wp-nginx-site2 volumes: - ./wordpress-site2:/var/www/html - ./nginx/site2/nginx.conf:/etc/nginx/conf.d/default.conf - ./nginx/site2/ssl:/etc/nginx/ssl restart: unless-stopped networks: - webapp_network healthcheck: test: ["CMD", "curl", "--fail", "http://localhost"] interval: 10s timeout: 5s retries: 3 networks: webapp_network: external: true
-
Create the database for the new site using phpMyAdmin:
- Log in to phpMyAdmin
- Create a new database named
wordpress_site2 - You can use the same
wordpressuser or create a new one
-
Update the main docker-compose.yml to include the new services:
wordpress-site2: extends: file: wordpress-site2.yml service: wordpress-site2 depends_on: - mysql nginx-site2: extends: file: wordpress-site2.yml service: nginx-site2 depends_on: - wordpress-site2
-
Configure Nginx Proxy Manager to route traffic to the new site:
- Access Nginx Proxy Manager admin interface (http://your-server-ip:81)
- Add a new "Proxy Host"
- Set the domain name to match your nginx configuration (e.g., site2.example.com)
- Set the scheme to http
- Set the forward hostname to nginx-site2
- Set the forward port to 80
- Configure SSL if needed
-
Start the new services:
docker-compose up -d
-
Access your new WordPress site at the configured domain and complete the WordPress setup
To add more static sites served by LiteSpeed:
-
Setup a new WordPress site following the WordPress site setup instructions above.
-
Create a static folder for the new WordPress site:
mkdir -p wordpress-site2/static
-
Create a new LiteSpeed configuration file:
# File location: litespeed-site2.yml services: litespeed-site2: image: litespeedtech/openlitespeed:latest container_name: litespeed-site2 restart: unless-stopped volumes: - ./wordpress-site2/static:/var/www/vhosts/localhost/html environment: - TZ=UTC # ports: # - "8889:80" networks: - webapp_network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80/"] interval: 15s timeout: 5s retries: 3 networks: webapp_network: external: true
-
Update docker-compose.yml to include the new service:
litespeed-site2: extends: file: litespeed-site2.yml service: litespeed-site2
-
Configure Nginx Proxy Manager to route traffic to this service:
- Add a new "Proxy Host" in the admin panel
- Set the domain name for the static site (e.g., static-site2.example.com)
- Point it to litespeed-site2:80
- Configure SSL if needed
-
Generate static content:
- Install and configure a static site generator plugin in your WordPress site
- Configure it to output to the static folder (e.g., /var/www/html/static)
- Generate the static site content
-
Start the new service:
docker-compose up -d
All sites can use the same MySQL database server with different database names:
-
Create a new database through phpMyAdmin:
- Log in to phpMyAdmin
- Create a new database (e.g.,
mysite_db) - Create or use an existing user with permissions on this database
-
Configure your application to use the shared database:
- Host:
mysql - Port:
3306 - Database: your database name (e.g.,
wordpress_site2) - Username:
wordpress(or create a new user) - Password:
wordpress_password(or set a new password)
- Host:
Backup important data volumes regularly:
# For MySQL data
tar -czvf mysql-backup.tar.gz ./mysql-data
# For WordPress files (including static site content)
tar -czvf wordpress-backup.tar.gz ./wordpress
# For additional WordPress sites
tar -czvf wordpress-site2-backup.tar.gz ./wordpress-site2
# For Nginx Proxy Manager data
tar -czvf npm-backup.tar.gz ./nginx-proxy-managerTo update services to the latest versions:
- Edit the relevant YAML file to update image versions
- Restart the services:
docker-compose down docker-compose up -d
View logs for all containers:
docker-compose logs
# For a specific service
docker-compose logs wordpress# Stop all services
docker-compose down
# Stop and remove volumes (WARNING: Deletes all data)
docker-compose down -v- Passwords: Change all default passwords in the configuration files
- Access: Restrict access to ports 80, 443, and 81 only
- SSL: Use Nginx Proxy Manager to secure all sites with SSL certificates
- Updates: Regularly update all container images
- Static Content: Using a static site reduces attack vectors significantly
-
Container not starting:
- Check logs:
docker-compose logs [service-name] - Verify networking:
docker network inspect webapp_network
- Check logs:
-
WordPress not connecting to database:
- Verify MySQL is running:
docker-compose ps mysql - Check credentials in wordpress.yml
- Make sure the database exists in MySQL
- Verify MySQL is running:
-
Cannot access Nginx Proxy Manager:
- Ensure port 81 is accessible
- Check logs:
docker-compose logs nginx-proxy-manager - If needed, use the
cleanup_npm.shscript to reset proxy configurations
-
File upload issues:
- Check the upload_max_filesize in uploads.ini
- Verify client_max_body_size in the Nginx configuration
-
Static site not updating:
- Verify the static site generator plugin is configured correctly
- Check the output path in the plugin configuration
- Regenerate the static site content after WordPress changes
This stack is designed to be modular. To add new services:
- Create a new YAML file for your service
- Add the service to docker-compose.yml
- Configure networking to connect to webapp_network
- Configure Nginx Proxy Manager to route traffic as needed