Apache Server Configs
The `apache-server-configs` package provides a robust collection of boilerplate configuration snippets for the Apache HTTP server, currently at version 6.0.0. It aims to enhance web server performance, improve security postures, and ensure resources are served with correct content-types, including cross-domain access when necessary. The project maintains an active development cycle, with major version updates occurring roughly annually, addressing evolving web standards for security, caching, and performance. Minor releases typically introduce new MIME types, expand caching directives, and refine existing configurations. A key differentiator is its focus on modern best practices, including strong `Cache-Control` policies, comprehensive security headers like `Content-Security-Policy`, `Permissions-Policy`, and Cross-Origin policies, and optimized asset handling. It explicitly discourages the use of `.htaccess` files due to performance overhead, advocating for direct integration into `httpd.conf`.
Common errors
-
Syntax error on line X of Y: Invalid command 'Cache-Control', perhaps misspelled or defined by a module not included in the server configuration
cause The `mod_headers` Apache module is not enabled, which is required for processing `Cache-Control` and other HTTP headers directives.fixEnable `mod_headers` using `sudo a2enmod headers` (Debian/Ubuntu) or by uncommenting `LoadModule headers_module modules/mod_headers.so` in `httpd.conf`, then restart Apache. -
AH00526: Syntax error on line X of Y: Invalid command 'AddOutputFilterByType', perhaps misspelled or defined by a module not included in the server configuration
cause The `mod_deflate` Apache module is not enabled, preventing the server from applying compression filters.fixEnable `mod_deflate` using `sudo a2enmod deflate` (Debian/Ubuntu) or by uncommenting `LoadModule deflate_module modules/mod_deflate.so` in `httpd.conf`, then restart Apache. -
AH00526: Syntax error on line X of Y: Invalid command 'ExpiresActive', perhaps misspelled or defined by a module not included in the server configuration
cause The `mod_expires` Apache module is not enabled, which is necessary for setting `Expires` headers and cache control.fixEnable `mod_expires` using `sudo a2enmod expires` (Debian/Ubuntu) or by uncommenting `LoadModule expires_module modules/mod_expires.so` in `httpd.conf`, then restart Apache. -
AH00526: Syntax error on line X of Y: Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configuration
cause The `mod_rewrite` Apache module is not enabled, which is critical for URL rewriting, redirects, and enforcing canonical URLs.fixEnable `mod_rewrite` using `sudo a2enmod rewrite` (Debian/Ubuntu) or by uncommenting `LoadModule rewrite_module modules/mod_rewrite.so` in `httpd.conf`, then restart Apache.
Warnings
- breaking Internet Explorer (`X-UA-Compatible` and `X-XSS-Protection` headers) support was removed in v5.0.0, potentially affecting compatibility with older browsers.
- breaking File paths for the `.htaccess` build system were altered in v4.0.0, which can cause 'file not found' errors if existing build scripts are not updated.
- gotcha Using `.htaccess` files can introduce significant performance overhead as Apache must process them on every request; direct configuration in `httpd.conf` is strongly recommended.
- breaking Apache httpd versions 2.3 and below are no longer supported since v3.0.0, which means configurations may fail to load or behave unexpectedly on older servers.
Install
-
npm install apache-server-configs -
yarn add apache-server-configs -
pnpm add apache-server-configs
Quickstart
import { promises as fs } from 'fs';
import { join } from 'path';
import { exec } from 'child_process';
const sourceDir = join(process.cwd(), 'node_modules', 'apache-server-configs', 'dist'); // Adjust if config files are not in 'dist'
const apacheConfDir = process.env.APACHE_CONF_DIR || '/etc/apache2/conf.d'; // Common Apache config directory
const httpdConfPath = process.env.HTTPD_CONF_PATH || '/etc/apache2/httpd.conf'; // Example main httpd.conf path
async function deployApacheConfigs() {
try {
console.log(`Copying Apache config files from ${sourceDir} to ${apacheConfDir}...`);
await fs.cp(sourceDir, apacheConfDir, { recursive: true, force: true });
console.log('Apache config files copied successfully.');
// Append an Include directive to httpd.conf if not already present
let httpdConfContent = await fs.readFile(httpdConfPath, 'utf8');
const includeDirective = `IncludeOptional ${apacheConfDir}/*.conf`;
if (!httpdConfContent.includes(includeDirective)) {
console.log(`Adding '${includeDirective}' to ${httpdConfPath}...`);
await fs.appendFile(httpdConfPath, `\n# H5BP Apache Server Configs\n${includeDirective}\n`);
} else {
console.log(`'${includeDirective}' already present in ${httpdConfPath}.`);
}
// Enable required modules (assuming a Debian/Ubuntu-like system with a2enmod)
console.log('Enabling required Apache modules...');
const modules = ['setenvif', 'headers', 'deflate', 'filter', 'expires', 'rewrite', 'include', 'mime', 'autoindex'];
const a2enmodCommand = `sudo a2enmod ${modules.join(' ')}`;
console.log(`Executing: ${a2enmodCommand}`);
await new Promise((resolve, reject) => {
exec(a2enmodCommand, (error, stdout, stderr) => {
if (error) {
console.error(`Error enabling modules: ${stderr}`);
return reject(error);
}
console.log(`Modules enabled: ${stdout}`);
resolve();
});
});
// Test Apache configuration
console.log('Testing Apache configuration...');
await new Promise((resolve, reject) => {
exec('sudo apache2 -t', (error, stdout, stderr) => {
if (error) {
console.error(`Apache config test failed: ${stderr}`);
return reject(error);
}
console.log(`Apache config test successful: ${stdout}`);
resolve();
});
});
// Reload Apache to apply new config
console.log('Reloading Apache service...');
await new Promise((resolve, reject) => {
exec('sudo apache2ctl reload', (error, stdout, stderr) => {
if (error) {
console.error(`Apache reload failed: ${stderr}`);
return reject(error);
}
console.log(`Apache reloaded successfully: ${stdout}`);
resolve();
});
});
console.log('Apache server configs deployed and Apache reloaded successfully!');
} catch (error) {
console.error('Deployment failed:', error);
process.exit(1);
}
}
deployApacheConfigs();