Deploy Docker Apps (Kit and Pro Plan)
Docker in DOM Cloud is powered by Podman. It's always run in rootless mode and allows running 24/7. Because of how powerful and resouce consuming this is only available with Kit
and Pro
user plan.
The podman
CLI is available as a system-wide packages. docker
is simply an alias to podman
. A preconfiguration is required by activating podman
feature via system runner to:
- assign
/etc/subuid
+/etc/subgid
to allow podman rootless using sub uids for assigning containers. - assign
/var/lib/systemd/linger
to allow backround processes not get killed when SSH session terminates.
Port Allocation Policy
A docker service should run all the time and have a standby port hidden from the internet.
Remember that DOM Cloud servers is a shared hosting environment, so only expose your port only for public-facing service. A port between 9000 and 32000 is a recommended port number. A port number 32768 and above is not recommended as it's an ephemeral ports only for internal/test usage (firewall don't block incoming traffic for them).
We'll choose this number for you by random for use through the documentation: 9669
Example
The deployment script below activates docker
capabilities and starts a "hello world" podman container for demo.
source: clear
features:
- docker
nginx:
passenger:
enabled: 'on'
app_start_command: 'socat TCP-LISTEN:$PORT,fork TCP:localhost:9669'
commands:
- docker run -t --name webserver -p 9669:80 quay.io/libpod/banner
Let's examine the reason why we use docker run
commands as such:
- Using
run
will create and start a new container pulled fromquay.io/libpod/banner
. - We're forwarding from host's port with number 9669 to container's port with number
80
. This port number is permanent. - The
80
from-p $PORT:80
implies that the app (quay.io/libpod/banner
) is listening on port80
inside the container. --name webserver
denotes the name of this container iswebserver
for easy debugging when inspecting via SSH later.socat
is used as port forwarder from$PORT
given from passenger phusion to9669
which your docker
Example with Docker Compose
To use docker-compose.yml
, you need to run it via podman-compose
. docker compose
is not available due to Podman version is still on 4.6.1
.
The example below setup Plausible self-hosting with their database depedencies.
# Requires Kit plan or higher!
source: https://github.com/plausible/hosting
features:
- docker
nginx:
root: public_html/public
passenger:
enabled: 'on'
app_start_command: 'socat TCP-LISTEN:$PORT,fork TCP:localhost:9669'
commands:
- get_hash() { openssl rand -base64 64 | tr -d '\n'; }
- sed -i 's/8000:8000/9669:8000/g' docker-compose.yml
- echo BASE_URL=https://$DOMAIN > plausible-conf.env
- echo SECRET_KEY_BASE=`get_hash` >> plausible-conf.env
- podman-compose down
- podman-compose up -d
Boot at system startup
While it's infrequent, our server may restart during scaling and other reasons. So future-proof your docker instance using systemd. That will make your docker app run at boot.
commands:
- mkdir -p ~/.config/systemd/user
- filename: app.service
content: |
[Unit]
Description=App Daemon
After=network-online.target
[Service]
Type=simple
WorkingDirectory=%h/public_html
ExecStart=/usr/bin/env podman-compose up -d
ExecReload=/usr/bin/env podman-compose down
Restart=always
[Install]
WantedBy=default.target
- mv app.service ~/.config/systemd/user/app.service
- systemctl --user daemon-reload
- systemctl --user start app
- systemctl --user enable app
After this have been implemented you can also start, restart and stop your docker app using systemctl --user start app
, systemctl --user restart app
and systemctl --user stop app
respectively.
Differences
Using docker has benefit compared other deployment system. These includes:
Allow additional background services
Adding entries to /var/lib/systemd/linger
will make sure that your processes won't get killed anytime you log out from SSH session. This also means you can add custom database system (like MongoDB and Redis) simply by pulling and starting the database service with detached mode (or using docker's compose).
Note that with this benefit limitations by Fair Usage still implies. We won't restrict your CPU and RAM limits but still watching overall system performance and deliberately kills it if it proven to abuse our resources. Additionally, there should be no public port exposed to the host other than what's given from passenger's $PORT
to avoid depleting server's ports allocations.
Allow building apps by Continous Integration (CI)
While other deployment system is benefited by simpler DX (you can code and fix bugs directly in production) and incremental builds, there are often a reasonable choices to use CI to build apps and only deliver the binary to us via docker images.
One of the benefit is you will be able to version your binaries via CI artifacts, this including releasing binaries via code versioning. This also added more security by not exposing your valuable source code to us, and lesser computation and storage used for compiling binaries by delegating it to CI instead of from our server.
... (example deployment code)
Advanced logging and microservice managements
Here are some additional reasons to use docker:
- Use
docker compose
to configure your apps along with its service depedencies - Use
docker ps
to inspect running containers, Usedocker logs
to inspect logs - Allow limiting CPU and RAM resources
- And many more...