While Caddy can be run directly with its [command line interface](/docs/command-line), there are numerous advantages to using a service manager to keep it running, such as ensuring it starts automatically when the system reboots and to capture stdout/stderr logs.
- [**`caddy.service`**](https://github.com/caddyserver/dist/blob/master/init/caddy.service) if you configure Caddy with a [Caddyfile](/docs/caddyfile). If you prefer to use a different config adapter or a JSON config file, you may [override](#overrides) the `ExecStart` and `ExecReload` commands.
- [**`caddy-api.service`**](https://github.com/caddyserver/dist/blob/master/init/caddy-api.service) if you configure Caddy solely through its [API](/docs/api). This service uses the [`--resume`](/docs/command-line#caddy-run) option which will start Caddy using the `autosave.json` which is [persisted](/docs/json/admin/config/) by default.
They are very similar, but differ in the `ExecStart` and `ExecReload` commands to accommodate the workflows.
If you need to switch between the services, you should disable and stop the previous one before enabling and starting the other. For example, to switch from the `caddy` service to the `caddy-api` service:
Some [installation methods](/docs/install) automatically set up Caddy to run as a service. If you chose a method that did not, you may follow these instructions to do so:
**Requirements:**
-`caddy` binary that you [downloaded](/download) or [built from source](/docs/build)
-`systemctl --version` 232 or newer
-`sudo` privileges
Move the caddy binary into your `$PATH`, for example:
If using a config file, be sure it is readable by the `caddy` user you just created.
Next, [choose a systemd unit file](#unit-files) based on your use case.
**Double-check the `ExecStart` and `ExecReload` directives.** Make sure the binary's location and command line arguments are correct for your installation! For example: if using a config file, change your `--config` path if it is different from the defaults.
The usual place to save the service file is: `/etc/systemd/system/caddy.service`
After saving your service file, you can start the service for the first time with the usual systemctl dance:
You can place your static site files in either `/var/www/html` or `/srv`. Make sure the `caddy` user has permission to read the files.
To verify that the service is running:
<pre><codeclass="cmd bash">systemctl status caddy</code></pre>
The status command will also show the location of the currently running service file.
When running with our official service file, Caddy's output will be redirected to `journalctl`. To read your full logs and to avoid lines being truncated:
<pre><codeclass="cmd bash">journalctl -u caddy --no-pager | less +G</code></pre>
If using a config file, you can gracefully reload Caddy after making any changes:
The Caddy process will run as the `caddy` user, which has its `$HOME` set to `/var/lib/caddy`. This means that:
- The default [data storage location](/docs/conventions#data-directory) (for certificates and other state information) will be in `/var/lib/caddy/.local/share/caddy`.
- The default [config storage location](/docs/conventions#configuration-directory) (for the auto-saved JSON config, primarily useful for the `caddy-api` service) will be in `/var/lib/caddy/.config/caddy`.
This will open a blank file with your default terminal text editor in which you can override or add directives to the unit definition. This is called a "drop-in" file.
Or, for example if you need to change the config file from the default of the Caddyfile, to instead using a JSON file (note that `Exec*` directives [must be reset with empty strings](https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=) before setting a new value):
```systemd
[Service]
ExecStart=
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/caddy.json
The simplest way to get up and running with Docker is to use Docker Compose. See the docs on [Docker Hub](https://hub.docker.com/_/caddy) for more additional details about the official Caddy Docker image.
<asideclass="tip">
This assumes you're using [Docker Compose V2](https://docs.docker.com/compose/reference/), where the command is now `docker compose` (space). instead of V1's `docker-compose` (hyphen).
Make sure to fill in the image `<version>` with the latest version number, which you can find listed on [Docker Hub](https://hub.docker.com/_/caddy) under the "Tags" section.
What this does:
- Uses the `unless-stopped` restart policy to make sure the Caddy container is restarted automatically when your machine is rebooted.
- Binds to ports `80` and `443` for HTTP and HTTPS respectively, plus `443/udp` for HTTP/3.
- Bind mounts the `Caddyfile` file which is your Caddy configuration.
- Bind mounts the `site` directory to serve your site's static files from `/srv`.
- Named volumes for `/data` and `/config` to [persist important information](/docs/conventions#file-locations).
If you have static files to serve, you may place them in a `site/` directory beside the configs, then set the [`root`](/docs/caddyfile/directives/root) using `root * /srv`. If you don't, then you may remove the `/srv` volume mount.
<asideclass="tip">
If you're using Caddy to [reverse proxy](/docs/caddyfile/directives/reverse_proxy) to another container, remember that in Docker networking, `localhost` means "this container", not "this machine". So for example, do not use `reverse_proxy localhost:8080`, instead use `reverse_proxy other-container:8080`
When using Docker for local development with HTTPS, you might use a [hostname](/docs/caddyfile/concepts#addresses) like `localhost` or `app.localhost`. This enables [Local HTTPS](/docs/automatic-https#local-https) using Caddy's local CA to issue certificates. This means that HTTP clients outside the container will not trust the TLS certificate served by Caddy. To solve this, you may install Caddy's root CA cert on your host machine's trust store: