@hotwyl/init-docker-minimal-dev 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/bin/cli.js +82 -0
- package/package.json +27 -0
- package/template/.env +22 -0
- package/template/Dockerfile +73 -0
- package/template/README.md +532 -0
- package/template/apache/.gitkeep +1 -0
- package/template/config/apache/000-default.conf +39 -0
- package/template/config/mysql/init/01-init.sql +42 -0
- package/template/config/mysql/my.cnf +33 -0
- package/template/config/php/php.ini +95 -0
- package/template/docker-compose.yml +89 -0
- package/template/www/.htaccess +181 -0
- package/template/www/errors/403.html +48 -0
- package/template/www/errors/404.html +48 -0
- package/template/www/errors/500.html +48 -0
- package/template/www/index.php +501 -0
- package/template/www/phpinfo.php +10 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
[PHP]
|
|
2
|
+
; ============================================
|
|
3
|
+
; Configurações Gerais
|
|
4
|
+
; ============================================
|
|
5
|
+
engine = On
|
|
6
|
+
short_open_tag = On
|
|
7
|
+
precision = 14
|
|
8
|
+
output_buffering = 4096
|
|
9
|
+
zlib.output_compression = Off
|
|
10
|
+
implicit_flush = Off
|
|
11
|
+
serialize_precision = -1
|
|
12
|
+
zend.enable_gc = On
|
|
13
|
+
|
|
14
|
+
; ============================================
|
|
15
|
+
; Limites de Recursos
|
|
16
|
+
; ============================================
|
|
17
|
+
max_execution_time = 300
|
|
18
|
+
max_input_time = 300
|
|
19
|
+
max_input_vars = 5000
|
|
20
|
+
memory_limit = 512M
|
|
21
|
+
|
|
22
|
+
; ============================================
|
|
23
|
+
; Tratamento de Erros (Desenvolvimento)
|
|
24
|
+
; ============================================
|
|
25
|
+
error_reporting = E_ALL
|
|
26
|
+
display_errors = On
|
|
27
|
+
display_startup_errors = On
|
|
28
|
+
log_errors = On
|
|
29
|
+
log_errors_max_len = 1024
|
|
30
|
+
ignore_repeated_errors = Off
|
|
31
|
+
ignore_repeated_source = Off
|
|
32
|
+
report_memleaks = On
|
|
33
|
+
html_errors = On
|
|
34
|
+
error_log = /var/log/apache2/php_errors.log
|
|
35
|
+
|
|
36
|
+
; ============================================
|
|
37
|
+
; Upload de Arquivos
|
|
38
|
+
; ============================================
|
|
39
|
+
file_uploads = On
|
|
40
|
+
upload_max_filesize = 100M
|
|
41
|
+
max_file_uploads = 20
|
|
42
|
+
|
|
43
|
+
; ============================================
|
|
44
|
+
; Fuso Horário
|
|
45
|
+
; ============================================
|
|
46
|
+
date.timezone = America/Sao_Paulo
|
|
47
|
+
|
|
48
|
+
; ============================================
|
|
49
|
+
; POST Data
|
|
50
|
+
; ============================================
|
|
51
|
+
post_max_size = 100M
|
|
52
|
+
|
|
53
|
+
; ============================================
|
|
54
|
+
; Sessões
|
|
55
|
+
; ============================================
|
|
56
|
+
session.save_handler = files
|
|
57
|
+
session.use_strict_mode = 0
|
|
58
|
+
session.use_cookies = 1
|
|
59
|
+
session.use_only_cookies = 1
|
|
60
|
+
session.name = PHPSESSID
|
|
61
|
+
session.auto_start = 0
|
|
62
|
+
session.cookie_lifetime = 0
|
|
63
|
+
session.cookie_path = /
|
|
64
|
+
session.cookie_domain =
|
|
65
|
+
session.cookie_httponly = 1
|
|
66
|
+
session.serialize_handler = php
|
|
67
|
+
session.gc_probability = 1
|
|
68
|
+
session.gc_divisor = 1000
|
|
69
|
+
session.gc_maxlifetime = 1440
|
|
70
|
+
session.cache_limiter = nocache
|
|
71
|
+
session.cache_expire = 180
|
|
72
|
+
session.use_trans_sid = 0
|
|
73
|
+
|
|
74
|
+
; ============================================
|
|
75
|
+
; OPcache
|
|
76
|
+
; ============================================
|
|
77
|
+
opcache.enable = 1
|
|
78
|
+
opcache.enable_cli = 1
|
|
79
|
+
opcache.memory_consumption = 128
|
|
80
|
+
opcache.interned_strings_buffer = 8
|
|
81
|
+
opcache.max_accelerated_files = 10000
|
|
82
|
+
opcache.revalidate_freq = 0
|
|
83
|
+
opcache.validate_timestamps = 1
|
|
84
|
+
opcache.fast_shutdown = 1
|
|
85
|
+
|
|
86
|
+
; ============================================
|
|
87
|
+
; Xdebug (Debugging)
|
|
88
|
+
; ============================================
|
|
89
|
+
[xdebug]
|
|
90
|
+
xdebug.mode = develop,debug
|
|
91
|
+
xdebug.start_with_request = yes
|
|
92
|
+
xdebug.client_host = host.docker.internal
|
|
93
|
+
xdebug.client_port = 9003
|
|
94
|
+
xdebug.log = /var/log/apache2/xdebug.log
|
|
95
|
+
xdebug.idekey = VSCODE
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
# Servidor Web Apache + PHP
|
|
5
|
+
web:
|
|
6
|
+
build:
|
|
7
|
+
context: .
|
|
8
|
+
dockerfile: Dockerfile
|
|
9
|
+
container_name: minimaldev-web
|
|
10
|
+
ports:
|
|
11
|
+
- "80:80"
|
|
12
|
+
- "443:443"
|
|
13
|
+
volumes:
|
|
14
|
+
- ./www:/var/www/html
|
|
15
|
+
- ./config/php/php.ini:/usr/local/etc/php/php.ini
|
|
16
|
+
- ./config/apache/000-default.conf:/etc/apache2/sites-available/000-default.conf
|
|
17
|
+
- ./logs/apache:/var/log/apache2
|
|
18
|
+
environment:
|
|
19
|
+
- APACHE_DOCUMENT_ROOT=/var/www/html
|
|
20
|
+
depends_on:
|
|
21
|
+
- mysql
|
|
22
|
+
networks:
|
|
23
|
+
- minimaldev-network
|
|
24
|
+
restart: unless-stopped
|
|
25
|
+
|
|
26
|
+
# Servidor MySQL
|
|
27
|
+
mysql:
|
|
28
|
+
image: mysql:latest
|
|
29
|
+
container_name: minimaldev-mysql
|
|
30
|
+
ports:
|
|
31
|
+
- "3306:3306"
|
|
32
|
+
volumes:
|
|
33
|
+
- mysql_data:/var/lib/mysql
|
|
34
|
+
- ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
|
|
35
|
+
- ./config/mysql/init:/docker-entrypoint-initdb.d
|
|
36
|
+
environment:
|
|
37
|
+
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}
|
|
38
|
+
MYSQL_DATABASE: ${MYSQL_DATABASE:-minimaldev}
|
|
39
|
+
MYSQL_USER: ${MYSQL_USER:-developer}
|
|
40
|
+
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-developer123}
|
|
41
|
+
networks:
|
|
42
|
+
- minimaldev-network
|
|
43
|
+
restart: unless-stopped
|
|
44
|
+
|
|
45
|
+
# phpMyAdmin
|
|
46
|
+
phpmyadmin:
|
|
47
|
+
image: phpmyadmin:latest
|
|
48
|
+
container_name: minimaldev-phpmyadmin
|
|
49
|
+
ports:
|
|
50
|
+
- "8080:80"
|
|
51
|
+
environment:
|
|
52
|
+
PMA_HOST: mysql
|
|
53
|
+
PMA_PORT: 3306
|
|
54
|
+
PMA_USER: root
|
|
55
|
+
PMA_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}
|
|
56
|
+
UPLOAD_LIMIT: 100M
|
|
57
|
+
depends_on:
|
|
58
|
+
- mysql
|
|
59
|
+
networks:
|
|
60
|
+
- minimaldev-network
|
|
61
|
+
restart: unless-stopped
|
|
62
|
+
|
|
63
|
+
# Node.js para desenvolvimento frontend/ferramentas
|
|
64
|
+
node:
|
|
65
|
+
image: node:lts
|
|
66
|
+
container_name: minimaldev-node
|
|
67
|
+
working_dir: /var/www/html
|
|
68
|
+
volumes:
|
|
69
|
+
- ./www:/var/www/html
|
|
70
|
+
ports:
|
|
71
|
+
- "5173:5173" # Útil caso utilize Vite (Frontend)
|
|
72
|
+
command: tail -f /dev/null
|
|
73
|
+
user: "node" # Evita que arquivos gerados pelo npm/yarn fiquem com permissão de root
|
|
74
|
+
tty: true
|
|
75
|
+
stdin_open: true
|
|
76
|
+
networks:
|
|
77
|
+
- minimaldev-network
|
|
78
|
+
restart: unless-stopped
|
|
79
|
+
|
|
80
|
+
# Rede para comunicação entre containers
|
|
81
|
+
networks:
|
|
82
|
+
minimaldev-network:
|
|
83
|
+
driver: bridge
|
|
84
|
+
name: minimaldev-network
|
|
85
|
+
|
|
86
|
+
# Volume persistente para MySQL
|
|
87
|
+
volumes:
|
|
88
|
+
mysql_data:
|
|
89
|
+
name: minimaldev-mysql-data
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# ============================================
|
|
2
|
+
# MinimalDev - Configurações .htaccess
|
|
3
|
+
# Ambiente de Desenvolvimento
|
|
4
|
+
# ============================================
|
|
5
|
+
|
|
6
|
+
# Habilitar reescrita de URL
|
|
7
|
+
RewriteEngine On
|
|
8
|
+
|
|
9
|
+
# Definir diretório base
|
|
10
|
+
RewriteBase /
|
|
11
|
+
|
|
12
|
+
# Prevenir listagem de diretórios
|
|
13
|
+
Options -Indexes
|
|
14
|
+
|
|
15
|
+
# Seguir links simbólicos
|
|
16
|
+
Options +FollowSymLinks
|
|
17
|
+
|
|
18
|
+
# Definir index padrão
|
|
19
|
+
DirectoryIndex index.php index.html index.htm
|
|
20
|
+
|
|
21
|
+
# ============================================
|
|
22
|
+
# Configurações de charset
|
|
23
|
+
# ============================================
|
|
24
|
+
AddDefaultCharset UTF-8
|
|
25
|
+
|
|
26
|
+
# ============================================
|
|
27
|
+
# Tipos MIME
|
|
28
|
+
# ============================================
|
|
29
|
+
AddType application/javascript .js
|
|
30
|
+
AddType text/css .css
|
|
31
|
+
AddType image/svg+xml .svg
|
|
32
|
+
AddType application/font-woff .woff
|
|
33
|
+
AddType application/font-woff2 .woff2
|
|
34
|
+
|
|
35
|
+
# ============================================
|
|
36
|
+
# Páginas de Erro Personalizadas
|
|
37
|
+
# ============================================
|
|
38
|
+
ErrorDocument 404 /errors/404.html
|
|
39
|
+
ErrorDocument 500 /errors/500.html
|
|
40
|
+
ErrorDocument 403 /errors/403.html
|
|
41
|
+
|
|
42
|
+
# ============================================
|
|
43
|
+
# Proteção de arquivos sensíveis
|
|
44
|
+
# ============================================
|
|
45
|
+
<FilesMatch "^\.">
|
|
46
|
+
Order allow,deny
|
|
47
|
+
Deny from all
|
|
48
|
+
</FilesMatch>
|
|
49
|
+
|
|
50
|
+
<FilesMatch "\.(env|ini|log|sh|sql|bak|config|dist|fla|inc|lock|psd|yml|yaml|json|xml|md)$">
|
|
51
|
+
Order allow,deny
|
|
52
|
+
Deny from all
|
|
53
|
+
</FilesMatch>
|
|
54
|
+
|
|
55
|
+
# Bloquear acesso a arquivos de backup e sensíveis
|
|
56
|
+
<FilesMatch "(^#.*#|\.(bak|conf|dist|fla|in[ci]|log|orig|psd|sh|sql|sw[op])|~)$">
|
|
57
|
+
Order allow,deny
|
|
58
|
+
Deny from all
|
|
59
|
+
</FilesMatch>
|
|
60
|
+
|
|
61
|
+
# Bloquear acesso ao composer e package
|
|
62
|
+
<FilesMatch "(composer\.(json|lock)|package(-lock)?\.json)$">
|
|
63
|
+
Order allow,deny
|
|
64
|
+
Deny from all
|
|
65
|
+
</FilesMatch>
|
|
66
|
+
|
|
67
|
+
# ============================================
|
|
68
|
+
# Proteção contra SQL Injection e XSS
|
|
69
|
+
# ============================================
|
|
70
|
+
<IfModule mod_rewrite.c>
|
|
71
|
+
# Bloquear tentativas de SQL Injection
|
|
72
|
+
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
|
|
73
|
+
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
|
|
74
|
+
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) [OR]
|
|
75
|
+
RewriteCond %{QUERY_STRING} proc/self/environ [OR]
|
|
76
|
+
RewriteCond %{QUERY_STRING} (\.\./)+ [OR]
|
|
77
|
+
RewriteCond %{QUERY_STRING} (boot\.ini|etc/passwd|self/environ) [NC,OR]
|
|
78
|
+
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
|
|
79
|
+
RewriteCond %{QUERY_STRING} (\||\||`|;|,|\^|\\|\0|00|mosConfig_[a-zA-Z_]{1,21}(=|\%3D)) [OR]
|
|
80
|
+
RewriteCond %{QUERY_STRING} (union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode) [NC]
|
|
81
|
+
RewriteRule .* - [F]
|
|
82
|
+
</IfModule>
|
|
83
|
+
|
|
84
|
+
# ============================================
|
|
85
|
+
# Cache de navegador para arquivos estáticos
|
|
86
|
+
# ============================================
|
|
87
|
+
<IfModule mod_expires.c>
|
|
88
|
+
ExpiresActive On
|
|
89
|
+
|
|
90
|
+
# Imagens
|
|
91
|
+
ExpiresByType image/jpg "access plus 1 month"
|
|
92
|
+
ExpiresByType image/jpeg "access plus 1 month"
|
|
93
|
+
ExpiresByType image/gif "access plus 1 month"
|
|
94
|
+
ExpiresByType image/png "access plus 1 month"
|
|
95
|
+
ExpiresByType image/webp "access plus 1 month"
|
|
96
|
+
ExpiresByType image/svg+xml "access plus 1 month"
|
|
97
|
+
ExpiresByType image/x-icon "access plus 1 year"
|
|
98
|
+
|
|
99
|
+
# CSS e JavaScript
|
|
100
|
+
ExpiresByType text/css "access plus 1 week"
|
|
101
|
+
ExpiresByType application/javascript "access plus 1 week"
|
|
102
|
+
|
|
103
|
+
# Fontes
|
|
104
|
+
ExpiresByType application/font-woff "access plus 1 month"
|
|
105
|
+
ExpiresByType application/font-woff2 "access plus 1 month"
|
|
106
|
+
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
|
|
107
|
+
ExpiresByType font/ttf "access plus 1 month"
|
|
108
|
+
</IfModule>
|
|
109
|
+
|
|
110
|
+
# ============================================
|
|
111
|
+
# Compressão GZIP
|
|
112
|
+
# ============================================
|
|
113
|
+
<IfModule mod_deflate.c>
|
|
114
|
+
AddOutputFilterByType DEFLATE text/html
|
|
115
|
+
AddOutputFilterByType DEFLATE text/css
|
|
116
|
+
AddOutputFilterByType DEFLATE text/javascript
|
|
117
|
+
AddOutputFilterByType DEFLATE text/xml
|
|
118
|
+
AddOutputFilterByType DEFLATE text/plain
|
|
119
|
+
AddOutputFilterByType DEFLATE application/javascript
|
|
120
|
+
AddOutputFilterByType DEFLATE application/json
|
|
121
|
+
AddOutputFilterByType DEFLATE application/xml
|
|
122
|
+
AddOutputFilterByType DEFLATE application/xhtml+xml
|
|
123
|
+
AddOutputFilterByType DEFLATE image/svg+xml
|
|
124
|
+
</IfModule>
|
|
125
|
+
|
|
126
|
+
# ============================================
|
|
127
|
+
# Headers de segurança avançados
|
|
128
|
+
# ============================================
|
|
129
|
+
<IfModule mod_headers.c>
|
|
130
|
+
# Prevenir clickjacking
|
|
131
|
+
Header always set X-Frame-Options "SAMEORIGIN"
|
|
132
|
+
|
|
133
|
+
# Prevenir XSS
|
|
134
|
+
Header always set X-XSS-Protection "1; mode=block"
|
|
135
|
+
|
|
136
|
+
# Prevenir MIME sniffing
|
|
137
|
+
Header always set X-Content-Type-Options "nosniff"
|
|
138
|
+
|
|
139
|
+
# Política de referrer
|
|
140
|
+
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
|
141
|
+
|
|
142
|
+
# Permissions Policy (substituiu Feature-Policy)
|
|
143
|
+
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()"
|
|
144
|
+
|
|
145
|
+
# Content Security Policy (CSP) - Modo permissivo para desenvolvimento
|
|
146
|
+
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: https:; font-src 'self' https://cdn.jsdelivr.net; connect-src 'self'; frame-ancestors 'self';"
|
|
147
|
+
|
|
148
|
+
# Strict Transport Security (HSTS) - Descomente em produção com HTTPS
|
|
149
|
+
# Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
150
|
+
|
|
151
|
+
# Remover assinatura do servidor
|
|
152
|
+
Header always unset X-Powered-By
|
|
153
|
+
Header always unset Server
|
|
154
|
+
</IfModule>
|
|
155
|
+
|
|
156
|
+
# ============================================
|
|
157
|
+
# Configurações PHP via htaccess
|
|
158
|
+
# ============================================
|
|
159
|
+
<IfModule mod_php.c>
|
|
160
|
+
php_value upload_max_filesize 100M
|
|
161
|
+
php_value post_max_size 100M
|
|
162
|
+
php_value max_execution_time 300
|
|
163
|
+
php_value max_input_time 300
|
|
164
|
+
php_value memory_limit 512M
|
|
165
|
+
</IfModule>
|
|
166
|
+
|
|
167
|
+
# ============================================
|
|
168
|
+
# Regras de reescrita para frameworks
|
|
169
|
+
# Descomente conforme necessário
|
|
170
|
+
# ============================================
|
|
171
|
+
|
|
172
|
+
# Laravel / Lumen
|
|
173
|
+
# RewriteCond %{REQUEST_FILENAME} !-d
|
|
174
|
+
# RewriteCond %{REQUEST_FILENAME} !-f
|
|
175
|
+
# RewriteRule ^ index.php [L]
|
|
176
|
+
|
|
177
|
+
# WordPress
|
|
178
|
+
# RewriteRule ^index\.php$ - [L]
|
|
179
|
+
# RewriteCond %{REQUEST_FILENAME} !-f
|
|
180
|
+
# RewriteCond %{REQUEST_FILENAME} !-d
|
|
181
|
+
# RewriteRule . /index.php [L]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="pt-BR">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>403 - Acesso Proibido</title>
|
|
7
|
+
<style>
|
|
8
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
+
body {
|
|
10
|
+
font-family: 'Segoe UI', Tahoma, sans-serif;
|
|
11
|
+
background: linear-gradient(135deg, #f39c12 0%, #d68910 100%);
|
|
12
|
+
min-height: 100vh;
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
color: white;
|
|
17
|
+
text-align: center;
|
|
18
|
+
}
|
|
19
|
+
.container { padding: 2rem; }
|
|
20
|
+
h1 { font-size: 8rem; margin-bottom: 1rem; text-shadow: 2px 2px 10px rgba(0,0,0,0.2); }
|
|
21
|
+
h2 { font-size: 2rem; margin-bottom: 1rem; }
|
|
22
|
+
p { font-size: 1.2rem; margin-bottom: 2rem; opacity: 0.8; }
|
|
23
|
+
a {
|
|
24
|
+
display: inline-block;
|
|
25
|
+
padding: 1rem 2rem;
|
|
26
|
+
background: white;
|
|
27
|
+
color: #f39c12;
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
border-radius: 50px;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
transition: transform 0.3s, box-shadow 0.3s;
|
|
32
|
+
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
|
|
33
|
+
}
|
|
34
|
+
a:hover {
|
|
35
|
+
transform: scale(1.05);
|
|
36
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<div class="container">
|
|
42
|
+
<h1>403</h1>
|
|
43
|
+
<h2>Acesso Proibido</h2>
|
|
44
|
+
<p>Você não tem permissão para acessar este recurso.</p>
|
|
45
|
+
<a href="/">Voltar ao Início</a>
|
|
46
|
+
</div>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="pt-BR">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>404 - Página não encontrada</title>
|
|
7
|
+
<style>
|
|
8
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
+
body {
|
|
10
|
+
font-family: 'Segoe UI', Tahoma, sans-serif;
|
|
11
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
12
|
+
min-height: 100vh;
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
color: white;
|
|
17
|
+
text-align: center;
|
|
18
|
+
}
|
|
19
|
+
.container { padding: 2rem; }
|
|
20
|
+
h1 { font-size: 8rem; margin-bottom: 1rem; text-shadow: 2px 2px 10px rgba(0,0,0,0.2); }
|
|
21
|
+
h2 { font-size: 2rem; margin-bottom: 1rem; }
|
|
22
|
+
p { font-size: 1.2rem; margin-bottom: 2rem; opacity: 0.8; }
|
|
23
|
+
a {
|
|
24
|
+
display: inline-block;
|
|
25
|
+
padding: 1rem 2rem;
|
|
26
|
+
background: white;
|
|
27
|
+
color: #667eea;
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
border-radius: 50px;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
transition: transform 0.3s, box-shadow 0.3s;
|
|
32
|
+
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
|
|
33
|
+
}
|
|
34
|
+
a:hover {
|
|
35
|
+
transform: scale(1.05);
|
|
36
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<div class="container">
|
|
42
|
+
<h1>404</h1>
|
|
43
|
+
<h2>Página não encontrada</h2>
|
|
44
|
+
<p>A página que você está procurando não existe ou foi movida.</p>
|
|
45
|
+
<a href="/">Voltar ao Início</a>
|
|
46
|
+
</div>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="pt-BR">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>500 - Erro Interno do Servidor</title>
|
|
7
|
+
<style>
|
|
8
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
+
body {
|
|
10
|
+
font-family: 'Segoe UI', Tahoma, sans-serif;
|
|
11
|
+
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
|
12
|
+
min-height: 100vh;
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
color: white;
|
|
17
|
+
text-align: center;
|
|
18
|
+
}
|
|
19
|
+
.container { padding: 2rem; }
|
|
20
|
+
h1 { font-size: 8rem; margin-bottom: 1rem; text-shadow: 2px 2px 10px rgba(0,0,0,0.2); }
|
|
21
|
+
h2 { font-size: 2rem; margin-bottom: 1rem; }
|
|
22
|
+
p { font-size: 1.2rem; margin-bottom: 2rem; opacity: 0.8; }
|
|
23
|
+
a {
|
|
24
|
+
display: inline-block;
|
|
25
|
+
padding: 1rem 2rem;
|
|
26
|
+
background: white;
|
|
27
|
+
color: #e74c3c;
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
border-radius: 50px;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
transition: transform 0.3s, box-shadow 0.3s;
|
|
32
|
+
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
|
|
33
|
+
}
|
|
34
|
+
a:hover {
|
|
35
|
+
transform: scale(1.05);
|
|
36
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<div class="container">
|
|
42
|
+
<h1>500</h1>
|
|
43
|
+
<h2>Erro Interno do Servidor</h2>
|
|
44
|
+
<p>Algo deu errado. Por favor, tente novamente mais tarde.</p>
|
|
45
|
+
<a href="/">Voltar ao Início</a>
|
|
46
|
+
</div>
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|