modified: .gitignore

new file:   Dockerfile.certbot
	new file:   Dockerfile.nginx
	new file:   Makefile
	new file:   compose.certbot.yml
	new file:   docker-compose.yml
	new file:   entrypoint-certbot.sh
	new file:   entrypoint-nginx.sh
	new file:   nginx-gitea.conf.template
	new file:   nginx.conf.template
This commit is contained in:
viljarb
2026-03-31 13:25:18 +02:00
parent ebfbce7cd2
commit 28212b9d5d
10 changed files with 272 additions and 0 deletions

6
.gitignore vendored
View File

@@ -1,5 +1,11 @@
.vscode/*
.vscode/**/*
gitea
gitea/*
gitea/**
html
html/*
html/**
logs
logs/*
logs/**

6
Dockerfile.certbot Normal file
View File

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

27
Dockerfile.nginx Normal file
View File

@@ -0,0 +1,27 @@
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
View File

@@ -0,0 +1,11 @@
dev:
docker compose up --build
down:
docker compose down
cert:
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
prod:
DOMAIN=viljarb.online GITEA_DOMAIN=gitea.viljarb.online GITEA_ROOT_URL=https://gitea.viljarb.online/ EMAIL=viljarb@tutanota.com docker compose up --build

22
compose.certbot.yml Normal file
View File

@@ -0,0 +1,22 @@
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:

73
docker-compose.yml Normal file
View File

@@ -0,0 +1,73 @@
networks:
default:
external: false
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"
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
volumes:
- certs:/etc/letsencrypt
- ./html:/usr/share/nginx/html
- ./logs:/var/log/nginx/visitors
ports:
- "80:80"
- "443:443"
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}
- SSH_PORT=2222
- GITEA__log__ROOT_PATH=/var/log/gitea
- GITEA__log__MODE=file
restart: always
networks:
- default
volumes:
- ./gitea:/data
- ./logs:/var/log/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "4000:3000"
- "2222:2222"
volumes:
certs:

21
entrypoint-certbot.sh Normal file
View File

@@ -0,0 +1,21 @@
#!/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

41
entrypoint-nginx.sh Normal file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env sh
set -e
if [ -n "$DOMAIN" ] && [ -n "$EMAIL" ]; then
# 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
# 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;"

25
nginx-gitea.conf.template Normal file
View File

@@ -0,0 +1,25 @@
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;
}
}

40
nginx.conf.template Normal file
View File

@@ -0,0 +1,40 @@
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;
}