Back to Lagoonify / Guides
Getting Started

What is Lagoon?

Lagoon is a container hosting platform that deploys Docker-based applications to Kubernetes. It reads two config files from your repo:

  • .lagoon.yml — Project metadata, routes, cron jobs, and environment settings
  • docker-compose.yml — Service definitions, build instructions, and service types

Lagoonify analyses your codebase and generates both files for you.

The Lagoonify workflow

  1. Analyze — Point Lagoonify at your repo. It detects languages, frameworks, databases, and services.
  2. Generate — Review the detected stack and tweak any options (project name, persistent storage, cron jobs). Hit Generate to produce your config files.
  3. Apply — Write the generated files into your repo. Optionally commit them in one step.

Or use Full Pipeline to run all three in one click.

Start simple. A basic config that deploys is infinitely more useful than a perfect config that never ships. You can always iterate after your first successful deployment.
Understanding Service Types

Lagoon uses service types (set via lagoon.type labels in docker-compose) to decide how to deploy each container. The most common:

TypePortUse case
python8800Python apps (Flask, FastAPI, Django)
node3000Node.js apps (Express, Next.js)
nginx-php8080PHP with Nginx (Laravel, WordPress)
nginx8080Static sites or custom Nginx configs
basic3000Generic container (Ruby, Go, etc.)

Add -persistent to any type (e.g. node-persistent) to attach a persistent storage volume. Lagoonify detects this automatically when your app uses file uploads, SQLite, or local data directories.

Ports matter. Your app must listen on the port Lagoon expects for its service type. Lagoon's health checks will fail if your app runs on a different port, causing deployment timeouts.
Dockerfiles and Base Images

Lagoon provides Alpine Linux-based base images (uselagoon/*). This matters:

  • Use apk add, not apt-get install
  • Containers run as uid 10000, not root or www-data
  • Don't chown to named users — use chmod 775 instead

If your repo already has a Dockerfile, Lagoonify will use it. Otherwise, it generates one using the appropriate Lagoon base image.

When to write your own Dockerfile

The generated Dockerfile covers the common case. Write your own when you need:

  • Multi-stage builds for compiled languages
  • System packages beyond the defaults
  • Custom build steps (asset compilation, code generation)
  • Non-standard directory layouts
Routes and Domains

Routes in .lagoon.yml map domains to services. A minimal route:

environments:
  main:
    routes:
      - node:
          - myapp.example.com:
              tls-acme: true
              insecure: Redirect
  • tls-acme: true — Auto-provision a Let's Encrypt SSL certificate
  • insecure: Redirect — Redirect HTTP to HTTPS

Multiple routes can point to different services in the same project. Routes are per-environment, so staging and production can have different domains.

The Right Amount of Configuration

The biggest trap in deployment config is over-engineering. Here's a practical framework:

Do now

  • Get the service type and port right
  • Set up your route so the app is reachable
  • Add persistent storage if your app writes to disk
  • Commit the generated files and deploy

Do after first successful deploy

  • Add cron jobs for scheduled tasks
  • Configure environment variables for secrets
  • Tune resource limits if needed
  • Set up additional environments (staging, dev)

Do when you actually need it

  • Custom Nginx configs and rewrites
  • Multi-service architectures (workers, queues)
  • Advanced build arguments and build-time secrets
  • Custom rollout strategies
The 80/20 rule applies. Lagoonify's defaults handle 80% of projects. Spend your energy on what makes your app unique, not on replicating config that works out of the box.
Monorepo Support

Lagoonify detects monorepos automatically. When multiple sub-projects are found (e.g. frontend/ and backend/), you'll be prompted to pick which one to configure.

Each sub-project gets its own service in the docker-compose file. The analyser looks at the root and each sub-directory for framework indicators like package.json, requirements.txt, or composer.json.

Tips for monorepos

  • Run Lagoonify from the repository root
  • Each sub-project should have its own dependency manifest
  • Routes can map different domains to different services
Troubleshooting Deployments

Build fails: "command not found"

Lagoon base images are Alpine Linux. Use apk add instead of apt-get install. Package names may differ too — check Alpine packages.

Deploy times out

Usually a port mismatch. Lagoon runs health checks on the port assigned to your service type. If your app listens on 8000 but the service type expects 8800, health checks never pass.

Pod CrashLoopBackOff

Check your CMD or ENTRYPOINT. The process must stay in the foreground. Common fix: ensure your web server binds to 0.0.0.0, not 127.0.0.1.

"Immutable field" errors

Kubernetes doesn't allow changing certain fields (like spec.selector) on existing deployments. If you change lagoon.type on a service that's already deployed, you'll need to delete the environment and redeploy from scratch.

Permission denied on files

Lagoon containers run as uid 10000. Don't chown files to named users. Use chmod 775 to ensure the container user can read and write.