Compare commits
29 Commits
Author | SHA1 | Date |
---|---|---|
|
beec72aed7 | |
|
b1d1eb47bf | |
|
2e5c1840c0 | |
|
2f01b4e822 | |
|
720e1c990a | |
|
78fc664a8c | |
|
525c8a11f9 | |
|
adc1726374 | |
|
7993539c96 | |
|
61366ac398 | |
|
3fca1a2c2e | |
|
45534502e8 | |
|
cd0092400a | |
|
48e3f5c0cb | |
|
8cbfa8a625 | |
|
677d64c3ba | |
|
46ba214a1f | |
|
3873bda1dd | |
|
caafc6133d | |
|
0c8953939f | |
|
d7ce2fd7e6 | |
|
de6d777005 | |
|
f793d9f93c | |
|
cd11385e1c | |
|
df315f1678 | |
|
92a298c487 | |
|
1627bc7df9 | |
|
200087fee3 | |
|
84177800c5 |
|
@ -1,3 +1,4 @@
|
||||||
|
# build 0
|
||||||
labels:
|
labels:
|
||||||
location: manager
|
location: manager
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
resume:
|
lucky-ddg:
|
||||||
build:
|
build:
|
||||||
context: ./docker/resume/
|
context: ./docker/lucky-ddg/
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
image: git.nixc.us/colin/resume:production
|
image: git.nixc.us/nixius/lucky-ddg:production
|
|
@ -1,8 +1,6 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
resume:
|
lucky-ddg:
|
||||||
build:
|
build:
|
||||||
context: ./docker/resume/
|
context: ./docker/lucky-ddg/
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
image: git.nixc.us/colin/resume:staging
|
image: git.nixc.us/nixius/lucky-ddg:staging
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Use the official Python image from Docker Hub
|
||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Install duckduckgo_search globally
|
||||||
|
RUN pip install --no-cache-dir duckduckgo_search
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy the application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Expose the Flask port
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
CMD ["python", "app.py"]
|
|
@ -0,0 +1,30 @@
|
||||||
|
import subprocess
|
||||||
|
from flask import Flask, request, redirect
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route('/search')
|
||||||
|
def search():
|
||||||
|
query = request.args.get('q')
|
||||||
|
if not query:
|
||||||
|
return "Query parameter 'q' is missing.", 400
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Execute the ddgs CLI command to perform the search
|
||||||
|
result = subprocess.run(
|
||||||
|
['ddgs', 'text', '-k', query, '-m', '1'],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True
|
||||||
|
)
|
||||||
|
# Parse the output to extract the first result URL
|
||||||
|
output_lines = result.stdout.splitlines()
|
||||||
|
for line in output_lines:
|
||||||
|
if line.startswith('http'):
|
||||||
|
return redirect(line)
|
||||||
|
return "No results found.", 404
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
return f"An error occurred: {e}", 500
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0', port=5000)
|
|
@ -0,0 +1 @@
|
||||||
|
flask==2.2.2
|
|
@ -1,5 +0,0 @@
|
||||||
FROM nginx:alpine
|
|
||||||
RUN rm /etc/nginx/conf.d/default.conf
|
|
||||||
COPY nginx.conf /etc/nginx/conf.d/
|
|
||||||
COPY resume.html /usr/share/nginx/html/
|
|
||||||
EXPOSE 8080
|
|
|
@ -1,53 +0,0 @@
|
||||||
# Use $request_id as a pseudo-nonce for Content Security Policy (CSP)
|
|
||||||
map $request_id $nonce {
|
|
||||||
default "$request_id";
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 8080;
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index resume.html;
|
|
||||||
|
|
||||||
# Security headers
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
|
||||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
||||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), accelerometer=(), gyroscope=(), magnetometer=(), payment=(), usb=()" always;
|
|
||||||
|
|
||||||
# Updated Content Security Policy (CSP) with 'unsafe-inline' temporarily for style-src
|
|
||||||
add_header Content-Security-Policy "
|
|
||||||
default-src 'none';
|
|
||||||
script-src 'self' 'nonce-$nonce' https://matomo.nixc.us https://gist.github.com https://assets-cdn.github.com;
|
|
||||||
style-src 'self' 'nonce-$nonce' https://colinknapp.com https://getbootstrap.com https://fonts.googleapis.com 'unsafe-inline';
|
|
||||||
img-src 'self' https://matomo.nixc.us https://colinknapp.com https://hedgedoc.nixc.us https://assets-cdn.github.com https://github.com https://forkaweso.me https://ionicons.com https://twitter.com data:;
|
|
||||||
font-src 'self' https://fonts.gstatic.com https://github.com https://forkaweso.me data:;
|
|
||||||
connect-src 'self' https://matomo.nixc.us;
|
|
||||||
frame-ancestors 'self';
|
|
||||||
base-uri 'self';
|
|
||||||
form-action 'self';
|
|
||||||
" always;
|
|
||||||
|
|
||||||
# Cross-origin isolation headers
|
|
||||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
|
||||||
add_header Cross-Origin-Resource-Policy "same-origin" always;
|
|
||||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
|
||||||
|
|
||||||
# Apply CORP header for the apple-touch-icon to allow cross-origin access
|
|
||||||
location /icons/apple-touch-icon.png {
|
|
||||||
add_header Cross-Origin-Resource-Policy "cross-origin";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Use sub_filter to inject the nonce into inline <script> and <style> tags automatically
|
|
||||||
sub_filter '<script>' '<script nonce="$nonce">';
|
|
||||||
sub_filter '<style>' '<style nonce="$nonce">';
|
|
||||||
sub_filter_once off;
|
|
||||||
sub_filter_types text/html;
|
|
||||||
|
|
||||||
# Redirect demo.hedgedoc.org resources to hedgedoc.nixc.us
|
|
||||||
sub_filter "https://demo.hedgedoc.org" "https://hedgedoc.nixc.us";
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ =404;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -3,12 +3,12 @@ networks:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
resume:
|
lucky:
|
||||||
image: git.nixc.us/colin/resume:production
|
image: git.nixc.us/nixius/lucky-ddg:production
|
||||||
deploy:
|
deploy:
|
||||||
placement:
|
# placement:
|
||||||
constraints:
|
# constraints:
|
||||||
- node.hostname == ingress.nixc.us
|
# - node.hostname == ingress.nixc.us
|
||||||
update_config:
|
update_config:
|
||||||
order: start-first
|
order: start-first
|
||||||
# failure_action: rollback
|
# failure_action: rollback
|
||||||
|
@ -19,12 +19,12 @@ services:
|
||||||
labels:
|
labels:
|
||||||
us.nixc.autodeploy: "true"
|
us.nixc.autodeploy: "true"
|
||||||
traefik.enable: "true"
|
traefik.enable: "true"
|
||||||
traefik.http.routers.production_resume.tls: "true"
|
traefik.http.routers.production_lucky-ddg.tls: "true"
|
||||||
traefik.http.services.production_resume.loadbalancer.server.port: "8080"
|
traefik.http.services.production_lucky-ddg.loadbalancer.server.port: "5000"
|
||||||
traefik.http.routers.production_resume.rule: "Host(`resume.colinknapp.com`, `colinknapp.com`)"
|
traefik.http.routers.production_lucky-ddg.rule: "Host(`ddg.nixc.us`)"
|
||||||
traefik.http.routers.production_resume.entrypoints: "websecure"
|
traefik.http.routers.production_lucky-ddg.entrypoints: "websecure"
|
||||||
traefik.http.routers.production_resume.tls.certresolver: "letsencryptresolver"
|
traefik.http.routers.production_lucky-ddg.tls.certresolver: "letsencryptresolver"
|
||||||
traefik.http.routers.production_resume.service: "production_resume"
|
traefik.http.routers.production_lucky-ddg.service: "production_lucky-ddg"
|
||||||
traefik.docker.network: "traefik"
|
traefik.docker.network: "traefik"
|
||||||
networks:
|
networks:
|
||||||
traefik:
|
traefik:
|
||||||
|
|
|
@ -1,38 +1,30 @@
|
||||||
version: "3.7"
|
|
||||||
networks:
|
networks:
|
||||||
traefik:
|
traefik:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
resume:
|
resume:
|
||||||
image: git.nixc.us/colin/resume:staging
|
image: git.nixc.us/nixius/lucky-ddg:production
|
||||||
deploy:
|
deploy:
|
||||||
placement:
|
# placement:
|
||||||
constraints:
|
# constraints:
|
||||||
- node.hostname == ingress.nixc.us
|
# - node.hostname == ingress.nixc.us
|
||||||
update_config:
|
update_config:
|
||||||
order: start-first
|
order: start-first
|
||||||
failure_action: rollback
|
# failure_action: rollback
|
||||||
delay: 5s
|
delay: 0s
|
||||||
delay: 10s
|
|
||||||
parallelism: 1
|
parallelism: 1
|
||||||
restart_policy:
|
restart_policy:
|
||||||
condition: on-failure
|
condition: on-failure
|
||||||
labels:
|
labels:
|
||||||
us.nixc.autodeploy: "true"
|
us.nixc.autodeploy: "true"
|
||||||
traefik.enable: "true"
|
traefik.enable: "true"
|
||||||
traefik.http.routers.staging_resume.tls: "true"
|
traefik.http.routers.production_lucky-ddg.tls: "true"
|
||||||
traefik.http.services.staging_resume.loadbalancer.server.port: "8080"
|
traefik.http.services.production_lucky-ddg.loadbalancer.server.port: "5000"
|
||||||
traefik.http.routers.staging_resume.rule: "Host(`staging.resume.colinknapp.com`, `staging.colinknapp.com`)"
|
traefik.http.routers.production_lucky-ddg.rule: "Host(`ddg.staging.nixc.us`)"
|
||||||
traefik.http.routers.staging_resume.entrypoints: "websecure"
|
traefik.http.routers.production_lucky-ddg.entrypoints: "websecure"
|
||||||
traefik.http.routers.staging_resume.tls.certresolver: "letsencryptresolver"
|
traefik.http.routers.production_lucky-ddg.tls.certresolver: "letsencryptresolver"
|
||||||
traefik.http.routers.staging_resume.service: "staging_resume"
|
traefik.http.routers.production_lucky-ddg.service: "production_lucky-ddg"
|
||||||
traefik.docker.network: "traefik"
|
traefik.docker.network: "traefik"
|
||||||
# traefik.http.routers.staging_resume.middlewares: "authelia@docker"
|
|
||||||
networks:
|
networks:
|
||||||
traefik:
|
traefik:
|
||||||
# logging:
|
|
||||||
# driver: "gelf"
|
|
||||||
# options:
|
|
||||||
# gelf-address: "udp://log.nixc.us:15124"
|
|
||||||
# tag: "resume_resume"
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue