AI 资讯
Kubernetes for Beginners: From Local to Production – May the Pods Be With You
The Quest Begins (The "Why") I remember the first time I tried to take a weekend side‑project from my laptop to something that felt “real”. I had a cute Express API that talked to Postman, a PostgreSQL container spun up with docker-compose up , and a React front‑end that lived in its own dev server. Everything worked beautifully … until I hit Ctrl+C on my laptop and the whole thing vanished. I needed a way to say, “Hey, keep this running even if I close my laptop, and if something crashes, bring it back up automatically.” I started poking at Docker Swarm, then Nomad, but the docs felt like reading ancient runes. That’s when a coworker slid over a Slack message: “Just try a Kind cluster. It’s K8s locally, and you’ll see why everyone talks about it.” Spoiler: it felt like discovering the secret level in a classic arcade game. Suddenly I could describe what I wanted my system to look like, and the cluster would make it happen — no more babysitting containers. The Revelation (The Insight) Kubernetes isn’t a mystical black box; it’s a declarative orchestrator . You tell it the desired state of your application (how many replicas, which image, what ports to expose) and it works relentlessly to match reality to that state. If a pod dies, Kubernetes spins up a new one. If you ask for three replicas and only two are running, it creates the missing pod. If you update the image tag, it rolls out the change pod‑by‑pod, keeping traffic flowing. Think of it like the save‑game system in a RPG: you define the story you want to experience, and the engine handles the gritty details of loading, saving, and recovering from crashes. The core objects you’ll meet early on are: Pod – the smallest deployable unit (one or more tightly coupled containers). Deployment – manages a set of identical pods, handles updates and rollbacks. Service – a stable network endpoint that load‑balances traffic to a set of pods. Ingress (optional) – exposes HTTP/HTTPS routes from outside the cluster to service
AI 资讯
Docker - redes e volumes na prática
1. Retomando: de imagens bem construídas a containers que conversam entre si Os artigos anteriores desta série cobriram como criar imagens eficientes e rodar containers isolados. Mas uma aplicação real raramente é um único container: normalmente há uma API, um banco de dados, um cache, talvez uma fila de mensagens — cada um em seu próprio container, precisando se comunicar. E containers, por padrão, são efêmeros: qualquer dado escrito dentro deles some quando são removidos. Este artigo cobre as duas peças que resolvem isso: redes (comunicação entre containers) e volumes (persistência de dados). 2. O problema do isolamento de rede por padrão Cada container recebe seu próprio namespace de rede, isolado dos demais e do host. Isso é uma característica de segurança, não um bug — mas significa que dois containers rodados de forma independente não conseguem se encontrar automaticamente: docker run -d --name api minha-api docker run -d --name banco postgres De dentro do container api , tentar acessar banco por esse nome simplesmente falha — cada container, isolado, só enxerga localhost como a si mesmo. A solução do Docker para isso é criar uma rede e conectar ambos os containers a ela. 3. Redes definidas pelo usuário (User-Defined Networks) docker network create minha-rede docker run -d --name banco --network minha-rede postgres docker run -d --name api --network minha-rede minha-api A partir daqui, dentro do container api , o hostname banco resolve automaticamente para o IP do container banco — o Docker roda um DNS interno para qualquer rede definida pelo usuário, resolvendo containers pelo nome (ou pelo alias definido com --network-alias , se houver mais de um). Isso é o motivo pelo qual strings de conexão em aplicações containerizadas costumam usar o nome do serviço em vez de um IP fixo: DATABASE_URL = postgresql :// usuario : senha @ banco : 5432 / meudb Comandos úteis para inspecionar redes: docker network ls # lista todas as redes docker network inspect minha-rede # d
AI 资讯
Docker Networking & Volumes: Connecting Containers and Persisting Data
Learn how containers communicate with each other and how to keep data alive even after containers are removed. Modern applications rarely run as a single container. A typical application might include a web application, a database, a cache layer, and background workers. For these services to work together, containers need a reliable way to communicate and share data. In this article, we'll learn: How Docker networking works How containers discover each other Docker network drivers Persistent storage with Docker volumes Essential networking and volume commands A real-world multi-container example By the end, we'll understand two of the most important concepts in Docker: networking and data persistence . Why Docker Networking Matters Every container runs inside its own isolated network namespace. This isolation improves security and prevents conflicts, but it also creates an important challenge: If containers are isolated, how does a web application connect to a database? Imagine a web application running inside one container and MongoDB running inside another. Without networking, they cannot communicate. Docker solves this problem using Docker Networks . A Docker network allows containers to communicate with each other while remaining isolated from unrelated containers. Web App Container | v Docker Network | v Database Container Without a shared network, containers cannot easily find or communicate with each other. Docker Network Drivers Docker supports several network drivers, but most developers primarily use three. Bridge Network A bridge network creates a private virtual network on the Docker host. Containers connected to the same bridge network can communicate with each other securely. Create a custom bridge network: docker network create my-app-network Benefits of bridge networks: Container-to-container communication Isolation from other applications Built-in DNS resolution Easy management For most Docker projects, a user-defined bridge network is the recommend
AI 资讯
Dockerfile na prática - camadas, cache de build e boas práticas
1. Retomando: do Dockerfile mínimo a um Dockerfile de verdade Na segunda parte desta série, um Dockerfile de poucas linhas já foi suficiente para empacotar uma aplicação Python. Isso funciona, mas um Dockerfile escrito sem pensar em camadas e cache de build gera imagens maiores do que precisam ser e builds que demoram muito mais do que deveriam a cada mudança pequena no código. Este artigo aprofunda como o Docker constrói uma imagem por dentro, e como escrever um Dockerfile que tira proveito disso. 2. Como funcionam as camadas (layers) Cada instrução de um Dockerfile ( FROM , RUN , COPY , ADD ) que modifica o sistema de arquivos gera uma camada — um diff read-only armazenado separadamente e empilhado sobre as anteriores. A imagem final é simplesmente a soma de todas essas camadas, e o container em execução adiciona uma camada gravável no topo (union filesystem). Container (camada gravável) ────────────────────────── Camada 4: COPY . . Camada 3: RUN pip install -r requirements.txt Camada 2: COPY requirements.txt . Camada 1: FROM python:3.12-slim Duas consequências práticas importantes: Camadas são reaproveitadas entre imagens. Se duas imagens diferentes compartilham as mesmas primeiras instruções (por exemplo, a mesma FROM e o mesmo RUN apt-get install ), o Docker armazena essa camada uma única vez em disco, mesmo que várias imagens a usem. Camadas são cacheadas entre builds. Ao rodar docker build de novo, o Docker verifica cada instrução, na ordem: se a instrução e seus arquivos de entrada não mudaram desde o último build, ele reaproveita a camada já construída em vez de refazer o trabalho. Isso é a base de todo o próximo tópico. 3. Cache de build: ordenar o Dockerfile por frequência de mudança O cache de build é invalidado a partir do primeiro ponto de mudança : se a instrução N mudou (ou um arquivo que ela copia mudou), toda camada a partir de N é reconstruída — mesmo que as instruções seguintes sejam idênticas ao build anterior. Isso significa que a ordem das ins
开发者
Reviving Open Source Giants: How I Brought Weave Scope Back with Multi-Platform Docker Support in One Afternoon Using Antigravity
How to rescue abandoned open-source projects, modernize build systems, and generate multi-architecture Docker images (x86_64, ARM64) in a single afternoon with Antigravity.
AI 资讯
Docker no dia a dia - comandos essenciais e primeiros containers reais
1. Retomando: de imagens a containers em execução Na primeira parte desta série vimos o que é o Docker, o problema que ele resolve e os três conceitos fundamentais — imagens, containers e registries. Agora que a base teórica está posta, o foco deste artigo é prático: os comandos que efetivamente viram hábito no uso diário — run , exec , logs , ps , build — aplicados a containers reais, não só ao hello-world . 2. docker run além do básico O artigo anterior já usou docker run para subir um Nginx. Vale conhecer as flags que aparecem o tempo todo: # Modo interativo, útil para explorar uma imagem manualmente docker run -it ubuntu bash # Variáveis de ambiente docker run -e POSTGRES_PASSWORD = segredo -d postgres # Montar um diretório do host dentro do container (volume bind mount) docker run -v $( pwd ) /dados:/dados -d minha-imagem # Remover o container automaticamente quando ele parar docker run --rm -it python:3.12 python3 # Limitar recursos docker run --memory = 512m --cpus = 1 minha-imagem -it combina -i (interativo, mantém STDIN aberto) com -t (aloca um pseudo-terminal) — é o par de flags para "entrar" em um container e usar um shell como se fosse uma máquina normal. --rm evita acumular containers parados no disco depois de testes rápidos e descartáveis — sem ela, cada docker run deixa um container parado para trás até ser removido manualmente. -e define variáveis de ambiente; imagens oficiais como a do Postgres costumam documentar quais variáveis elas esperam (usuário, senha, nome do banco inicial). 3. Inspecionando o que está rodando O comando mais usado para ter uma visão geral do que o Docker está gerenciando na máquina: docker ps # containers em execução docker ps -a # todos, incluindo parados docker ps -q # só os ids (útil em scripts) Para investigar um container específico mais a fundo: docker inspect meu-container # todos os metadados em JSON: rede, volumes, config docker top meu-container # processos rodando dentro do container docker stats # uso de CPU/mem
AI 资讯
Kubernetes and Docker
Docker and Kubernetes are two of the most consequential infrastructure technologies of the last decade. They changed how software is built, packaged, and deployed. They are also two technologies that most engineers use before they understand, which creates gaps in knowledge that show up at the worst times: a production outage, a security incident, a performance problem you cannot diagnose. This guide builds understanding from the ground up. Every concept is introduced with the problem it solves. You will understand why containers exist before you understand what they are. You will understand why Kubernetes exists before you understand how it works. By the end, you will know not just how to run these technologies but how to reason about them. Table of Contents The Problem Containers Solve - Why Docker Exists Docker Internals - What a Container Actually Is Images - Building Portable Application Packages Dockerfile - Writing Reproducible Builds Docker Networking - Container Communication Docker Volumes - Managing State Docker Compose - Multi-Container Applications The Problem Kubernetes Solves - Why Orchestration Exists Kubernetes Architecture - The Control Plane and Data Plane Core Kubernetes Objects - Pods, Deployments, Services, ConfigMaps, Secrets Namespaces and RBAC - Multi-Tenancy and Access Control Storage in Kubernetes - Persistent Volumes Ingress - Routing External Traffic Helm - Package Management for Kubernetes Service Mesh - Istio and Advanced Traffic Management AWS Container Services - ECS and EKS Real Architecture Patterns The Problem Containers Solve - Why Docker Exists The Classic Failure Mode A developer builds an application on their MacBook. It works. They hand it to the QA team. It does not work. They hand it to the operations team to deploy to production. It works differently than in QA. "It works on my machine" is not a joke. It is a description of a real, chronic infrastructure problem. The application depends on: A specific version of Python, No
AI 资讯
Docker - O Que É, Para Que Serve e Conceitos Iniciais
1. O Problema que o Docker Resolve "Na minha máquina funciona." Poucas frases resumem tão bem um problema que atormentou (e ainda atormenta) times de desenvolvimento: um código que roda perfeitamente no notebook do desenvolvedor, mas quebra no servidor de produção — porque a versão do Python é outra, uma biblioteca do sistema está faltando, uma variável de ambiente não foi configurada, ou o sistema operacional simplesmente se comporta de forma diferente. O Docker resolve exatamente isso: ele empacota uma aplicação junto com tudo que ela precisa para rodar — código, dependências, bibliotecas do sistema, variáveis de ambiente, configuração — em uma unidade isolada e portátil chamada container . Essa unidade roda da mesma forma em qualquer lugar que tenha o Docker instalado: no notebook do desenvolvedor, no servidor de CI, ou em produção. Esta é a primeira parte de uma série que vai do zero ao avançado em Docker: hoje o foco é entender o problema que ele resolve, os conceitos fundamentais e como eles se encaixam. 2. Containers vs Máquinas Virtuais A comparação mais comum ao explicar Docker é com máquinas virtuais (VMs), porque ambos resolvem um problema parecido — isolar e empacotar aplicações — mas de formas muito diferentes. Uma máquina virtual virtualiza o hardware inteiro: cada VM roda seu próprio sistema operacional completo (kernel incluso), gerenciado por um hypervisor. Isso garante isolamento forte, mas tem um custo alto: cada VM consome centenas de MBs a alguns GBs de disco e memória só para o SO, e leva de dezenas de segundos a minutos para inicializar. Um container , por outro lado, virtualiza no nível do sistema operacional: todos os containers em uma máquina compartilham o mesmo kernel do host, mas cada um enxerga seu próprio sistema de arquivos, processos e rede isolados — usando recursos do kernel Linux como namespaces (isolamento de visão) e cgroups (limites de CPU/memória). O resultado é que containers são muito mais leves: alguns MBs a poucas centenas
AI 资讯
Gubernator v2.13.0: Google SRE SLOs, Native CoreDNS Suite & Caddy Ingress for Docker Compose
If you love the simplicity of Docker Swarm (native Compose files, lightweight single binary) but miss the advanced capabilities of Kubernetes (targeted label placement, SRE-grade observability, built-in DNS service discovery, and zero-trust ingress), meet Gubernator (gbnt) . We are excited to release Gubernator v2.13.0 , introducing three massive feature suites natively integrated into a single binary and a modern Material Design 3 Flutter Web Dashboard: Google SRE Multi-Burn-Rate SLO Engine & Interactive Suite CoreDNS 4-Tab Management Suite & Interactive Dig Playground Caddy Ingress & Zero-Trust Reverse Proxy Suite Fun Fact: The entirety of Gubernator's codebase, multi-node deployment pipelines, and SRE features were designed, built, and pair-programmed using **Google Antigravity (AGY) , Google DeepMind's agentic AI coding assistant! Let's dive into what's new and how you can level up your self-hosted or production container clusters! 1. Google SRE Multi-Burn-Rate SLO Engine & Web Suite Defining Service Level Objectives (SLOs) and tracking Error Budgets is the gold standard of Site Reliability Engineering. Until now, implementing SLOs meant running heavy Kubernetes CRDs (via tools like Sloth or Pyrra) or using costly SaaS platforms. Gubernator v2.13.0 brings Google SRE Workbook (Chapter 5) compliant multi-burn-rate alerting straight to simple docker-compose.yml services: version : " 3.8" services : payment-api : image : hashicorp/http-echo:latest labels : gbnt.slo.enable : " true" gbnt.slo.target : " 99.9" gbnt.slo.window : " 30d" gbnt.slo.template : " caddy-http" gbnt.slo.journey : " Checkout Flow" What makes Gubernator's SLO Suite unique? Google Multi-Burn-Rate Alerting : Automatically generates standard 4-window Prometheus recording and alert rules ( Critical Page 1h/6h & Warning Ticket 3d/14d ). Dynamic "No-Code" Management : Click "+ Configure / Add SLO" in the Web UI or call POST /v1/slo/edit to create, edit, or disable SLOs on the fly without editing Compose
AI 资讯
Why Spark Couldn't Read from Kafka: A Real Debugging Journey Across PySpark, Hadoop, Docker, and Kafka
I thought this would be a simple task. I already had a Python Kafka producer running. Kafka was up in Docker. The topic existed, and I could send a message into it successfully. The next step sounded straightforward: Python Producer ↓ Kafka ↓ Spark Structured Streaming All I wanted Spark to do was read a JSON message from a Kafka topic. Instead, I ran into one error after another. At first, it looked like one problem: Spark cannot read Kafka. It was not one problem. It turned into a chain of failures across several different layers: Python / PySpark ↓ Spark runtime ↓ Kafka connector ↓ Hadoop / Windows ↓ Docker ↓ Kafka networking ↓ Ivy dependency resolution The useful part of this experience was not any single fix. It was learning how to separate the layers and stop treating every error as a problem in my Python code. This is the full debugging path. What I Was Building This was part of an financial data engineering project. The batch side of the project already looked roughly like this: Financial Data Source ↓ Python ingestion ↓ AWS S3 ↓ Snowflake ↓ dbt ↓ Financial anomaly models I wanted to add a streaming extension for newly arriving financial events. For the first version, I kept it intentionally simple: Python Kafka Producer ↓ Kafka topic: financial_events ↓ Spark Structured Streaming The producer sent a simulated financial event: { "company_id" : "COMPANY_001" , "company_name" : "Sample Company" , "report_type" : "quarterly_report" , "reporting_date" : "2026-08-08" , "event_id" : "FIN-20260808-001" , "source" : "simulated_financial_event" } Kafka accepted the message successfully. I could even read it with Kafka's console consumer. So Kafka itself was working. Then Spark entered the picture. Failure #1: PySpark Worked, but spark-submit Didn't I installed PySpark: pip install pyspark Then I installed Java 17 and verified it: java -version After reopening my terminal, Java was available. I tested Spark directly through Python: python -c "from pyspark.sql import S
AI 资讯
My AI Answered in 5.8 Seconds and Said Nothing Useful. I Almost Blamed the Model.
I put an AI into a Google Meet call. It transcribed Japanese, generated a reply, and spoke it out loud. Total new spend: $0 . Then I asked it the one question I actually needed answered, and it said: "I think there's still room for discussion. How about we set up a session to align our understanding?" That is exactly what a person says when they don't know. TL;DR: I had a latency problem and an "is this model smart enough" problem. Neither was real. Same model, same question, 5.80s → 5.68s — 2,545 characters of context turned a deflection into a claim you could argue with. The stack, and what it replaced I wanted an AI participant in a real meeting. Not a note-taker — something that answers when someone demands specifics. The obvious stack bills you three times: a hosted meeting-bot API, a speech-to-text vendor, and a text-to-speech vendor. I replaced all three. Layer Obvious choice What I used Why Meeting bot Recall.ai, $0.50/hour Attendee (OSS, self-hosted) no per-hour billing Speech-to-text Deepgram / AssemblyAI Google Meet's own captions the meeting already generates them Text-to-speech Google Cloud TTS raw audio POST (below) no GCP project at all Reasoning + voice LLM + TTS, two hops Gemini Live (speech-to-speech) one model, one hop Attendee is 699 stars, last pushed 2026-08-07. Google Meet exposes no bot API, so it drives a full Chrome instance — which is why setup hurt before anything else did. The setup tax, compressed Two problems were routine. The image pins FROM --platform=linux/amd64 ubuntu:22.04 , and my machine is Apple Silicon, so colima with Rosetta: colima start --vm-type = vz --vz-rosetta --cpu 6 --memory 12 --disk 60 docker run --rm --platform = linux/amd64 alpine:3.20 uname -m # x86_64, 5.6s cold Then the build died at step 35 of 42 with the --chmod option requires BuildKit — colima's docker CLI ships without the buildx plugin. brew install docker-buildx , point ~/.docker/config.json at /opt/homebrew/lib/docker/cli-plugins via cliPluginsExtraDirs
AI 资讯
Docker for Beginners: Images, Containers, Ports, and Volumes Explained
Docker for Beginners: Images, Containers, Ports, and Volumes Explained If you've ever followed a programming tutorial and seen something like: docker run ... you've probably wondered: What exactly is Docker doing? I had the same question when I started learning Docker. At first, I thought Docker was simply a way to "run applications in containers." But there is much more to it. Once I understood four concepts — images, containers, ports, and volumes — Docker became much easier to understand. So let's break it down from the beginning. What Is Docker? Docker is a platform for building, packaging, and running applications in isolated environments called containers . The basic idea is simple: Package an application together with the things it needs to run, and make that package portable. For example, imagine you build a Python application. Your application might depend on: Python 3.12 FastAPI Uvicorn Several Python packages Environment variables Certain system libraries On your computer, everything works. Then someone else downloads your project. They install a different Python version. A package is missing. Something behaves differently. Now you have: "It works on my machine." Docker helps reduce this problem by allowing you to define the environment your application should run in. The Four Concepts You Need to Understand Before learning Docker commands, understand these four things: Docker Image ↓ Docker Container ↓ Ports ↓ Volumes Let's look at each one. 1. What Is a Docker Image? A Docker image is a packaged, read-only template used to create containers. Think of it like a blueprint. For example: Docker Image │ ├── Ubuntu ├── Python ├── Application code ├── Dependencies └── Configuration An image contains the instructions and filesystem needed to create a container. You can download images from container registries such as Docker Hub. For example: docker pull nginx This downloads the Nginx image. You can see your downloaded images with: docker images You might see s
AI 资讯
2.Self-Hosted AI: n8n + Ollama, local AI workflows on your Mac
If you want AI agents running on your own machine, with your own models, and no data leaving your computer, this is the article :). This is part three of the series. In part one we set up PostgreSQL, and in part two we covered the LLM concepts (models, parameter, quantization, context, capabilities, VRAM). Today we put them to work: n8n for the workflows and Ollama for the models. One prerequisite: Docker. If you do not have it yet, install Docker Desktop for Mac following the official guide [ Docker docs ]. Quick setup: n8n The fastest path is n8n's official Self-hosted AI Starter Kit, a Docker Compose template that ships n8n, Ollama, Qdrant (a vector store) and PostgreSQL preconfigured to talk to each other [ n8n docs ]. git clone https://github.com/n8n-io/self-hosted-ai-starter-kit.git cd self-hosted-ai-starter-kit cp .env.example .env # file where your passwords are stored The .env file is hidden by default. In Finder, press Command + Shift + Period to show hidden files, or just edit it from the terminal. Update the credentials, for example: POSTGRES_USER = admin POSTGRES_PASSWORD = root POSTGRES_DB = n8n Also replace the N8N_ENCRYPTION_KEY and N8N_USER_MANAGEMENT_JWT_SECRET values with your own random strings. Now one Mac-specific detail. Docker on Apple Silicon cannot use the Mac's GPU, so the kit's README recommends running Ollama natively on your Mac for speed and letting the containers connect to it [ starter kit README ]. That is what we'll do. Set this in your .env : OLLAMA_HOST = host.docker.internal:11434 Then start everything: docker compose up Open http://localhost:5678 to create your n8n account (once), and http://localhost:5678/home/workflows is where your workflows and agents live. If you only want n8n without the rest of the kit, this single command works too [ n8n docs ]: docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n Quick setup: Ollama On the Mac side (from part two, condensed): brew install olla
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
AI 资讯
What a Malicious Ollama Model Can Actually Do to Your Host, and How to Sandbox /api/pull
A malicious Ollama model is not a virus you double click, but it is untrusted input handed to a C parser, a template engine and your filesystem in one request. The realistic damage from a hostile /api/pull is disk exhaustion, VRAM starvation, blob writes under ~/.ollama/models , a poisoned chat template that silently rewrites every prompt, and memory corruption in the GGUF loader if the file is crafted for it. None of that requires a vulnerability in your app code, only an Ollama daemon that trusts whoever can reach port 11434 and whichever registry a tag points at. Bind the daemon to localhost, pin models by SHA256 digest, run the container as a non root user with a read only root filesystem and a capped model volume, and the entire class collapses to a bad model that answers badly. TL;DR by reader profile: Solo developer running Ollama on a laptop, for example a contractor testing llama3.1:8b locally: leave OLLAMA_HOST at 127.0.0.1:11434 and pin digests, because your only real exposure is pulling a model whose tag moved under you. Two person startup running Ollama on one rented GPU box, for example a founder pair serving an internal assistant: run it in Docker as UID 1000 with --read-only , --cap-drop ALL and a sized model volume, because a single unbounded pull can fill the disk that also holds your Postgres data. Team fronting Ollama with Open WebUI or Continue, for example five engineers sharing one workstation: put model management behind the proxy and block /api/pull , /api/create , /api/push and /api/delete for normal users, because chat access and registry access are not the same privilege. Anyone building agents or RAG on Ollama, for example a support bot with tool calling: treat the Modelfile TEMPLATE and SYSTEM blocks as attacker controlled text, because a poisoned template reaches the model before your prompt does. Consultancies holding client data, for example a two person shop under an NDA: keep model pulls on a staging host, mirror approved blobs int
AI 资讯
Directus + Coolify: Should You Decouple Postgres & Redis?
This is Part 2 of the Directus + Coolify series. If you're new here, start with "Secure Your VPS Before Hackers Do" and the first Directus + Coolify post — the bundled, single-Compose-file setup — before following along with this one. Introduction In the first method, we coupled all of the services into one stack using a single Docker Compose file. The network between all services was created automatically, and we didn't have to start them up individually — which removes the risk of a race condition if service startup isn't handled properly. If you're running a single app, that's genuinely the recommended way to set up Directus on a Coolify-managed VPS. Going in, I assumed there were several good reasons to split the services apart instead — more control over backups, monitoring, restarts, that kind of thing. So before recommending decoupling, I actually tested each of those assumptions on a live Coolify instance. Most of them turned out to be wrong. Myth 1: Restarting Directus Restarts the Whole Stack I expected that restarting Directus inside the bundled Compose file would restart Redis and Postgres along with it. It doesn't. Coolify lets you restart each service in the stack independently — Directus, Database, and Cache each get their own Restart button, right there in the same view. No decoupling needed for this one. Myth 2: You Need a Separate Database Resource for S3 Backups Same story. Even with Postgres bundled inside the Directus Compose file, Coolify still gives it its own dedicated Backups option, S3 included. This isn't a separate-resource-only feature. Myth 3: Scheduled Tasks Require Separate Services Also not true. Coolify exposes a Scheduled Tasks tab per service, even inside a single bundled stack — complete with a Container name dropdown letting you target the cron job at just the database, or just Directus, without splitting anything apart. What Actually Holds Up Two things survived testing. First: metrics. This one's confirmed directly in Coolify'
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
开发者
Halfway Through the MLH Production Engineering Fellowship
I'm halfway through the MLH Production Engineering Fellowship, and while I've learned a lot technically—from Linux fundamentals, Docker, NGINX, automated testing, and contributing to open source, the thing that has stood out to me most is how well the program is structured. Beyond the technical curriculum, there is a strong emphasis on interview preparation and career growth. We’ve had regular opportunities to practice technical interviews, receive feedback, and stay in close contact with our Meta mentors, who have been incredibly approachable throughout the program. Looking forward to seeing what the second half of the fellowship has in store. Thanks to the MLH team, mentors, and my podmates for making it such a rewarding experience so far!
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
AI 资讯
Installing Ghost Blogging Platform on Ubuntu 24.04
Ghost is an open-source publishing platform with built-in newsletters, memberships, subscriptions, ActivityPub federation, and Tinybird-powered web analytics. This guide covers two install paths on Ubuntu 24.04: Ghost-CLI for a traditional host install, and Docker Compose for a containerized deployment with analytics. Prerequisites: an Ubuntu 24.04 server, non-root sudo user, a domain A record (e.g. ghost.example.com ). Option A: Install with Ghost-CLI Install Node.js Ghost requires Node v22 LTS — check compatible versions before installing elsewhere. $ curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh $ sudo -E bash nodesource_setup.sh $ sudo apt install -y nodejs $ node -v Install and Configure MySQL $ sudo apt install -y mysql-server $ mysql --version $ sudo mysql_secure_installation Walk through the prompts: enable password validation ( y ), pick strong policy ( 2 ), remove anonymous users ( y ), restrict root to localhost ( y ), drop the test database ( y ), reload privileges ( y ). $ sudo mysql mysql > CREATE DATABASE ghost_db ; mysql > CREATE USER 'ghostuser' @ 'localhost' IDENTIFIED BY 'Your_password2!' ; mysql > GRANT ALL PRIVILEGES ON ghost_db . * TO 'ghostuser' @ 'localhost' ; mysql > FLUSH PRIVILEGES ; mysql > EXIT ; Install Nginx $ sudo apt install -y nginx $ sudo ufw allow 'Nginx Full' $ sudo systemctl status nginx Install Ghost $ sudo npm install ghost-cli@latest -g $ sudo mkdir -p /var/www/html/ghost $ sudo chown $USER : $USER /var/www/html/ghost $ sudo chmod 775 /var/www/html/ghost $ cd /var/www/html/ghost $ ghost install The installer prompts for: Blog URL : https://ghost.example.com MySQL hostname : localhost MySQL username/password/database : from the setup above Set up Nginx? : y Set up SSL? : y (installs acme.sh ) Email for SSL : your address Set up Systemd? : y Start Ghost? : y Manage the Config $ nano /var/www/html/ghost/config.production.json $ cd /var/www/html/ghost $ ghost restart Or via systemd (replace ghost-example