今日已更新 35 条资讯 | 累计 37284 条内容
关于我们

标签:#ux

找到 254 篇相关文章

AI 资讯

The Same Setting, Three Different Answers: Why 0.0.0.0 Isn't Always What You Want

There is a line in almost every Python web tutorial that nobody explains: uvicorn main:app --host 0.0.0.0 --port 8000 I copied it for weeks without thinking about it. Then I deployed the same application three times — to a local VM, to a production server, and into a container — and the correct value was different every time. Twice it was 0.0.0.0 . Once, in the place that mattered most, it was not. That gap is worth writing about, because the setting itself is trivial and the reasoning behind it is not. What the Flag Actually Controls A server process doesn't "open a port." It creates a socket and binds it to an address. The bind address answers one question: which network interfaces should this socket accept connections from? A machine has more than one interface: lo (loopback) — reachable only from inside the machine ( 127.0.0.1 ). Packets addressed there never reach a physical network card; the kernel loops them straight back. 0.0.0.0 — a wildcard meaning every interface this machine has , including ones added later. So the flag isn't about security or convenience. It's about reachability — and reachability depends entirely on what sits in front of the process. Case 1: The Local VM — 0.0.0.0 I was running the service inside a Multipass VM and wanted to hit it from the browser on my laptop. The laptop is outside the VM, so binding to loopback would have made the service invisible to it. curl inside the VM would work; the browser outside would get connection refused. Decision: wildcard bind. Nothing sits in front of the process, and nothing needs protecting. Case 2: Production — 127.0.0.1 Here I copied the same line at first, and it was wrong. The production box has a public IP. Binding to 0.0.0.0 there means the application is directly exposed to the internet: no TLS, no rate limiting, no authentication. Within hours of provisioning that server, its SSH logs showed hundreds of automated login attempts against usernames like admin and oracle . The same scanners try

2026-08-07 原文 →
AI 资讯

How to Set Up Rate Limiting in Nuxt

Rate limiting is one of those things that doesn't feel urgent—until someone hammers your login endpoint at 3am and you wake up to a flooded database and a locked-out user base. I added this to my Nuxt base layer after realising I'd shipped several projects with zero protection on auth routes. Not great. This post walks through the exact setup I now use: Redis-backed, an in-memory fallback when Redis is down, named presets for different sensitivity levels, and a 429 page that shows a live countdown instead of just dying on the user. The structure Three pieces, each with one job: createRateLimiter() — a factory that builds the limiter, using Redis with an in-memory fallback applyRateLimit() — what you call inside handlers to enforce a limit server/middleware/rateLimiter.ts — global middleware so every route gets a baseline for free 1. Install npm install rate-limiter-flexible ioredis rate-limiter-flexible does the heavy lifting: sliding windows, Redis integration, and the insurance fallback pattern we'll use. 2. The factory Create server/utils/rateLimiter.ts : import { RateLimiterRedis , RateLimiterMemory , type RateLimiterAbstract , } from ' rate-limiter-flexible ' import { getRedisClient } from ' ./redis ' export interface RateLimiterConfig { keyPrefix : string // Must be unique per limiter, e.g. 'rl:auth' limit : number // Maximum requests within the window windowSeconds : number } export interface RateLimitResult { allowed : boolean limit : number remaining : number resetAt : number // Unix timestamp in seconds when the window resets retryAfter : number // Seconds until retry; 0 if allowed } function buildLimiter ( config : RateLimiterConfig , ): RateLimiterAbstract { const insurance = new RateLimiterMemory ({ keyPrefix : config . keyPrefix , points : config . limit , duration : config . windowSeconds , }) const redis = getRedisClient () if ( ! redis ) { return insurance } return new RateLimiterRedis ({ storeClient : redis , keyPrefix : config . keyPrefix , points

2026-08-07 原文 →
AI 资讯

The Privacy Summary Screen — 60 Minutes of Design With Outsized Impact

