code.gitea.io/gitea@v1.22.3/docs/content/installation/with-docker.en-us.md (about) 1 --- 2 date: "2020-03-19T19:27:00+02:00" 3 title: "Installation with Docker" 4 slug: "install-with-docker" 5 sidebar_position: 70 6 toc: false 7 draft: false 8 aliases: 9 - /en-us/install-with-docker 10 menu: 11 sidebar: 12 parent: "installation" 13 name: "With Docker" 14 sidebar_position: 70 15 identifier: "install-with-docker" 16 --- 17 18 # Installation with Docker 19 20 Gitea provides automatically updated Docker images within its Docker Hub organization. It is 21 possible to always use the latest stable tag or to use another service that handles updating 22 Docker images. 23 24 This reference setup guides users through the setup based on `docker-compose`, but the installation 25 of `docker-compose` is out of scope of this documentation. To install `docker-compose` itself, follow 26 the official [install instructions](https://docs.docker.com/compose/install/). 27 28 ## Basics 29 30 The most simple setup just creates a volume and a network and starts the `gitea/gitea:latest` 31 image as a service. Since there is no database available, one can be initialized using SQLite3. 32 Create a directory like `gitea` and paste the following content into a file named `docker-compose.yml`. 33 Note that the volume should be owned by the user/group with the UID/GID specified in the config file. 34 If you don't give the volume correct permissions, the container may not start. 35 For a stable release you can use `:latest`, `:1` or specify a certain release like `:@version@`, but if you'd like to use the latest development version of Gitea then you could use the `:nightly` tag. If you'd like to run the latest commit from a release branch you can use the `:1.x-nightly` tag, where x is the minor version of Gitea. (e.g. `:1.16-nightly`) 36 37 ```yaml 38 version: "3" 39 40 networks: 41 gitea: 42 external: false 43 44 services: 45 server: 46 image: gitea/gitea:@version@ 47 container_name: gitea 48 environment: 49 - USER_UID=1000 50 - USER_GID=1000 51 restart: always 52 networks: 53 - gitea 54 volumes: 55 - ./gitea:/data 56 - /etc/timezone:/etc/timezone:ro 57 - /etc/localtime:/etc/localtime:ro 58 ports: 59 - "3000:3000" 60 - "222:22" 61 ``` 62 63 ## Ports 64 65 To bind the integrated OpenSSH daemon and the webserver on a different port, adjust 66 the port section. It's common to just change the host port and keep the ports within 67 the container like they are. 68 69 ```diff 70 version: "3" 71 72 networks: 73 gitea: 74 external: false 75 76 services: 77 server: 78 image: gitea/gitea:@version@ 79 container_name: gitea 80 environment: 81 - USER_UID=1000 82 - USER_GID=1000 83 restart: always 84 networks: 85 - gitea 86 volumes: 87 - ./gitea:/data 88 - /etc/timezone:/etc/timezone:ro 89 - /etc/localtime:/etc/localtime:ro 90 ports: 91 - - "3000:3000" 92 - - "222:22" 93 + - "8080:3000" 94 + - "2221:22" 95 ``` 96 97 ## Databases 98 99 ### MySQL database 100 101 To start Gitea in combination with a MySQL database, apply these changes to the 102 `docker-compose.yml` file created above. 103 104 ```diff 105 version: "3" 106 107 networks: 108 gitea: 109 external: false 110 111 services: 112 server: 113 image: gitea/gitea:@version@ 114 container_name: gitea 115 environment: 116 - USER_UID=1000 117 - USER_GID=1000 118 + - GITEA__database__DB_TYPE=mysql 119 + - GITEA__database__HOST=db:3306 120 + - GITEA__database__NAME=gitea 121 + - GITEA__database__USER=gitea 122 + - GITEA__database__PASSWD=gitea 123 restart: always 124 networks: 125 - gitea 126 volumes: 127 - ./gitea:/data 128 - /etc/timezone:/etc/timezone:ro 129 - /etc/localtime:/etc/localtime:ro 130 ports: 131 - "3000:3000" 132 - "222:22" 133 + depends_on: 134 + - db 135 + 136 + db: 137 + image: mysql:8 138 + restart: always 139 + environment: 140 + - MYSQL_ROOT_PASSWORD=gitea 141 + - MYSQL_USER=gitea 142 + - MYSQL_PASSWORD=gitea 143 + - MYSQL_DATABASE=gitea 144 + networks: 145 + - gitea 146 + volumes: 147 + - ./mysql:/var/lib/mysql 148 ``` 149 150 ### PostgreSQL database 151 152 To start Gitea in combination with a PostgreSQL database, apply these changes to 153 the `docker-compose.yml` file created above. 154 155 ```diff 156 version: "3" 157 158 networks: 159 gitea: 160 external: false 161 162 services: 163 server: 164 image: gitea/gitea:@version@ 165 container_name: gitea 166 environment: 167 - USER_UID=1000 168 - USER_GID=1000 169 + - GITEA__database__DB_TYPE=postgres 170 + - GITEA__database__HOST=db:5432 171 + - GITEA__database__NAME=gitea 172 + - GITEA__database__USER=gitea 173 + - GITEA__database__PASSWD=gitea 174 restart: always 175 networks: 176 - gitea 177 volumes: 178 - ./gitea:/data 179 - /etc/timezone:/etc/timezone:ro 180 - /etc/localtime:/etc/localtime:ro 181 ports: 182 - "3000:3000" 183 - "222:22" 184 + depends_on: 185 + - db 186 + 187 + db: 188 + image: postgres:14 189 + restart: always 190 + environment: 191 + - POSTGRES_USER=gitea 192 + - POSTGRES_PASSWORD=gitea 193 + - POSTGRES_DB=gitea 194 + networks: 195 + - gitea 196 + volumes: 197 + - ./postgres:/var/lib/postgresql/data 198 ``` 199 200 ## Named volumes 201 202 To use named volumes instead of host volumes, define and use the named volume 203 within the `docker-compose.yml` configuration. This change will automatically 204 create the required volume. You don't need to worry about permissions with 205 named volumes; Docker will deal with that automatically. 206 207 ```diff 208 version: "3" 209 210 networks: 211 gitea: 212 external: false 213 214 +volumes: 215 + gitea: 216 + driver: local 217 + 218 services: 219 server: 220 image: gitea/gitea:@version@ 221 container_name: gitea 222 restart: always 223 networks: 224 - gitea 225 volumes: 226 - - ./gitea:/data 227 + - gitea:/data 228 - /etc/timezone:/etc/timezone:ro 229 - /etc/localtime:/etc/localtime:ro 230 ports: 231 - "3000:3000" 232 - "222:22" 233 ``` 234 235 MySQL or PostgreSQL containers will need to be created separately. 236 237 ## Startup 238 239 To start this setup based on `docker-compose`, execute `docker-compose up -d`, 240 to launch Gitea in the background. Using `docker-compose ps` will show if Gitea 241 started properly. Logs can be viewed with `docker-compose logs`. 242 243 To shut down the setup, execute `docker-compose down`. This will stop 244 and kill the containers. The volumes will still exist. 245 246 Notice: if using a non-3000 port on http, change app.ini to match 247 `LOCAL_ROOT_URL = http://localhost:3000/`. 248 249 ## Installation 250 251 After starting the Docker setup via `docker-compose`, Gitea should be available using a 252 favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the 253 installation wizard. If the database was started with the `docker-compose` setup as 254 documented above, please note that `db` must be used as the database hostname. 255 256 ## Configure the user inside Gitea using environment variables 257 258 - `USER`: **git**: The username of the user that runs Gitea within the container. 259 - `USER_UID`: **1000**: The UID (Unix user ID) of the user that runs Gitea within the container. Match this to the UID of the owner of the `/data` volume if using host volumes (this is not necessary with named volumes). 260 - `USER_GID`: **1000**: The GID (Unix group ID) of the user that runs Gitea within the container. Match this to the GID of the owner of the `/data` volume if using host volumes (this is not necessary with named volumes). 261 262 ## Customization 263 264 Customization files described [here](administration/customizing-gitea.md) should 265 be placed in `/data/gitea` directory. If using host volumes, it's quite easy to access these 266 files; for named volumes, this is done through another container or by direct access at 267 `/var/lib/docker/volumes/gitea_gitea/_data`. The configuration file will be saved at 268 `/data/gitea/conf/app.ini` after the installation. 269 270 ## Upgrading 271 272 :exclamation::exclamation: **Make sure you have volumed data to somewhere outside Docker container** :exclamation::exclamation: 273 274 To upgrade your installation to the latest release: 275 276 ```bash 277 # Edit `docker-compose.yml` to update the version, if you have one specified 278 # Pull new images 279 docker-compose pull 280 # Start a new container, automatically removes old one 281 docker-compose up -d 282 ``` 283 284 ## Managing Deployments With Environment Variables 285 286 In addition to the environment variables above, any settings in `app.ini` can be set 287 or overridden with an environment variable of the form: `GITEA__SECTION_NAME__KEY_NAME`. 288 These settings are applied each time the docker container starts, and won't be passed into Gitea's sub-processes. 289 Full information [here](https://github.com/go-gitea/gitea/tree/master/contrib/environment-to-ini). 290 291 These environment variables can be passed to the docker container in `docker-compose.yml`. 292 The following example will enable an smtp mail server if the required env variables 293 `GITEA__mailer__FROM`, `GITEA__mailer__HOST`, `GITEA__mailer__PASSWD` are set on the host 294 or in a `.env` file in the same directory as `docker-compose.yml`. 295 296 The settings can be also set or overridden with the content of a file by defining an environment variable of the form: 297 `GITEA__section_name__KEY_NAME__FILE` that points to a file. 298 299 ```bash 300 ... 301 services: 302 server: 303 environment: 304 - GITEA__mailer__ENABLED=true 305 - GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set} 306 - GITEA__mailer__PROTOCOL=smtps 307 - GITEA__mailer__SMTP_ADDR=${GITEA__mailer__SMTP_ADDR:?GITEA__mailer__SMTP_ADDR not set} 308 - GITEA__mailer__SMTP_PORT=${GITEA__mailer__SMTP_PORT:?GITEA__mailer__SMTP_PORT not set} 309 - GITEA__mailer__USER=${GITEA__mailer__USER:-apikey} 310 - GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}""" 311 ``` 312 313 Gitea will generate new secrets/tokens for every new installation automatically and write them into the app.ini. If you want to set the secrets/tokens manually, you can use the following docker commands to use of Gitea's built-in [generate utility functions](administration/command-line.md#generate). Do not lose/change your SECRET_KEY after the installation, otherwise the encrypted data can not be decrypted anymore. 314 315 The following commands will output a new `SECRET_KEY` and `INTERNAL_TOKEN` to `stdout`, which you can then place in your environment variables. 316 317 ```bash 318 docker run -it --rm gitea/gitea:1 gitea generate secret SECRET_KEY 319 docker run -it --rm gitea/gitea:1 gitea generate secret INTERNAL_TOKEN 320 ``` 321 322 ```yaml 323 ... 324 services: 325 server: 326 environment: 327 - GITEA__security__SECRET_KEY=[value returned by generate secret SECRET_KEY] 328 - GITEA__security__INTERNAL_TOKEN=[value returned by generate secret INTERNAL_TOKEN] 329 ``` 330 331 ## SSH Container Passthrough 332 333 Since SSH is running inside the container, SSH needs to be passed through from the host to the container if SSH support is desired. One option would be to run the container SSH on a non-standard port (or moving the host port to a non-standard port). Another option which might be more straightforward is for Gitea users to ssh to a Gitea user on the host which will then relay those connections to the docker. 334 335 ### Understanding SSH access to Gitea (without passthrough) 336 337 To understand what needs to happen, you first need to understand what happens without passthrough. So we will try to explain this: 338 339 1. The client adds their SSH public key to Gitea using the webpage. 340 2. Gitea will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. 341 3. This entry has the public key, but also has a `command=` option. It is this command that Gitea uses to match this key to the client user and manages authentication. 342 4. The client then makes an SSH request to the SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 343 5. The client will attempt to authenticate with the server, passing one or more public keys one at a time to the server. 344 6. For each key the client provides, the SSH server will first check its configuration for an `AuthorizedKeysCommand` to see if the public key matches, and then the `git` user's `authorized_keys` file. 345 7. The first entry that matches will be selected, and assuming this is a Gitea entry, the `command=` will now be executed. 346 8. The SSH server creates a user session for the `git` user, and using the shell for the `git` user runs the `command=` 347 9. This runs `gitea serv` which takes over control of the rest of the SSH session and manages gitea authentication & authorization of the git commands. 348 349 Now, for the SSH passthrough to work, we need the host SSH to match the public keys and then run the `gitea serv` on the docker. There are multiple ways of doing this. However, all of these require some information about the docker being passed to the host. 350 351 ### SSHing Shim (with authorized_keys) 352 353 In this option, the idea is that the host simply uses the `authorized_keys` that gitea creates but at step 9 the `gitea` command that the host runs is a shim that actually runs ssh to go into the docker and then run the real docker `gitea` itself. 354 355 - To make the forwarding work, the SSH port of the container (22) needs to be mapped to the host port 2222 in `docker-compose.yml` . Since this port does not need to be exposed to the outside world, it can be mapped to the `localhost` of the host machine: 356 357 ```yaml 358 ports: 359 # [...] 360 - "127.0.0.1:2222:22" 361 ``` 362 363 - Next on the host create the `git` user which shares the same `UID`/ `GID` as the container values `USER_UID`/ `USER_GID`. These values can be set as environment variables in the `docker-compose.yml`: 364 365 ```yaml 366 environment: 367 - USER_UID=1000 368 - USER_GID=1000 369 ``` 370 371 - Mount `/home/git/.ssh` of the host into the container. This ensures that the `authorized_keys` file is shared between the host `git` user and the container `git` user otherwise the SSH authentication cannot work inside the container. 372 373 ```yaml 374 volumes: 375 - /home/git/.ssh/:/data/git/.ssh 376 ``` 377 378 - Now a SSH key pair needs to be created on the host. This key pair will be used to authenticate the `git` user on the host to the container. As an administrative user on the host run: (by administrative user we mean a user that can sudo to root) 379 380 ```bash 381 sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key" 382 ``` 383 384 - Please note depending on the local version of ssh you may want to consider using `-t ecdsa` here. 385 386 - `/home/git/.ssh/authorized_keys` on the host now needs to be modified. It needs to act in the same way as `authorized_keys` within the Gitea container. Therefore add the public key of the key you created above ("Gitea Host Key") to `~/git/.ssh/authorized_keys`. As an administrative user on the host run: 387 388 ```bash 389 sudo -u git cat /home/git/.ssh/id_rsa.pub | sudo -u git tee -a /home/git/.ssh/authorized_keys 390 sudo -u git chmod 600 /home/git/.ssh/authorized_keys 391 ``` 392 393 Important: The pubkey from the `git` user needs to be added "as is" while all other pubkeys added via the Gitea web interface will be prefixed with `command="/usr [...]`. 394 395 `/home/git/.ssh/authorized_keys` should then look somewhat like 396 397 ```bash 398 # SSH pubkey from git user 399 ssh-rsa <Gitea Host Key> 400 401 # other keys from users 402 command="/usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty <user pubkey> 403 ``` 404 405 - The next step is to create the fake host `gitea` command that will forward commands from the host to the container. The name of this file depends on your version of Gitea: 406 407 - For Gitea v1.16.0+. As an administrative user on the host run: 408 409 ```bash 410 cat <<"EOF" | sudo tee /usr/local/bin/gitea 411 #!/bin/sh 412 ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" 413 EOF 414 sudo chmod +x /usr/local/bin/gitea 415 ``` 416 417 Here is a detailed explanation what is happening when a SSH request is made: 418 419 1. The client adds their SSH public key to Gitea using the webpage. 420 2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. 421 - However, because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key has been added to the host `git` user's `authorized_keys` file too. 422 3. This entry has the public key, but also has a `command=` option. 423 - This command matches the location of the Gitea binary on the container, but also the location of the shim on the host. 424 4. The client then makes an SSH request to the host SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 425 5. The client will attempt to authenticate with the server, passing one or more public keys in turn to the host. 426 6. For each key the client provides, the host SSH server will first check its configuration for an `AuthorizedKeysCommand` to see if the public key matches, and then the host `git` user's `authorized_keys` file. 427 - Because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key they added to the Gitea web will be found 428 7. The first entry that matches will be selected, and assuming this is a Gitea entry, the `command=` will now be executed. 429 8. The host SSH server creates a user session for the `git` user, and using the shell for the host `git` user runs the `command=` 430 9. This means that the host runs the host `/usr/local/bin/gitea` shim that opens an SSH from the host to container passing the rest of the command arguments directly to `/usr/local/bin/gitea` on the container. 431 10. Meaning that the container `gitea serv` is run, taking over control of the rest of the SSH session and managing gitea authentication & authorization of the git commands. 432 433 **Notes** 434 435 SSH container passthrough using `authorized_keys` will work only if 436 437 - `opensshd` is used in the container 438 - if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation 439 - `LOCAL_ROOT_URL` is not changed (depending on the changes) 440 441 If you try to run `gitea` on the host, you will attempt to ssh to the container and thence run the `gitea` command there. 442 443 Never add the `Gitea Host Key` as a SSH key to a user on the Gitea interface. 444 445 ### SSHing Shell (with authorized_keys) 446 447 In this option, the idea is that the host simply uses the `authorized_keys` that gitea creates but at step 8 above we change the shell that the host runs to ssh directly into the docker and then run the shell there. This means that the `gitea` that is then run is the real docker `gitea`. 448 449 - In this case we setup as per SSHing Shim except instead of creating `/usr/local/bin/gitea` 450 we create a new shell for the git user. As an administrative user on the host run: 451 452 ```bash 453 cat <<"EOF" | sudo tee /home/git/ssh-shell 454 #!/bin/sh 455 shift 456 ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $@" 457 EOF 458 sudo chmod +x /home/git/ssh-shell 459 sudo usermod -s /home/git/ssh-shell git 460 ``` 461 462 Be careful here - if you try to login as the git user in future you will ssh directly to the docker. 463 464 Here is a detailed explanation what is happening when a SSH request is made: 465 466 1. The client adds their SSH public key to Gitea using the webpage. 467 2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. 468 - However, because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key has been added to the host `git` user's `authorized_keys` file too. 469 3. This entry has the public key, but also has a `command=` option. 470 - This command matches the location of the Gitea binary on the container. 471 4. The client then makes an SSH request to the host SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 472 5. The client will attempt to authenticate with the server, passing one or more public keys in turn to the host. 473 6. For each key the client provides, the host SSH server will first check its configuration for an `AuthorizedKeysCommand` to see if the public key matches, and then the host `git` user's `authorized_keys` file. 474 - Because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key they added to the Gitea web will be found 475 7. The first entry that matches will be selected, and assuming this is a Gitea entry, the `command=` will now be executed. 476 8. The host SSH server creates a user session for the `git` user, and using the shell for the host `git` user runs the `command=` 477 9. The shell of the host `git` user is now our `ssh-shell` which opens an SSH connection from the host to container, (which opens a shell on the container for the container `git`). 478 10. The container shell now runs the `command=` option meaning that the container `gitea serv` is run, taking over control of the rest of the SSH session and managing gitea authentication & authorization of the git commands. 479 480 **Notes** 481 482 SSH container passthrough using `authorized_keys` will work only if 483 484 - `opensshd` is used in the container 485 - if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation 486 - `LOCAL_ROOT_URL` is not changed (depending on the changes) 487 488 If you try to login as the `git` user on the host in future you will ssh directly to the docker. 489 490 Never add the `Gitea Host Key` as a SSH key to a user on the Gitea interface. 491 492 ### Docker Shell (with authorized_keys) 493 494 Similar to the above ssh shell technique we can use a shell which simply uses `docker exec`. As an administrative user on the host run: 495 496 ```bash 497 cat <<"EOF" | sudo tee /home/git/docker-shell 498 #!/bin/sh 499 /usr/bin/docker exec -i -u git --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@" 500 EOF 501 sudo chmod +x /home/git/docker-shell 502 sudo usermod -s /home/git/docker-shell git 503 ``` 504 505 Here is a detailed explanation what is happening when a SSH request is made: 506 507 1. The client adds their SSH public key to Gitea using the webpage. 508 2. Gitea in the container will add an entry for this key to the `.ssh/authorized_keys` file of its running user, `git`. 509 - However, because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key has been added to the host `git` user's `authorized_keys` file too. 510 3. This entry has the public key, but also has a `command=` option. 511 - This command matches the location of the Gitea binary on the container. 512 4. The client then makes an SSH request to the host SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 513 5. The client will attempt to authenticate with the server, passing one or more public keys in turn to the host. 514 6. For each key the client provides, the host SSH server will first check its configuration for an `AuthorizedKeysCommand` to see if the public key matches, and then the host `git` user's `authorized_keys` file. 515 - Because `/home/git/.ssh/` on the host is mounted as `/data/git/.ssh` this means that the key they added to the Gitea web will be found 516 7. The first entry that matches will be selected, and assuming this is a Gitea entry, the `command=` will now be executed. 517 8. The host SSH server creates a user session for the `git` user, and using the shell for the host `git` user runs the `command=` 518 9. The shell of the host `git` user is now our `docker-shell` which uses `docker exec` to open a shell for the `git` user on the container. 519 10. The container shell now runs the `command=` option meaning that the container `gitea serv` is run, taking over control of the rest of the SSH session and managing gitea authentication & authorization of the git commands. 520 521 Note that `gitea` in the docker command above is the name of the container. If you named yours differently, don't forget to change that. The host `git` user also has to have 522 permission to run `docker exec`. 523 524 **Notes** 525 526 Docker shell passthrough using `authorized_keys` will work only if 527 528 - `opensshd` is used in the container 529 - if `AuthorizedKeysCommand` is _not used_ in combination with `SSH_CREATE_AUTHORIZED_KEYS_FILE=false` to disable authorized files key generation 530 - `LOCAL_ROOT_URL` is not changed (depending on the changes) 531 532 If you try to login as the `git` user on the host in future you will `docker exec` directly to the docker. 533 534 A Docker execing shim could be created similarly to above. 535 536 ### Docker Shell with AuthorizedKeysCommand 537 538 The AuthorizedKeysCommand route provides another option that does not require many changes to the compose file or the `authorized_keys` - but does require changes to the host `/etc/sshd_config`. 539 540 In this option, the idea is that the host SSH uses an `AuthorizedKeysCommand` instead of relying on sharing the `authorized_keys` file that gitea creates. We continue to use a special shell at step 8 above to exec into the docker and then run the shell there. This means that the `gitea` that is then run is the real docker `gitea`. 541 542 - On the host create a `git` user with permission to run `docker exec`. 543 - We will again assume that the Gitea container is called `gitea`. 544 - Modify the `git` user's shell to forward commands to the `sh` executable inside the container using `docker exec`. As an administrative user on the host run: 545 546 ```bash 547 cat <<"EOF" | sudo tee /home/git/docker-shell 548 #!/bin/sh 549 /usr/bin/docker exec -i -u git --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@" 550 EOF 551 sudo chmod +x /home/git/docker-shell 552 sudo usermod -s /home/git/docker-shell git 553 ``` 554 555 Now all attempts to login as the `git` user on the host will be forwarded to the docker - including the `SSH_ORIGINAL_COMMAND`. We now need to set-up SSH authentication on the host. 556 557 We will do this by leveraging the [SSH AuthorizedKeysCommand](administration/command-line.md#keys) to match the keys against those accepted by Gitea. 558 559 Add the following block to `/etc/ssh/sshd_config`, on the host: 560 561 ```bash 562 Match User git 563 AuthorizedKeysCommandUser git 564 AuthorizedKeysCommand /usr/bin/docker exec -i -u git gitea /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k 565 ``` 566 567 (From 1.16.0 you will not need to set the `-c /data/gitea/conf/app.ini` option.) 568 569 Finally restart the SSH server. As an administrative user on the host run: 570 571 ```bash 572 sudo systemctl restart sshd 573 ``` 574 575 Here is a detailed explanation what is happening when a SSH request is made: 576 577 1. The client adds their SSH public key to Gitea using the webpage. 578 2. Gitea in the container will add an entry for this key to its database. 579 3. The client then makes an SSH request to the host SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 580 4. The client will attempt to authenticate with the server, passing one or more public keys in turn to the host. 581 5. For each key the client provides, the host SSH server will checks its configuration for an `AuthorizedKeysCommand`. 582 6. The host runs the above `AuthorizedKeysCommand`, which execs in to the docker and then runs the `gitea keys` command. 583 7. Gitea on the docker will look in it's database to see if the public key matches and will return an entry like that of an `authorized_keys` command. 584 8. This entry has the public key, but also has a `command=` option which matches the location of the Gitea binary on the container. 585 9. The host SSH server creates a user session for the `git` user, and using the shell for the host `git` user runs the `command=`. 586 10. The shell of the host `git` user is now our `docker-shell` which uses `docker exec` to open a shell for the `git` user on the container. 587 11. The container shell now runs the `command=` option meaning that the container `gitea serv` is run, taking over control of the rest of the SSH session and managing gitea authentication & authorization of the git commands. 588 589 **Notes** 590 591 Docker shell passthrough using `AuthorizedKeysCommand` will work only if 592 593 - The host `git` user is allowed to run the `docker exec` command. 594 595 If you try to login as the `git` user on the host in future you will `docker exec` directly to the docker. 596 597 A Docker execing shim could be created similarly to above. 598 599 ### SSH Shell with AuthorizedKeysCommand 600 601 Create a key for the host `git` user as above, add it to the docker `/data/git/.ssh/authorized_keys` then finally create and set the `ssh-shell` as above. 602 603 Add the following block to `/etc/ssh/sshd_config`, on the host: 604 605 ```bash 606 Match User git 607 AuthorizedKeysCommandUser git 608 AuthorizedKeysCommand /usr/bin/ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k 609 ``` 610 611 (From 1.16.0 you will not need to set the `-c /data/gitea/conf/app.ini` option.) 612 613 Finally restart the SSH server. As an administrative user on the host run: 614 615 ```bash 616 sudo systemctl restart sshd 617 ``` 618 619 Here is a detailed explanation what is happening when a SSH request is made: 620 621 1. The client adds their SSH public key to Gitea using the webpage. 622 2. Gitea in the container will add an entry for this key to its database. 623 3. The client then makes an SSH request to the host SSH server using the `git` user, e.g. `git clone git@domain:user/repo.git`. 624 4. The client will attempt to authenticate with the server, passing one or more public keys in turn to the host. 625 5. For each key the client provides, the host SSH server will checks its configuration for an `AuthorizedKeysCommand`. 626 6. The host runs the above `AuthorizedKeysCommand`, which will SSH in to the docker and then run the `gitea keys` command. 627 7. Gitea on the docker will look in it's database to see if the public key matches and will return an entry like that of an `authorized_keys` command. 628 8. This entry has the public key, but also has a `command=` option which matches the location of the Gitea binary on the container. 629 9. The host SSH server creates a user session for the `git` user, and using the shell for the host `git` user runs the `command=`. 630 10. The shell of the host `git` user is now our `git-shell` which uses SSH to open a shell for the `git` user on the container. 631 11. The container shell now runs the `command=` option meaning that the container `gitea serv` is run, taking over control of the rest of the SSH session and managing gitea authentication & authorization of the git commands. 632 633 **Notes** 634 635 SSH container passthrough using `AuthorizedKeysCommand` will work only if 636 637 - `opensshd` is running on the container 638 639 If you try to login as the `git` user on the host in future you will `ssh` directly to the docker. 640 641 Never add the `Gitea Host Key` as a SSH key to a user on the Gitea interface. 642 643 SSHing shims could be created similarly to above.