deleted: Dockerfile.certbot

deleted:    Dockerfile.nginx
	modified:   Makefile
	modified:   README.md
	deleted:    compose.certbot.yml
	modified:   docker-compose.yml
	deleted:    entrypoint-certbot.sh
	deleted:    entrypoint-nginx.sh
	deleted:    nginx-gitea.conf.template
	deleted:    nginx.conf.template
	new file:   proxy/Caddyfile
	new file:   proxy/limiter.toml
	new file:   searx/.env
	new file:   searx/.env.example
	new file:   searx/core-config/limiter.toml
	new file:   searx/limiter.toml
	new file:   web/Caddyfile
This commit is contained in:
viljarb
2026-07-07 15:14:28 +00:00
parent f506d339a3
commit d6e0b550a9
17 changed files with 167 additions and 227 deletions

View File

@@ -1,6 +0,0 @@
FROM certbot/certbot
COPY entrypoint-certbot.sh /entrypoint-certbot.sh
RUN chmod +x /entrypoint-certbot.sh
ENTRYPOINT ["/entrypoint-certbot.sh"]

View File

@@ -1,27 +0,0 @@
FROM nginx:alpine
ARG DOMAIN
ARG EMAIL
ARG GITEA_DOMAIN
ENV DOMAIN=${DOMAIN}
ENV EMAIL=${EMAIL}
ENV GITEA_DOMAIN=${GITEA_DOMAIN}
# Install gettext (for envsubst) and openssl
RUN apk add --no-cache gettext openssl
# Copy nginx config templates (generated at runtime with envsubst)
COPY nginx.conf.template /etc/nginx/nginx.conf.template
COPY nginx-gitea.conf.template /etc/nginx/nginx-gitea.conf.template
# Copy HTML content
COPY html /usr/share/nginx/html
# Copy and set up entrypoint
COPY entrypoint-nginx.sh /entrypoint-nginx.sh
RUN chmod +x /entrypoint-nginx.sh
EXPOSE 80 443
ENTRYPOINT ["/entrypoint-nginx.sh"]
CMD ["nginx", "-g", "daemon off;"]

11
Makefile Executable file → Normal file
View File

@@ -1,11 +1,8 @@
dev:
docker compose up --build
up:
docker compose up -d --build
down:
docker compose down
up:
DOMAIN=viljarb.online GITEA_DOMAIN=gitea.viljarb.online GITEA_ROOT_URL=https://gitea.viljarb.online/ EMAIL=viljarb@tutanota.com docker compose -f compose.certbot.yml --profile certbot run --rm certbot
DOMAIN=viljarb.online GITEA_DOMAIN=gitea.viljarb.online GITEA_ROOT_URL=https://gitea.viljarb.online/ EMAIL=viljarb@tutanota.com docker compose up --build -d
restart: down up
restart: down up

View File

@@ -1,6 +1,3 @@
# site
## folders
* *html*: website run by nginx
* *gitea*: gitea data
* *logs*: all logs in one place
This is my personal site.

View File

@@ -1,22 +0,0 @@
services:
certbot:
profiles:
- certbot # Only run via: docker compose --profile certbot run --rm certbot
network_mode: host
build:
context: .
dockerfile: Dockerfile.certbot
environment:
- DOMAIN=${DOMAIN}
- EMAIL=${EMAIL}
- GITEA_DOMAIN=${GITEA_DOMAIN}
volumes:
- certs:/etc/letsencrypt
ports:
- "80:80"
restart: "no"
volumes:
certs:

View File

