Running Caddy 2 on Android

Caddy 2 can run on Android. There are several ways to do this without rooting your device.

NOTE: Due to Android’s permission model, Caddy’s functionality might be severely limited. For example, you won’t be able to bind to low ports (notably 80 and 443) without more invasive tactics.


Using Termux

Prerequisite steps for these Termux methods:

  1. Install F-Droid.
  2. Use F-Droid to install Termux.
  3. Launch the Termux app.

A: Install with pkg

pkg is a recommended apt wrapper in Termux.

  1. pkg install caddy

B: Compile from source on-device

  1. pkg install golang
  2. go install github.com/caddyserver/caddy/v2/cmd/caddy@latest

This compiles Caddy and puts it in $GOPATH/bin, and the default $GOPATH is $HOME/go. Thus, run cd go/bin then ls and you’ll find caddy sitting there. Run it like so: ./caddy version


Side-loading using adb

Requirements:

Steps:

From the folder that has your Caddy ARM binary:

$ adb push caddy /data/local/tmp
$ adb shell "cd /data/local/tmp; chmod 755 caddy; ./caddy file-server -root /sdcard --listen :8080 --browse"

Note that you can run nearly any caddy command you want; we’re just demonstrating a simple file server with listings enabled. On the same LAN as your phone, open up your phone’s IP to port :8080 in your browser and you should see a file listing you can traverse.

You probably won’t be able to bind to low ports (hence our use of the --listen flag). You could also pass a config file or a Caddyfile and use that for more advanced customization.


Native Android app

Note: This method is very incomplete and doesn’t do anything useful yet. Just some notes from my tinkering. Someone else is welcome to fill this out more.

Requirements:

  • gomobile installed installed (then run gomobile init)
  • macOS only: XCode Command Line Tools (or XCode itself)
  • Android NDK
  • USB debugging enabled on your phone. (You’ll have to enable “Developer mode”; search for instructions)

Steps:

  1. Create a Go module, for example: go mod init caddy
  2. Create a main.go file that contains:
package main

import (
	"os"

	caddycmd "github.com/caddyserver/caddy/v2/cmd"
	"golang.org/x/mobile/app"

	// plug in Caddy modules here
	_ "github.com/caddyserver/caddy/v2/modules/standard"
)

func main() {
	// TODO: you can customize the exact command you want to run
	os.Args = []string{os.Args[0], "file-server", "--listen", ":1234", "--browse", "--root", "/sdcard"}
	app.Main(func(_ app.App) {
		caddycmd.Main()
	})
}
  1. Create a file called AndroidManifest.xml with these contents:
<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
	package="org.golang.todo.caddy"
	android:versionCode="1"
	android:versionName="1.0">

	<uses-permission android:name="android.permission.INTERNET" />

	<application
		android:label="Caddy"
		android:debuggable="true"
		android:label="@string/app_name">
	<activity android:name="org.golang.app.GoNativeActivity"
		android:label="Caddy"
		android:configChanges="orientation|keyboardHidden">
		<meta-data android:name="android.app.lib_name" android:value="caddy" />
		<intent-filter>
			<action android:name="android.intent.action.MAIN" />
			<category android:name="android.intent.category.LAUNCHER" />
		</intent-filter>
	</activity>
	</application>
</manifest>

Notably, this file grants your app permission to use the Internet (<uses-permission android:name="android.permission.INTERNET" />). You might need to add other permissions to do other things like access external storage, etc.

  1. With your phone plugged in and with USB debugging enabled, run gomobile install -target android.

The .apk file will be installed on your phone as a native Android app. You can then run it. Woohoo.

4 Likes