TL;DR: A step-by-step walkthrough from an empty folder to a live HTTPS URL: a small Express app, a Dockerfile and a .dockerignore, a local test, a push to GitHub, the deploy itself, environment variables, an optional $1 managed database, and the checks that tell you it worked. No card and no DevOps background needed.

This hands-on guide walks you through deploying your first Docker container for free. We'll cover project setup, Dockerfile creation, environment configuration, and the actual deployment process with real code examples.

Prerequisites

  • A GitHub account
  • Basic familiarity with the command line
  • A simple application (we'll use a Node.js example)

Step 1: Prepare Your Application

Let's create a simple Express.js application. Create these files in your project:

{ "name": "my-free-container", "version": "1.0.0", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.18.2" } } 
const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.json({ status: 'running', message: 'Hello from my free container!', timestamp: new Date().toISOString() }); }); app.get('/health', (req, res) => { res.status(200).send('OK'); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); 

Step 2: Create a Dockerfile

Add a Dockerfile to your project root:

# Use official Node.js LTS image FROM node:22-alpine # Set working directory WORKDIR /app # Copy package files first (for better caching) COPY package*.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port your app runs on EXPOSE 3000 # Start the application CMD ["npm", "start"] 

Dockerfile Best Practices

  • Use Alpine images — Smaller size means faster builds
  • Copy package.json first — Enables Docker layer caching
  • Use npm ci — Faster and more reliable than npm install
  • Don't run as root — Add a non-root user for production

Step 3: Add a .dockerignore File

Create .dockerignore to exclude unnecessary files:

node_modules npm-debug.log .git .gitignore .env *.md .DS_Store 

Step 4: Test Locally (Optional)

Before deploying, verify your container works locally:

# Build the image docker build -t my-app . # Run the container docker run -p 3000:3000 my-app # Test it curl http://localhost:3000 

Step 5: Push to GitHub

Initialize a git repository and push your code:

git init git add . git commit -m "Initial commit with Dockerfile" git remote add origin https://github.com/yourusername/my-app.git git push -u origin main 

Step 6: Deploy to SnapDeploy

Now deploy your containerized application:

  1. Create account — Go to snapdeploy.dev and sign up (no credit card)
  2. New Container — Click "New Container" in the dashboard
  3. Connect GitHub — Authorize access and select your repository
  4. Configure — Set container name (becomes your-app.containers.snapdeploy.app)
  5. Deploy — Click Deploy and watch the build logs

Step 7: Configure Environment Variables

If your app needs environment variables, add them in the dashboard:

# Example environment variables NODE_ENV=production DATABASE_URL=postgresql://user:pass@host:5432/db API_KEY=your-secret-key 

Access them in your code with process.env.VARIABLE_NAME.

Step 7b (Optional): Add a Managed Database for $1

Your free container is stateless — data inside the container resets on every deploy. For persistent data, add a managed database. You have two paths:

  • Test first with the DB Sprint Pack — $1 for 12 hours. Pick any of six engines (PostgreSQL 16, MySQL 8, MariaDB 11, MongoDB 7, Redis 7, RabbitMQ 3) at full Mini-tier capacity. Persistent EFS storage, daily backups, full privileged access. Convert to monthly anytime during the 12-hour window or the 24-hour grace afterward — same EFS volume re-attaches, zero data migration.
  • Or go straight to a monthly subscription: Mini from $29/mo (SQL), $12/mo (Redis), $14/mo (RabbitMQ). Auto-injected connection strings.

Once provisioned, SnapDeploy injects the database connection string into your container as an environment variable (DATABASE_URL for SQL, REDIS_URL for Redis, etc.) — your app reads it the same way as the example above.

Read the DB Sprint Pack guide →

Step 8: Verify Deployment

Once deployed, test your live container:

# Test the root endpoint curl https://your-app.containers.snapdeploy.app # Expected response: { "status": "running", "message": "Hello from my free container!", "timestamp": "2026-01-06T10:30:00.000Z" } 

Troubleshooting Common Issues

Ensure package-lock.json is committed. Run npm install locally first.

Check that your app listens on the PORT environment variable, not a hardcoded port.

Check the logs in the dashboard. Common cause: missing environment variables or database connection failures.

⚡ Need it online 24/7? Skip the cold starts.

Your free container sleeps when idle and wakes when a visitor opens it — perfect for side projects. But for a client demo, an interview review, or a weekend launch that has to stay up, drop a Sprint Pack on it: $1 / ₹99 for 24 hours of unlimited deploys plus Always-On. One-time, no subscription, no auto-renewal.

Next Steps

You now have a containerized application running for free. Free deploy includes auto-sleep when idle and auto-wake on visits — your container is there when someone opens it. For 24/7 uptime, add Always-On starting at $12/month.