Commit Graph

103 Commits

Author SHA1 Message Date
Dmytro Shteflyuk
c63ec39f07 Added a test for colliding hosts passed via hosts array 2024-09-29 20:56:23 -04:00
Donal McBreen
63f854ea18 Add validations for host/ssl roles
Roles with SSL can only have one server.
Two roles with SSL can't use the same host.
2024-09-18 17:42:45 +01:00
Donal McBreen
d7d6fa34b0 Use Volume for kamal proxy config volume 2024-09-16 16:44:58 +01:00
Donal McBreen
cb73c730f9 No need for run_id 2024-09-16 16:44:58 +01:00
Donal McBreen
a40b644145 Check that there's no traefik hooks left behind 2024-09-16 16:44:58 +01:00
Donal McBreen
f4d309c5cc Rip out Traefik 2024-09-16 16:44:55 +01:00
Donal McBreen
27a7b339a6 Drop run_directory configuration option
We need to drop to be fixed so multiple applications put the config in
the same place.
2024-09-16 16:44:41 +01:00
Donal McBreen
d2d0223c37 Require an arch to be set, and default to amd64 in the template 2024-08-29 08:45:51 +01:00
Donal McBreen
29c723f7ec Add support for configuration extensions
Allow blocks prefixed with `x-` in the configuration as a place to
declare reusable blocks with YAML anchors and aliases.

Borrowed from the Docker Compose configuration file format -
https://github.com/compose-spec/compose-spec/blob/main/spec.md#extension

Thanks to @ruyrocha for the suggestion.
2024-07-15 20:47:55 +01:00
Donal McBreen
4f317b8499 Configuration validation
Validate the Kamal configuration giving useful warning on errors.
Each section of the configuration has its own config class and a YAML
file containing documented example configuration.

You can run `kamal docs` to see the example configuration, and
`kamal docs <section>` to see the example configuration for a specific
section.

The validation matches the configuration to the example configuration
checking that there are no unknown keys and that the values are of
matching types.

Where there is more complex validation - e.g for envs and servers, we
have custom validators that implement those rules.

Additonally the configuration examples are used to generate the
configuration documentation in the kamal-site repo.

You generate them by running:

```
bundle exec bin/docs <kamal-site-checkout>
```
2024-06-04 14:19:29 +01:00
Donal McBreen
0efb5ccfff Remove the healthcheck step
To speed up deployments, we'll remove the healthcheck step.

This adds some risk to deployments for non-web roles - if they don't
have a Docker healthcheck configured then the only check we do is if
the container is running.

If there is a bad image we might see the container running before it
exits and deploy it. Previously the healthcheck step would have avoided
this by ensuring a web container could boot and serve traffic first.

To mitigate this, we'll add a deployment barrier. Until one of the
primary role containers passes its healthcheck, we'll keep the barrier
up and avoid stopping the containers on the non-primary roles.

It the primary role container fails its healthcheck, we'll close the
barrier and shut down the new containers on the waiting roles.

We also have a new integration test to check we correctly handle a
a broken image. This highlighted that SSHKit's default runner will
stop at the first error it encounters. We'll now have a custom runner
that waits for all threads to finish allowing them to clean up.
2024-05-20 12:18:30 +01:00
Matthew Kent
b8aaddb4c9 Apply --hosts and --roles filters to traefik hosts as well. 2024-04-26 17:08:57 -07:00
Tim Tilberg
69f90387a8 Allow capital letters to match valid service name, such as in MyApp 2024-04-15 09:09:58 -05:00
Donal McBreen
53bfefeb2f Make building from a git archive the default
If no context is specified and we are in a git repo, then we'll build
from a git archive by default. This means we don't need a separate
setting and gives us a safer default build.
2024-03-27 08:42:10 +00:00
Donal McBreen
f3b7569032 Build from a git archive
Building directly from a checkout will pull in uncommitted files to or
more sneakily files that are git ignored, but not docker ignored.

To avoid this, we'll add an option to build from a git archive of HEAD
instead. Docker doesn't provide a way to build directly from a git
repo, so instead we create a tarball of the current HEAD with git
archive and pipe it into the build command.

When building from a git archive, we'll still display the warning about
uncommitted changes, but we won't add the `_uncommitted_...` suffix to
the container name as they won't be included in the build.

Perhaps this should be the default, but we'll leave that decision for
now.
2024-03-27 08:38:56 +00:00
Donal McBreen
3ecfb3744f Add Rubocop
- Pull in the 37signals house style
- Autofix violations
- Add to CI
2024-03-20 10:23:02 +00:00
Donal McBreen
4966d52919 Pass around Roles instead of Strings
Avoid looking up roles by names everywhere. This avoids the awkward
role/role_config naming as well.
2024-03-08 08:44:35 +00:00
Donal McBreen
cc8c508556 Merge branch 'main' into valid_service_name 2024-03-05 11:02:33 +00:00
Nick Hammond
3b16e047c5 Add hyphen to the allowed character list for service name 2024-03-04 10:03:22 -07:00
Donal McBreen
6892abb4be Config the number of containers to keep
By default we keep 5 containers around for rollback. The containers
don't take much space, but the images for them can.

Make the number of containers to retain configurable, either in the
config with the `retain_containers` setting on the command line
with the `--retain` option.
2024-03-04 11:55:45 +00:00
Nick Hammond
a02af74dda Add a simple validation to the service name to prevent setup issues 2024-02-22 09:47:48 -07:00
Yoel Cabo
7472e5dfa6 Merge remote-tracking branch 'origin/main' into feat/no-web 2023-11-14 12:11:18 +01:00
Matthew Kent
60187cc3a4 Add allow_empty_roles to control aborting on roles with no hosts.
This added flexibility allows you to define base roles that might not
necessarily exist in each deploy destination.
2023-11-12 08:54:28 -08:00
Yoel Cabo
87cb8c1f71 fix: allow configurations without web roles 2023-11-12 09:39:07 +01:00
Matthew Kent
073f745677 Test for both undefined roles and missing traefik. 2023-11-11 12:57:52 -08:00
Matthew Kent
d0ac6507e7 Add test coverage. 2023-11-10 16:49:37 -08:00
Leon
792aa1dbdf Add SSH port option 2023-11-03 22:32:37 +01:00
Donal McBreen
f6662c7a8f Remove the env check
The env check is not needded anymore as all the commands rely on the
env files having already been created remotely.

The only place the env is needed is when running `kamal env push` and
that will still raise an apropriate error.
2023-09-25 15:23:01 +01:00
dhh
e95a9b4fa2 Fix tests 2023-09-16 11:35:29 -07:00
dhh
cfbfb37e23 Extract Kamal::Git as gateway for all git usage 2023-09-16 11:30:29 -07:00
Donal McBreen
60835d13a8 Merge pull request #444 from rience/custom-healthcheck-log-lines-count
Configurable Number of Lines in Healthcheck Log Output
2023-09-13 08:57:00 +01:00
Krzysztof Adamski
892cf0e66b Configurable Log Lines Number in Healthcheck Log Output 2023-09-12 21:06:36 +02:00
Krzysztof Adamski
8ddc484ce6 Configurable Lines Number in Healthcheck Log Output 2023-09-12 21:04:18 +02:00
Donal McBreen
daa53f5831 Merge pull request #451 from basecamp/require-destinations
Add a require_destination setting
2023-09-12 08:26:36 +01:00
Donal McBreen
00cb7d99d8 Merge pull request #449 from basecamp/asset-path
Asset paths
2023-09-12 08:26:07 +01:00
Donal McBreen
26dcd75423 Add a require_destination setting
If you always want to use a destination, and have a base deploy.yml file
that doesn't specify any hosts, then if you forget to specific the
destination you will get a cryptic error.

Add a "require_destination" setting you can use to avoid this.
2023-09-11 16:57:11 +01:00
Donal McBreen
718776eb72 Prune healthcheck containers
If a deployment is interrupted it could leave stale healthcheck
containers around that prevent dependent images from being pruned.
2023-09-11 14:36:25 +01:00
Donal McBreen
0b439362da Asset paths
During deployments both the old and new containers will be active for a
small period of time. There also may be lagging requests for older CSS
and JS after the deployment.

This can lead to 404s if a request for old assets hits a new container
or visa-versa.

This PR makes sure that both sets of assets are available throughout the
deployment from before the new version of the app is booted.

This can be configured by setting the asset path:

```yaml
asset_path: "/rails/public/assets"
```

The process is:
1. We extract the assets out of the container, with docker run, docker
cp, docker stop. Docker run sets the container command to "sleep" so
this needs to be available in the container.
2. We create an asset volume directory on the host for the new version
of the app on the host and copy the assets in there.
3. If there is a previous deployment we also copy the new assets into
its asset volume and copy the older assets into the new asset volume.
4. We start the new container mapping the asset volume over the top of
the container's asset path.

This means the both the old and new versions have replaced the asset
path with a volume containing both sets of assets and should be able
to serve any request during the deployment. The older assets will
continue to be available until the next deployment.
2023-09-11 12:18:18 +01:00
Donal McBreen
cccf79ed94 Merge branch 'main' into fix/ssh-auth-methods 2023-09-07 10:21:28 +01:00
Gianni Chiappetta
9a539ffc86 chore: update tests to remove hardcoded ssh auth method 2023-09-06 10:59:17 -04:00
Donal McBreen
8a41d15b69 Zero downtime deployment with cord file
When replacing a container currently we:
1. Boot the new container
2. Wait for it to become healthy
3. Stop the old container

Traefik will send requests to the old container until it notices that it
is unhealthy. But it may have stopped serving requests before that point
which can result in errors.

To get round that the new boot process is:

1. Create a directory with a single file on the host
2. Boot the new container, mounting the cord file into /tmp and
including a check for the file in the docker healthcheck
3. Wait for it to become healthy
4. Delete the healthcheck file ("cut the cord") for the old container
5. Wait for it to become unhealthy and give Traefik a couple of seconds
to notice
6. Stop the old container

The extra steps ensure that Traefik stops sending requests before the
old container is shutdown.
2023-09-06 14:35:30 +01:00
Donal McBreen
94bf090657 Copy env files to remote hosts
Setting env variables in the docker arguments requires having them on
the deploy host.

Instead we'll add two new commands `kamal env push` and
`kamal env delete` which will manage copying the environment as .env
files to the remote host.

Docker will pick up the file with `--env-file <path-to-file>`. Env files
will be stored under `<kamal run directory>/env`.

Running `kamal env push` will create env files for each role and
accessory, and traefik if required.

`kamal envify` has been updated to also push the env files.

By avoiding using `kamal envify` and creating the local and remote
secrets manually, you can now avoid accessing secrets needed
for the docker runtime environment locally. You will still need build
secrets.

One thing to note - the Docker doesn't parse the environment variables
in the env file, one result of this is that you can't specify multi-line
values - see https://github.com/moby/moby/issues/12997.

We maybe need to look docker config or docker secrets longer term to get
around this.

Hattip to @kevinmcconnell - this was all his idea.
2023-09-06 14:33:13 +01:00
Donal McBreen
adc7173cf2 Merge pull request #437 from basecamp/kamal-run-directory
Configurable Kamal directory
2023-09-06 14:31:07 +01:00
Krzysztof Adamski
c2b2f7ea33 Fixing Tests 2023-09-06 10:16:59 +02:00
Donal McBreen
787688ea08 kamal -> .kamal 2023-08-28 17:13:52 +01:00
Donal McBreen
bcfa1d83e8 Configurable Kamal directory
To avoid polluting the default SSH directory with lots of Kamal config,
we'll default to putting them in a `kamal` sub directory.

But also make the directory configurable with the `run_directory` key,
so for example you can set it as `/var/run/kamal/`

The directory is created during bootstrap or before any command that
will need to access a file.
2023-08-28 16:32:18 +01:00
David Heinemeier Hansson
c4a203e648 Rename to Kamal 2023-08-22 08:24:31 -07:00
Donal McBreen
1163c3de07 Configurable log levels
Allow ssh log_level to be set - this will help to debug connection
issues.
2023-08-15 16:51:56 +01:00
Donal McBreen
aa89ededde Merge pull request #399 from mrsked/manage-ssh-connection-starts
Manage SSH connection starts
2023-08-07 14:37:34 +01:00
Donal McBreen
94d6a763a8 Extract ssh and sshkit configuration 2023-07-26 12:26:23 +01:00