Most mobile apps ship a privacy policy as a link that opens Safari. A smaller number ship an in-app rendered policy. A tiny minority ship what I think is the single highest-leverage privacy screen: a summary that mirrors your Nutrition Label in plain language, designed to be read. Why it's high-leverage The privacy summary sits at the intersection of three concerns: Users read it before granting sensitive permissions. Especially for camera, contacts, location, and health data. App Store reviewers check it exists and matches your store listing. Regulators (GDPR, CCPA) reward it. Clarity is a compliance signal, not a legal defense — but it's what an investigator asks for first. Sixty minutes of design work. Meaningful trust dividends. Often the difference between first-submission approval and a rejection loop. What to include The privacy summary should mirror your Privacy Nutrition Label but with real language humans can parse: Each data category you collect — displayed as a card or a row, with a clear icon. Why you collect it — one line, plain language. "So you can log in on another device," not "for authentication purposes." Where it's used — is it stored on our servers, shared with third parties, only on your device? Be specific. How to opt out or delete it — a link or a button to the settings page where the user can act on that category. Six to eight cards, one per data category. No more. Visual patterns that read as trustworthy Design choices that consistently score high in user-testing for trust signal: Real language, not legalese. "We store your email address so you can log in" beats "Personal identifiers are retained for authentication purposes." Muted, confident colors. No warning reds, no compliance yellows. A neutral surface with soft accent for the data-category icons. Readable typography. 16pt body, generous line-height (1.5x), enough paragraph spacing that scanning is easy. Icons per category (not just text). A camera icon for camera data, a location pin

2026-08-06 原文 →
AI 资讯

Claude and Figma: bulk edits that don't break your file

I asked an agent to swap one colour value across a file. It did. It also rewrote the line that defined the value in the first place, so the definition now pointed at itself. Nothing errored. Nothing warned. The instruction ran perfectly, which is the whole problem. Every one of these has the same shape A single condition matched more than I meant, and everything that matched got changed. The second one I still think about: hiding a set of shadow rectangles also hid a keyboard, because the keyboard's parts satisfied exactly the same single condition. Again no error, again a clean report of success. Once you see the pattern it's everywhere. It isn't a model being careless. It's an instruction that was less precise than it felt while writing it, executed with total literalness by something that has no idea what any of these objects are for. The rule: scope, and two conditions, never one Name the region it may touch. Not "the file" — this section, these frames, this layer group. Then give it two properties that must both be true. Not "everything with this colour" but "everything with this colour, inside this region, that is a fill rather than a definition". The second condition is doing the real work: it's what stops the match spreading into things that happen to share one attribute. It's a small amount of extra writing. It's the difference between a change and an incident. It cannot see the result — that's the fixed constraint An agent writes the change, the change renders somewhere it has no eyes on, and it reports success based on the instruction completing rather than the outcome being right. People treat that missing feedback loop as a tooling problem, something that will be solved in a future version. I don't think it is one. It's a sequencing problem, and sequencing is available today. The loop can't be closed by the agent. Fine. It can still be closed by a person — just not a hundred times. One, then all Run the operation on a single representative case. Render

2026-08-06 原文 →
AI 资讯

Claude to Figma: keeping AI-generated UI bound to your design system

On one build I found 127 places bound to a raw colour instead of a named role. Every single one had passed visual review. They all surfaced the moment someone asked for dark mode. That number is the whole argument. Not because 127 is large, but because none of them looked wrong. A value that was typed in and a value that came from the system are visually identical. The difference only exists in what happens next. The failure isn't that the agent breaks the rules It's that it extends them. Give an agent a design system and ask it to build. When it reaches something the system covers, it uses the system — genuinely, reliably. When it reaches something the system doesn't cover, it does not stop and ask. It invents. And what it invents is a name that sounds exactly like one of yours, sitting right next to the real ones, reading as though someone chose it on purpose. That's why this is so hard to catch by eye. A fabricated token isn't a glaring error. It's a plausible one. Six months later nobody can tell you whether it was a deliberate exception or a hallucination, and by then five components depend on it. Readable is not the same as closed Making a library available to an agent gets you components it will reuse. It does not get you a closed set. A closed set means: these values exist, everything else does not, and anything outside them fails loudly rather than passing quietly. The distinction sounds pedantic and it decides everything. A readable system produces output that mostly matches. A closed system produces output you can audit. Which is the real test I'd apply to any AI design setup: not how much of your system it covers, but what happens to the things it doesn't cover. If those slip through silently, coverage is irrelevant — you've just made the drift harder to spot. Layers, and not reaching past them Tokens have layers for a reason. Base values underneath — the raw material. Named roles on top — what a value is for. And the product interface binds to the role,

2026-08-06 原文 →
AI 资讯

Figma MCP: turning Claude-generated UI into a component library

This is the stretch nobody films. The demo ends at the screenshot; the job ends about a week later, in a Figma file that someone else has to be able to open without you in the room. It's also where roughly 40% of the work lives, and where most AI-assisted design quietly falls over — not because the screens are bad, but because nothing in them is addressable. Import destroys the names Bring generated markup into Figma and everything arrives as a frame inside a frame inside a frame, with names that mean nothing. The structure survives. The meaning doesn't. The instinct at this point is to start componentising from what's on the canvas — find a button in a screen, make it a component, move on. Don't. That tree is a rendering artefact. Build your library from it and you inherit every accident in it: wrapper divs promoted to components, layout containers baked into masters, the same element modelled three different ways because it appeared in three different screens. The source markup is the specification. It knows what each thing is. So the first move is reading it and producing a record of what should exist and what it should be called — then renaming against that record, then componentising. Rename first, componentise second. Reversing those two costs more than any other ordering mistake in this stage. Library first, screens second Masters get built in a clean library section, not harvested from inside screens. The difference shows up in what ends up inside the component. Harvested masters carry their surroundings — a padding wrapper that belonged to the screen, a demo label, a background that existed to make it visible on a dark canvas. Those things then travel into every instance, and six months later somebody is asking why every card has eight pixels of phantom padding. Same-structure things get grouped into a variant set rather than left as separate components. A button that arrives as five unrelated components instead of one set is the single most common breakage

2026-08-06 原文 →
AI 资讯

The Mindset Behind Hard Debugging

Hard debugging is rarely defeated by a lack of tools. It is defeated by three quiet habits: assuming the fault is where the symptom appears, clinging to the first explanation, and hoping a tool will do the thinking. A difficult fault is usually lost to those habits before you read a line of code. The engineers who resolve hard faults are the ones who notice these defaults and replace them with a patient, evidence-first mindset. Most hard bugs are lost before we touch them, in the attitude we bring to the session. When something breaks, the average person rushes in with three quiet habits: they assume the fault lives exactly where it shows up, they cling to the first explanation their mind offers, and they hope a tool or a smarter person will tell them what to do next. Those habits feel natural, but on hard faults they are exactly what keep us stuck. Put two engineers on the same failing board. One finds a way through in an afternoon; the other is still going three days later. The difference is rarely raw intelligence or how many commands they know. It is the mental posture each brings to the work before the first step. Handling a hard debug session is less about knowing every tool and more about managing your own assumptions, reactions, and impatience. A tough problem is usually lost in your mindset before it is lost in your methods. Habit one: starting too narrow The first habit is to fix on the most visible symptom and refuse to look anywhere else. Something breaks, so we stare at the last thing we changed, and we return to it because it is familiar and close at hand. When the answer is not there, we look harder in the same place instead of stepping back. Here is what that looks like on real hardware. A device keeps dropping off the bus. You are a kernel person, so you open the driver and read it, carefully, for three days: the probe path, the error handling, the power-management callbacks. Every line is correct, and the device still fails. The fault was a layer b

2026-08-06 原文 →
AI 资讯

Linux Troubleshooting Workflow for Beginners: A Step-by-Step Guide

Most Linux problems aren't actually difficult. They're difficult because they're often debugged in the wrong order. Many beginners immediately: Restart services randomly Run commands without a plan Change configurations before understanding the problem Guess instead of observing Experienced engineers do something different. They follow a structured troubleshooting process. This article isn't about learning new Linux commands. It's about knowing when and why to use the commands you've already learned throughout this Linux Beginner Series. Think of it as putting everything together into one practical troubleshooting workflow that's used in real Linux and DevOps environments. Quick Troubleshooting Workflow Observe ↓ Check System Health ↓ Identify Problem Type ↓ Read Logs ↓ Verify Service ↓ Check Network ↓ Check Disk ↓ Recent Changes ↓ Find the Root Cause ↓ Apply the Fix Keep this workflow in mind as you read through the guide. Step 0: Observe Before You Change Anything Before running a single command, pause for a moment. Ask yourself: What exactly is broken? When did the issue start? Is everyone affected or only some users? Is the problem constant or intermittent? What changed recently? Many troubleshooting sessions become longer because people try to fix the problem before they understand it. Good troubleshooting begins with observation, not commands. Step 1: Check Overall System Health Your first goal is to understand the overall health of the system—not to fix anything yet. Useful commands: uptime free -h top Look for: High load average High CPU usage Low available memory Signs that the server is under heavy load At this stage, you're only gathering evidence. A quick system health check often tells you where to investigate next. Step 2: Identify the Type of Problem Before diving deeper, classify the issue. Problem Type Common Symptoms First Commands to Check CPU Slow system, high CPU usage top , htop Memory Applications crashing, OOM kills free -h Disk "No space lef

2026-08-04 原文 →
AI 资讯

A Month With Bash — Part 3: Building Projects

A Month With Bash — Part 3: Building Projects After all the expansions and syntax, I moved on to regex in bash. It wasn't too hard since I'd already worked with regex in Python, but alongside it I learned grep , sed , and awk — tools that turned out to be extremely useful for automation. I built a few mini projects and started automating some of my small day-to-day tasks. I won't go too deep into that here, but you can check out my learning-bash GitHub repo, which has all my learning scripts. From there I covered conditionals, loops, and repetitive tasks. Finally I learned about array variables in bash and shell options, went even further testing different ways of looping, and that's when I started actual project building(I am still building ) #!/usr/bin/env bash ## looping with range functions -- somehow # python style looping {start..end} for i in { 1..10 } ; do # this uses brace expansion so using vars wont work becase of execution sequencing echo $i done clear ## c - slyle looping for (( i = 0 ; i < 10 ; i++ )) ; do # variables works here well echo "hello $i " done ## using variables to loop clear start = 1 stop = 10 step = 2 for i in $( seq $start $stop ) ; do # this uses the seq command echo "hello world" done Conclusion Spending so much time on bash wasn't a waste. Not only did it force me to learn a huge number of commands, it changed how I think about my own machine — most of what I used to do manually, I can now automate. That shift alone made the month worth it. i am still learning and trying to get the best practices and things not to do THANK YOU FOR READING THIS FAR. That is a rough summary of me writing bash for a month there is really a lot left unsaid here but still building and learning. If you are just starting out with bash or if you haven't tried it hope this helps feel free to drop questions advice and corrections

2026-08-04 原文 →
AI 资讯

A Month With Bash — Part 2: Expansions

A Month With Bash — Part 2: Expansions Continuing from where I left off, the next thing I learned was special parameters in bash: "$*" $# $? $@ $N $- $0 Another important concept I picked up is how bash executes shell scripts. Bash is one of those languages that interprets each line as it goes — but it doesn't stop if a line fails. It continues on unless you explicitly set set -o pipefail (or -e , depending on what you want it to catch). Generally, the procedure looks like this: Tokenizing : splitting the line into tokens, usually split using the IFS value. Brace expansion : a mechanism by which arbitrary strings can be generated. echo file { 1,2,3 } .txt ## output: file1.txt file2.txt file3.txt Bash preserves the order from left to right. Tilde expansion : this is where expansion of special symbols takes place. ~ represents the HOME built-in variable ~+ represents PWD , the current working directory and others DIR = ~/Desktop # this is $HOME/Desktop echo " $DIR " Parameter expansion : introduced with the $ symbol. # ${} — the braces can be omitted for normal variables but not for array-type variables Command substitution : very important — it lets you assign the output of a command to a variable, and use commands inside if and for statements. Done with $(command to execute) . week_name = " $( date +%A ) " # gets the current day of the week echo " $week_name " Generally, $() spawns a new shell instance, so it's advisable to avoid it where possible, for latency reasons. Arithmetic expansion : just from the name, this allows evaluation of arithmetic expressions and substitution of the result. It starts with $(( expression )) . There are some rules — bash doesn't support floating point arithmetic natively, so you'd reach for bc if you need it. I won't go deep into that here since this isn't a full bash tutorial. Here's a simple BMI calculator I wrote while practicing this: #!/usr/bin/env bash # script calculates user's BMI and gives a recommendation set -euo pipefail #

2026-08-04 原文 →
AI 资讯

How Much Should Live Together? Learning to Isolate Services the Hard Way

Also Published On trever.cloud Medium LinkedIn Most of us who get into self-hosting start the same way: start with linux, throw a few apps into Docker, get them running and connectable outside the home network, and call it good for months, maybe even years. Nothing wrong with that approach. A compose file and a spare mini PC gets you further than you think, and if it works and you don't have to think about it, that's a perfectly fine place to stop. Then there's the rest of us. The people who get that first setup running, feel the little spark of "wait, I built this", and immediately start wondering what else is possible. More services. Less babysitting. A real answer to "what happens if this box dies at 2am". If any of that sounds familiar, this one's for you. If you keep going, you'll eventually run into the question every self-hosted setup faces sooner or later, whether you notice it happening or not, "how much should live together, and how much should be kept apart?". Put everything on one box and you quickly feel the fragility when one bad update takes everything down with it. Or when nightly backups put services on hold longer and longer. Split everything into its own isolated piece and you've gained resiliency but now manage a lot of moving parts. Most of the actual learning in running infrastructure happens in the space between those two answers. Where you draw that line is where most of the real infrastructure lessons live. Over the years, I've lived through a few different answers to that question in my own homelab, and each one taught me something the previous one couldn't. It started with a large VM, Docker installed, and every service I wanted to self-host running as a container inside. It was the fastest path to "it's actually working", and at the time that was the whole goal. I didn't know yet what I'd eventually want out of this thing, so keeping the infrastructure simple while I figured that out made sense. That setup carried me a long way, and I don

2026-08-03 原文 →
AI 资讯

The 4% rule: picking app background colors that survive cheap phone screens

Every design team eventually ships a beautiful off-white, off-blue, or off-anything background… and then opens the app on a $120 phone and watches it turn dirty gray . Same hex, same build. This post explains why, and gives you a small formula to convert any tint you've chosen into one that survives budget panels. Why subtle tints die on cheap screens Four panel-level failure modes, all common in the budget tier: 1. Weak gamut coverage. Entry-level LCDs cover only a fraction of sRGB — independent panel measurements routinely land in the 55–70% range, with large per-color error. A low-chroma tint simply doesn't have the budget to survive that compression. 2. Cold white points. sRGB assumes a D65 white (6500K). Budget modules commonly ship visibly cooler — high-6000s to 9000K+ — because blue-ish whites look "brighter" in a store. That blue cast is spread across the entire grayscale, and its magnitude is comparable to a subtle warm tint. Net result: the panel can cancel your background color outright. 3. Stretched gamuts on budget AMOLED. The opposite failure: "vivid" default modes stretch sRGB content across the panel's wider native gamut. Your quiet tint renders at roughly double saturation and suddenly has an opinion. 4. Banding. Many cheap panels are 6-bit + FRC. Soft near-white gradients develop visible steps, which makes barely-different surface colors look like rendering bugs. The 4% rule You don't need a colorimeter to know if you're at risk. Use channel spread — the distance between your highest and lowest RGB channel — as a chroma proxy: spread = max(R, G, B) − min(R, G, B) If spread is under ~10 of 255 (≈4%) , your tint is inside a cheap panel's error bar. It may render as intended, as gray, or as tinted the other direction — you don't get a vote. (Quick check on any hex: two outer pairs of digits within ~0x0A of each other = you're in the danger zone.) Why 4%? Because that's the same order of magnitude as the grayscale tint produced by a few-hundred-kelvin

2026-08-03 原文 →
AI 资讯

Architecting Mainline-Friendly Products

Mainline-friendly products are designed so their board support lives in upstream Linux, U-Boot, and standard build systems instead of a vendor fork. The decision is architectural, not aspirational: it is made when you choose the SoC, design the add-on connectors, and write the device tree — not when the product is already shipping. This article gives the strategic case, the product design rules that follow from current kernel work on hot-pluggable add-on boards, a vendor checklist for tech leads, and the concrete steps to upstream your own board support. We have covered why silicon vendors are moving to upstream-first BSPs . This article covers the product team's side of that shift: what you should do about it. Building mainline-friendly products means making a set of design decisions — SoC selection, connector design, device tree structure, and an upstreaming plan — so that mainline Linux and U-Boot treat your board as a normally supported board rather than as a permanent private port. Each section below turns one of those decisions into rules you can apply on your next board. Why mainline-friendly products are a strategic decision The cost of a vendor-fork BSP is not paid at bring-up; it is paid for the life of the product. Every kernel upgrade becomes a forward-port of private patches. Every security fix arrives on the vendor's schedule, not the kernel's — and for devices in scope of regulations such as the EU Cyber Resilience Act, patch latency is now a compliance question, not just an engineering one. Hiring is harder, because engineers must learn your fork before they can touch it, and the knowledge they build does not transfer in either direction. Board support that lives in mainline inverts each of these. New kernels are more likely to boot your board without forward-porting private support patches, because your board is part of the kernel's own build-and-test surface; LTS security fixes are easier to consume because the code paths you depend on are already

2026-08-02 原文 →
AI 资讯

How to Learn Linux in 2026 (Hands-On, Free, No Experience Needed)

Here is the whole method: get access to a real Linux machine, type commands on it for 30 to 60 minutes every day, and follow a plan that builds from navigating the filesystem up to running your own web server. Do that and you will be comfortable in four weeks and genuinely fluent in about eight. No experience required, no money required. The rest of this article is the specific plan: what to type each week, where to get a free machine you can safely break, what the three scariest errors mean, and how to tell you are actually improving. Why most people fail at Linux The pattern is nearly universal. Someone decides to learn Linux, finds a nine-hour video course, watches it at 1.5x speed, takes beautiful notes, and three weeks later cannot list the contents of a directory without checking those notes. Watching someone else type is not practice. It feels like learning because the explanation makes sense while you hear it. But command line skill is muscle memory wrapped around a mental model, and both are built one way: typing, failing, reading the error, trying again. An hour of reading about ls teaches you less than typing ls twenty times in twenty directories. Videos are fine as a preview. They are just not the workout. So flip the ratio: for every minute reading or watching, spend five with your hands on a keyboard. This article included. Read a section, then go type it. Two smaller failure modes show up almost as often. Trying to memorize everything Linux has thousands of commands. Working engineers lean hard on a core of about 25 and look up the rest without shame. The plan below teaches that core and nothing else. Fear of breaking things On a practice machine, breaking things is the goal, not the risk. A system you broke and fixed teaches more than ten flawless tutorials. Every option in the practice section makes the worst case "start over," which costs a minute. The four-week plan First, get a machine from the free options below (one minute to one afternoon, dep

2026-08-01 原文 →
AI 资讯

How to Verify a SHA-256 Checksum on Windows, macOS, and Linux

How to Verify a SHA-256 Checksum on Windows, macOS, and Linux You download an ISO, installer, archive, or release binary. The publisher provides a long value such as: 9f86d081884c7d659a2feaa0c55ad015 a3bf4f1b2b0b822cd15d6c15b0f00a08 That value is a checksum, usually generated with SHA-256. Verifying it answers one practical question: Does the file you downloaded have exactly the same contents as the file the publisher hashed? A checksum mismatch can indicate a damaged download, an incomplete transfer, the wrong file version, or modified contents. Before verifying anything Get the expected checksum from a source you trust. Ideally, use the software publisher’s official website, release page, package repository, or signed checksum file. A matching checksum confirms that your file matches the data represented by the expected hash. It does not prove that the original publisher or website was trustworthy. If an attacker can replace both the download and the displayed checksum, they can make the two values match. For stronger authenticity verification, use a signed release when the publisher provides one. Verify SHA-256 on Windows Open PowerShell in the folder containing the downloaded file. Run: Get-FileHash ".\filename.iso" -Algorithm SHA256 Example: Get-FileHash ".\ubuntu.iso" -Algorithm SHA256 PowerShell returns something similar to: Algorithm : SHA256 Hash : 4A1F... Path : C:\Users\You\Downloads\ubuntu.iso Compare the value beside Hash with the checksum published by the download provider. Uppercase and lowercase letters do not matter in hexadecimal hashes. The characters themselves must otherwise match exactly. Compare automatically in PowerShell Instead of comparing two 64-character values manually, store the expected checksum and let PowerShell compare them: $expected = "PASTE_EXPECTED_SHA256_HERE" $actual = ( Get-FileHash ".\filename.iso" -Algorithm SHA256 ) . Hash if ( $actual -eq $expected ) { Write-Host "Checksum matches" } else { Write-Host "Checksum does not

2026-08-01 原文 →
开源项目

Anleitung: Alienware m17x (2008) als Linux DJ-Workstation

moin, ich möchte euch mein aktuelles Projekt vorstellen: Die Wiederbelebung eines Alienware m17x (Baujahr 2008) als dedizierte DJ-Workstation unter Linux. Ziel war es, alte Hardware nachhaltig zu nutzen und eine stabile Umgebung für Mixxx zu schaffen. Die Hardware: Notebook: Alienware m17x (Core 2 Duo, 4GB RAM, SSD) OS: KDE Neon mit Low-Latency-Kernel (6.8.0) Software: Mixxx 2.4 Audio-Interface: Günstiges USB-Audio-Device für den Master-Ausgang Das Problem: Mixxx verweigerte unter ALSA den Dienst mit der Fehlermeldung: Error opening "USB Audio Device (hw:1,0)" - Invalid sample rate Die Analyse über /proc/asound/card1/stream0 zeigte die Ursache: Das USB-Gerät unterstützt ausschließlich 46875 Hz – eine für Audio-Interfaces sehr unübliche Rate, die weder 44100 Hz noch 48000 Hz entspricht. Der direkte Zugriff über hw:CARD=Device,DEV=0 schlug fehl. Die Lösung: Die Rettung war die Aktivierung der ALSA-Plug-Erweiterung über PipeWire/ALSA, die eine automatische Sample-Rate-Konvertierung erlaubt. Starten Sie Mixxx nicht direkt, sondern setzen Sie zuvor die Umgebungsvariable: export PA_ALSA_PLUGHW=1 mixxx Damit Mixxx auch dauerhaft korrekt startet (z.B. über das KDE-Menü), habe ich den Starter wie folgt angepasst: bash -c "export PA_ALSA_PLUGHW=1; mixxx" Ergebnis: ✅ Master-Ausgabe über das USB-Device funktioniert stabil. ✅ Kopfhörer-Vorhören (C-Media USB Headphone Set) läuft parallel. ✅ Das System läuft trotz des Alters der Hardware (2008) flüssig und mit geringer Latenz. Die vollständige Dokumentation inklusive Fotos des Umbaus, der genauen Kernel-Einstellungen und der Konfiguration findet ihr in meinem Open-Source-Repository: 👉 [ https://github.com/qrishii/DJ-Installationen ] Ich hoffe, diese Lösung hilft anderen, die ähnliche Probleme mit exotischen USB-Audio-Raten unter Linux haben! das Leben ist lustig

2026-08-01 原文 →
AI 资讯

Deploying ImgProxy – Process, Resize, Convert Images on the Fly

ImgProxy is an open-source image-processing server — resize, convert, and transform images on the fly via URL parameters, ideal as a caching layer in front of a CDN or web app. This guide builds ImgProxy from source on Ubuntu, runs it as a systemd service behind Nginx with TLS, walks through its URL processing options, and secures it with signed URLs. Prerequisites: an Ubuntu server, a domain A record (e.g. imgproxy.example.com ), non-root sudo user. Install ImgProxy ImgProxy uses libvips for image processing; this builds it from source with Go. $ sudo add-apt-repository ppa:dhor/myway $ sudo apt update $ sudo apt install libvips-dev -y $ sudo snap install --classic --channel = latest/stable go $ git clone https://github.com/imgproxy/imgproxy.git $ cd imgproxy $ sudo CGO_LDFLAGS_ALLOW = "-s|-w" go build -o /usr/local/bin/imgproxy Create the environment config: $ sudo touch /usr/local/bin/imgproxy.env $ sudo nano /usr/local/bin/imgproxy.env IMGPROXY_BIND = :8080 IMGPROXY_NETWORK = tcp IMGPROXY_READ_TIMEOUT = 10 IMGPROXY_WRITE_TIMEOUT = 10 IMGPROXY_WORKERS = 2 IMGPROXY_REQUESTS_QUEUE_SIZE = 0 IMGPROXY_QUALITY = 100 IMGPROXY_PREFERRED_FORMATS = webp,jpeg,png,gif,avif IMGPROXY_LOG_FORMAT = "pretty" IMGPROXY_LOG_LEVEL = "INFO" IMGPROXY_WATERMARK_URL = https://example.com/watermark.png IMGPROXY_WATERMARK_OPACITY = 1 Key settings: IMGPROXY_WORKERS should be ~2× your vCPU count; IMGPROXY_REQUESTS_QUEUE_SIZE=0 means unlimited queueing; IMGPROXY_WATERMARK_URL points at whatever image you want overlaid when watermarking is enabled. Point ImgProxy at the config and test: $ export IMGPROXY_ENV_LOCAL_FILE_PATH = /usr/local/bin/imgproxy.env $ cd $ imgproxy WARNING [2024-05-28T00:40:42Z] No keys defined, so signature checking is disabled WARNING [2024-05-28T00:40:42Z] No salts defined, so signature checking is disabled INFO [2024-05-28T00:40:42Z] Starting server at :8080 Stop it with Ctrl+C once verified, then set it up as a service. Run ImgProxy as a systemd Service $ sudo useradd

2026-07-31 原文 →
AI 资讯

Deploying code-server for VS Code on Ubuntu 24.04

code-server is the open-source project that runs full VS Code including extensions, integrated terminal, Git, IntelliSense — on a remote server, accessible from any browser. This guide deploys it on Ubuntu 24.04 with Docker Compose, fronted by Traefik for automatic HTTPS. Prerequisites: an Ubuntu 24.04 server (1GB RAM / 2 vCPU minimum), a domain A record (e.g. code.example.com ), Docker and Docker Compose installed. Set Up the Project $ mkdir -p ~/vscode-server/ { project,config,local,letsencrypt } $ cd ~/vscode-server project — your editable workspace config — code-server settings/extensions local — user-specific data letsencrypt — Traefik's ACME certificate storage Find your UID/GID and add yourself to the docker group: $ id $USER $ sudo usermod -aG docker $USER Write the Compose File $ nano docker-compose.yml services : code-server : image : codercom/code-server:latest container_name : code-server user : " UID:GID" # Replace with your user's UID and GID environment : - PASSWORD=SECURE_PASSWORD # Replace with a strong password - DOCKER_USER=LINUXUSER # Replace with your username volumes : - ./project:/home/coder/project - ./config:/home/coder/.config - ./local:/home/coder/.local networks : - internal restart : unless-stopped labels : - " traefik.enable=true" - " traefik.http.routers.code-server.rule=Host(`CODE.EXAMPLE.COM`)" # Replace with your domain name - " traefik.http.routers.code-server.entrypoints=websecure" - " traefik.http.routers.code-server.tls.certresolver=myresolver" - " traefik.http.services.code-server.loadbalancer.server.port=8080" traefik : image : traefik:latest container_name : traefik ports : - " 80:80" - " 443:443" volumes : - /var/run/docker.sock:/var/run/docker.sock:ro - ./letsencrypt:/letsencrypt command : - " --providers.docker=true" - " --providers.docker.exposedbydefault=false" - " --providers.docker.network=internal" - " --entrypoints.web.address=:80" - " --entrypoints.websecure.address=:443" - " --entrypoints.web.http.redirections.entr

2026-07-31 原文 →