@@ -1,40 +1,58 @@
networks:
default:
external: false
services:
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
args:
- DOMAIN=${DOMAIN}
- EMAIL=${EMAIL}
- GITEA_DOMAIN=${GITEA_DOMAIN}
environment:
- DOMAIN=${DOMAIN}
- EMAIL=${EMAIL}
- GITEA_DOMAIN=${GITEA_DOMAIN}
networks:
- default
web:
image: caddy:latest
restart: always
volumes:
- certs:/etc/letsencrypt
- ./html:/usr/share/nginx/html
- ./logs:/var/log/nginx/visitors
- ./web/html:/srv/html
- ./web/Caddyfile:/etc/caddy/Caddyfile
proxy:
image: caddy:latest
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./proxy/Caddyfile:/etc/caddy/Caddyfile
- ./proxy/data:/data
- ./proxy/config:/config
depends_on:
- web
- searxng-core
- searxng-valkey
- gitea
searxng-core:
container_name: searxng-core
image: docker.io/searxng/searxng:${SEARXNG_VERSION:-latest}
restart: always
env_file: ./searx/.env
networks:
- default
volumes:
- ./searx/core-config/:/etc/searxng/:Z
- ./searx/core-data:/var/cache/searxng/
- ./searx/limiter.toml:/etc/searxng/limiter.toml:Z
searxng-valkey:
container_name: searxng-valkey
image: docker.io/valkey/valkey:9-alpine
command: valkey-server --save 30 1 --loglevel warning
restart: always
networks:
- default
volumes:
- ./searx/valkey-data:/data/
gitea:
image: docker.io/gitea/gitea
environment:
- USER_UID=1000
- USER_GID=1000
- ROOT_URL=${GITEA_ROOT_URL}
- DOMAIN=${GITEA_DOMAIN}
- SSH_DOMAIN=${GITEA_DOMAIN}
- ROOT_URL=https://gitea.viljarb.online
- DOMAIN=gitea.viljarb.online
- SSH_DOMAIN=gitea.viljarb.online
- SSH_PORT=2222
- GITEA__log__ROOT_PATH=/var/log/gitea
- GITEA__log__MODE=file
@@ -43,15 +61,8 @@ services:
- default
volumes:
- ./gitea:/data
- ./logs:/var/log/gitea
- ./gitea/logs:/var/log/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "4000:3000"
- "2222:2222"
volumes:
certs:

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env sh
set -e
if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ]; then
echo "Skipping certificate (development mode)"
exit 0
fi
# Build domain list for cert (DOMAIN + optional GITEA_DOMAIN)
DOMAINS="-d $DOMAIN"
if [ -n "$GITEA_DOMAIN" ]; then
DOMAINS="$DOMAINS -d $GITEA_DOMAIN"
fi
# get/renew cert
certbot certonly --standalone \
$DOMAINS \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--keep-until-expiring

View File

@@ -1,41 +0,0 @@
#!/usr/bin/env sh
set -e
if [ -n "$DOMAIN" ] && [ -n "$EMAIL" ]; then
# for production: get Let's Encrypt cert
if [ ! -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]; then
certbot certonly --standalone \
-d "$DOMAIN" \
--email "$EMAIL" \
--agree-tos \
--non-interactive
fi
export SSL_CERTIFICATE="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
export SSL_CERTIFICATE_KEY="/etc/letsencrypt/live/$DOMAIN/privkey.pem"
else
# for development: self-signed cert
echo "Development mode: using self-signed certificate"
mkdir -p /etc/nginx/certs
if [ ! -f /etc/nginx/certs/cert.pem ]; then
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/certs/key.pem \
-out /etc/nginx/certs/cert.pem \
-subj "/CN=localhost"
fi
export DOMAIN="localhost"
export SSL_CERTIFICATE="/etc/nginx/certs/cert.pem"
export SSL_CERTIFICATE_KEY="/etc/nginx/certs/key.pem"
fi
# generate nginx config from template
envsubst '${DOMAIN} ${SSL_CERTIFICATE} ${SSL_CERTIFICATE_KEY}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
# generate gitea config when GITEA_DOMAIN is set
mkdir -p /etc/nginx/conf.d
if [ -n "$GITEA_DOMAIN" ]; then
envsubst '${GITEA_DOMAIN} ${SSL_CERTIFICATE} ${SSL_CERTIFICATE_KEY}' < /etc/nginx/nginx-gitea.conf.template > /etc/nginx/conf.d/gitea.conf
else
echo "# Gitea not configured" > /etc/nginx/conf.d/gitea.conf
fi
exec nginx -g "daemon off;"

View File

@@ -1,25 +0,0 @@
server {
listen 80;
server_name ${GITEA_DOMAIN};
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name ${GITEA_DOMAIN};
ssl_certificate ${SSL_CERTIFICATE};
ssl_certificate_key ${SSL_CERTIFICATE_KEY};
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://gitea:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}

View File

@@ -1,40 +0,0 @@
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format visitor_ip '$remote_addr - $time_iso8601';
access_log /var/log/nginx/visitors/visitors.log visitor_ip;
server {
listen 80;
server_name ${DOMAIN};
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name ${DOMAIN};
root /usr/share/nginx/html;
index index.html;
ssl_certificate ${SSL_CERTIFICATE};
ssl_certificate_key ${SSL_CERTIFICATE_KEY};
ssl_protocols TLSv1.2 TLSv1.3;
location / {
try_files $uri $uri/ /index.html;
}
}
include /etc/nginx/conf.d/gitea.conf;
}

25
proxy/Caddyfile Normal file
View File

@@ -0,0 +1,25 @@
viljarb.online {
reverse_proxy web:80
}
www.viljarb.online {
reverse_proxy web:80
}
gitea.viljarb.online {
reverse_proxy gitea:3000
}
searx.viljarb.online {
reverse_proxy searxng-core:8080 {
header_up X-Real-IP {http.request.remote.host}
header_up X-Forwarded-For {http.request.remote.host}
header_up X-Forwarded-Proto {http.request.scheme}
header_up X-Forwarded-Port {http.request.port}
header_up Connection "close"
}
}
localhost:80 {
respond "this is localhost"
}
localhost:81 {
respond "this is another localhost"
}

27
proxy/limiter.toml Normal file
View File

@@ -0,0 +1,27 @@
[botdetection]
ipv4_prefix = 32
ipv6_prefix = 48
# Trust the Caddy reverse proxy on the docker network.
trusted_proxies = [
"127.0.0.0/8",
"::1",
"172.16.0.0/12",
"10.0.0.0/8",
]
[botdetection.ip_limit]
filter_link_local = false
link_token = false
[botdetection.ip_lists]
block_ip = [
]
pass_ip = [
]
pass_searxng_org = true

19
searx/.env Normal file
View File

@@ -0,0 +1,19 @@
# Read the documentation before using the `docker-compose.yml` file:
# https://docs.searxng.org/admin/installation-docker.html
#
# Additional ENVs:
# https://docs.searxng.org/admin/settings/settings_general.html#settings-general
# https://docs.searxng.org/admin/settings/settings_server.html#settings-server
# Use a specific version tag. E.g. "latest" or "2026.3.25-541c6c3cb".
# 2026.5.31 has a SQLite init race that breaks the radio browser engine on startup.
SEARXNG_VERSION=latest
# Listen to a specific address.
#SEARXNG_HOST=[::]
# Listen to a specific port.
#SEARXNG_PORT=8080
# Public URL of the instance (served behind the reverse proxy).
SEARXNG_BASE_URL=https://searx.viljarb.online/

15
searx/.env.example Normal file
View File

@@ -0,0 +1,15 @@
# Read the documentation before using the `docker-compose.yml` file:
# https://docs.searxng.org/admin/installation-docker.html
#
# Additional ENVs:
# https://docs.searxng.org/admin/settings/settings_general.html#settings-general
# https://docs.searxng.org/admin/settings/settings_server.html#settings-server
# Use a specific version tag. E.g. "latest" or "2026.3.25-541c6c3cb".
#SEARXNG_VERSION=latest
# Listen to a specific address.
#SEARXNG_HOST=[::]
# Listen to a specific port.
#SEARXNG_PORT=8080

View File

27
searx/limiter.toml Normal file
View File

@@ -0,0 +1,27 @@
[botdetection]
ipv4_prefix = 32
ipv6_prefix = 48
# Trust the Caddy reverse proxy on the docker network.
trusted_proxies = [
"127.0.0.0/8",
"::1",
"172.16.0.0/12",
"10.0.0.0/8",
]
[botdetection.ip_limit]
filter_link_local = false
link_token = false
[botdetection.ip_lists]
block_ip = [
]
pass_ip = [
]
pass_searxng_org = true

4
web/Caddyfile Normal file
View File

@@ -0,0 +1,4 @@
:80 {
root * /srv/html
file_server
}