mirror of https://github.com/go-gitea/gitea
docker: rootless image (#10154)
* docker: rootless image * improve docs + remove check for write perm on custom * add more info on ssh passtrough * Add comment for internal ssh server in container configpull/13380/head
parent
f3bbd46c49
commit
fe458ce877
@ -0,0 +1,68 @@ |
||||
|
||||
################################### |
||||
#Build stage |
||||
FROM golang:1.15-alpine3.12 AS build-env |
||||
|
||||
ARG GOPROXY |
||||
ENV GOPROXY ${GOPROXY:-direct} |
||||
|
||||
ARG GITEA_VERSION |
||||
ARG TAGS="sqlite sqlite_unlock_notify" |
||||
ENV TAGS "bindata timetzdata $TAGS" |
||||
ARG CGO_EXTRA_CFLAGS |
||||
|
||||
#Build deps |
||||
RUN apk --no-cache add build-base git nodejs npm |
||||
|
||||
#Setup repo |
||||
COPY . ${GOPATH}/src/code.gitea.io/gitea |
||||
WORKDIR ${GOPATH}/src/code.gitea.io/gitea |
||||
|
||||
#Checkout version if set |
||||
RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \ |
||||
&& make clean-all build |
||||
|
||||
FROM alpine:3.12 |
||||
LABEL maintainer="maintainers@gitea.io" |
||||
|
||||
EXPOSE 2222 3000 |
||||
|
||||
RUN apk --no-cache add \ |
||||
bash \ |
||||
ca-certificates \ |
||||
gettext \ |
||||
git \ |
||||
gnupg |
||||
|
||||
RUN addgroup \ |
||||
-S -g 1000 \ |
||||
git && \ |
||||
adduser \ |
||||
-S -H -D \ |
||||
-h /var/lib/gitea/git \ |
||||
-s /bin/bash \ |
||||
-u 1000 \ |
||||
-G git \ |
||||
git && \ |
||||
echo "git:$(dd if=/dev/urandom bs=24 count=1 status=none | base64)" | chpasswd |
||||
|
||||
RUN mkdir -p /var/lib/gitea /etc/gitea |
||||
RUN chown git:git /var/lib/gitea /etc/gitea |
||||
|
||||
COPY docker/rootless / |
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /usr/local/bin/gitea |
||||
RUN chown root:root /usr/local/bin/* && chmod 755 /usr/local/bin/* |
||||
|
||||
USER git:git |
||||
ENV GITEA_WORK_DIR /var/lib/gitea |
||||
ENV GITEA_CUSTOM /var/lib/gitea/custom |
||||
ENV GITEA_TEMP /tmp/gitea |
||||
#TODO add to docs the ability to define the ini to load (usefull to test and revert a config) |
||||
ENV GITEA_APP_INI /etc/gitea/app.ini |
||||
ENV HOME "/var/lib/gitea/git" |
||||
VOLUME ["/var/lib/gitea", "/etc/gitea"] |
||||
WORKDIR /var/lib/gitea |
||||
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] |
||||
CMD [] |
||||
|
@ -0,0 +1,19 @@ |
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}}-rootless |
||||
{{#if build.tags}} |
||||
tags: |
||||
{{#each build.tags}} |
||||
- {{this}} |
||||
{{/each}} |
||||
{{/if}} |
||||
manifests: |
||||
- |
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-amd64-rootless |
||||
platform: |
||||
architecture: amd64 |
||||
os: linux |
||||
- |
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64-rootless |
||||
platform: |
||||
architecture: arm64 |
||||
os: linux |
||||
variant: v8 |
@ -0,0 +1,58 @@ |
||||
APP_NAME = $APP_NAME |
||||
RUN_USER = $RUN_USER |
||||
RUN_MODE = $RUN_MODE |
||||
|
||||
[repository] |
||||
ROOT = $GITEA_WORK_DIR/git/repositories |
||||
|
||||
[repository.local] |
||||
LOCAL_COPY_PATH = $GITEA_TEMP/local-repo |
||||
|
||||
[repository.upload] |
||||
TEMP_PATH = $GITEA_TEMP/uploads |
||||
|
||||
[server] |
||||
APP_DATA_PATH = $GITEA_WORK_DIR |
||||
SSH_DOMAIN = $SSH_DOMAIN |
||||
HTTP_PORT = $HTTP_PORT |
||||
ROOT_URL = $ROOT_URL |
||||
DISABLE_SSH = $DISABLE_SSH |
||||
; In rootless gitea container only internal ssh server is supported |
||||
START_SSH_SERVER = true |
||||
SSH_PORT = $SSH_PORT |
||||
SSH_LISTEN_PORT = $SSH_LISTEN_PORT |
||||
BUILTIN_SSH_SERVER_USER = $RUN_USER |
||||
LFS_START_SERVER = $LFS_START_SERVER |
||||
LFS_CONTENT_PATH = $GITEA_WORK_DIR/git/lfs |
||||
|
||||
[database] |
||||
PATH = $GITEA_WORK_DIR/data/gitea.db |
||||
DB_TYPE = $DB_TYPE |
||||
HOST = $DB_HOST |
||||
NAME = $DB_NAME |
||||
USER = $DB_USER |
||||
PASSWD = $DB_PASSWD |
||||
|
||||
[indexer] |
||||
ISSUE_INDEXER_PATH = $GITEA_WORK_DIR/data/indexers/issues.bleve |
||||
|
||||
[session] |
||||
PROVIDER_CONFIG = $GITEA_WORK_DIR/data/sessions |
||||
|
||||
[picture] |
||||
AVATAR_UPLOAD_PATH = $GITEA_WORK_DIR/data/avatars |
||||
REPOSITORY_AVATAR_UPLOAD_PATH = $GITEA_WORK_DIR/data/gitea/repo-avatars |
||||
|
||||
[attachment] |
||||
PATH = $GITEA_WORK_DIR/data/attachments |
||||
|
||||
[log] |
||||
ROOT_PATH = $GITEA_WORK_DIR/data/log |
||||
|
||||
[security] |
||||
INSTALL_LOCK = $INSTALL_LOCK |
||||
SECRET_KEY = $SECRET_KEY |
||||
|
||||
[service] |
||||
DISABLE_REGISTRATION = $DISABLE_REGISTRATION |
||||
REQUIRE_SIGNIN_VIEW = $REQUIRE_SIGNIN_VIEW |
@ -0,0 +1,11 @@ |
||||
#!/bin/sh |
||||
|
||||
if [ -x /usr/local/bin/docker-setup.sh ]; then |
||||
/usr/local/bin/docker-setup.sh || { echo 'docker setup failed' ; exit 1; } |
||||
fi |
||||
|
||||
if [ $# -gt 0 ]; then |
||||
exec "$@" |
||||
else |
||||
exec /usr/local/bin/gitea -c ${GITEA_APP_INI} web |
||||
fi |
@ -0,0 +1,48 @@ |
||||
#!/bin/bash |
||||
|
||||
# Prepare git folder |
||||
mkdir -p ${HOME} && chmod 0700 ${HOME} |
||||
if [ ! -w ${HOME} ]; then echo "${HOME} is not writable"; exit 1; fi |
||||
|
||||
# Prepare custom folder |
||||
mkdir -p ${GITEA_CUSTOM} && chmod 0500 ${GITEA_CUSTOM} |
||||
|
||||
# Prepare temp folder |
||||
mkdir -p ${GITEA_TEMP} && chmod 0700 ${GITEA_TEMP} |
||||
if [ ! -w ${GITEA_TEMP} ]; then echo "${GITEA_TEMP} is not writable"; exit 1; fi |
||||
|
||||
#Prepare config file |
||||
if [ ! -f ${GITEA_APP_INI} ]; then |
||||
|
||||
#Prepare config file folder |
||||
GITEA_APP_INI_DIR=$(dirname ${GITEA_APP_INI}) |
||||
mkdir -p ${GITEA_APP_INI_DIR} && chmod 0700 ${GITEA_APP_INI_DIR} |
||||
if [ ! -w ${GITEA_APP_INI_DIR} ]; then echo "${GITEA_APP_INI_DIR} is not writable"; exit 1; fi |
||||
|
||||
# Set INSTALL_LOCK to true only if SECRET_KEY is not empty and |
||||
# INSTALL_LOCK is empty |
||||
if [ -n "$SECRET_KEY" ] && [ -z "$INSTALL_LOCK" ]; then |
||||
INSTALL_LOCK=true |
||||
fi |
||||
|
||||
# Substitude the environment variables in the template |
||||
APP_NAME=${APP_NAME:-"Gitea: Git with a cup of tea"} \ |
||||
RUN_MODE=${RUN_MODE:-"dev"} \ |
||||
RUN_USER=${USER:-"git"} \ |
||||
SSH_DOMAIN=${SSH_DOMAIN:-"localhost"} \ |
||||
HTTP_PORT=${HTTP_PORT:-"3000"} \ |
||||
ROOT_URL=${ROOT_URL:-""} \ |
||||
DISABLE_SSH=${DISABLE_SSH:-"false"} \ |
||||
SSH_PORT=${SSH_PORT:-"2222"} \ |
||||
SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-$SSH_PORT} \ |
||||
DB_TYPE=${DB_TYPE:-"sqlite3"} \ |
||||
DB_HOST=${DB_HOST:-"localhost:3306"} \ |
||||
DB_NAME=${DB_NAME:-"gitea"} \ |
||||
DB_USER=${DB_USER:-"root"} \ |
||||
DB_PASSWD=${DB_PASSWD:-""} \ |
||||
INSTALL_LOCK=${INSTALL_LOCK:-"false"} \ |
||||
DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-"false"} \ |
||||
REQUIRE_SIGNIN_VIEW=${REQUIRE_SIGNIN_VIEW:-"false"} \ |
||||
SECRET_KEY=${SECRET_KEY:-""} \ |
||||
envsubst < /etc/templates/app.ini > ${GITEA_APP_INI} |
||||
fi |
@ -0,0 +1,296 @@ |
||||
--- |
||||
date: "2020-02-09T20:00:00+02:00" |
||||
title: "Installation with Docker (rootless)" |
||||
slug: "install-with-docker-rootless" |
||||
weight: 10 |
||||
toc: true |
||||
draft: true |
||||
menu: |
||||
sidebar: |
||||
parent: "installation" |
||||
name: "With Docker Rootless" |
||||
weight: 10 |
||||
identifier: "install-with-docker-rootless" |
||||
--- |
||||
|
||||
# Installation with Docker |
||||
|
||||
Gitea provides automatically updated Docker images within its Docker Hub organization. It is |
||||
possible to always use the latest stable tag or to use another service that handles updating |
||||
Docker images. |
||||
|
||||
The rootless image use Gitea internal ssh to provide git protocol and doesn't support openssh. |
||||
|
||||
This reference setup guides users through the setup based on `docker-compose`, but the installation |
||||
of `docker-compose` is out of scope of this documentation. To install `docker-compose` itself, follow |
||||
the official [install instructions](https://docs.docker.com/compose/install/). |
||||
|
||||
## Basics |
||||
|
||||
The most simple setup just creates a volume and a network and starts the `gitea/gitea:latest-rootless` |
||||
image as a service. Since there is no database available, one can be initialized using SQLite3. |
||||
Create a directory for `data` and `config` then paste the following content into a file named `docker-compose.yml`. |
||||
Note that the volume should be owned by the user/group with the UID/GID specified in the config file. By default Gitea in docker will use uid:1000 gid:1000. If needed you can set ownership on those folders with the command: `sudo chown 1000:1000 config/ data/` |
||||
If you don't give the volume correct permissions, the container may not start. |
||||
Also be aware that the tag `:latest-rootless` will install the current development version. |
||||
For a stable release you can use `:1-rootless` or specify a certain release like `:{{< version >}}-rootless`. |
||||
|
||||
```yaml |
||||
version: "2" |
||||
|
||||
services: |
||||
server: |
||||
image: gitea/gitea:latest-rootless |
||||
restart: always |
||||
volumes: |
||||
- ./data:/var/lib/gitea |
||||
- ./config:/etc/gitea |
||||
- /etc/timezone:/etc/timezone:ro |
||||
- /etc/localtime:/etc/localtime:ro |
||||
ports: |
||||
- "3000:3000" |
||||
- "2222:2222" |
||||
``` |
||||
|
||||
## Custom port |
||||
|
||||
To bind the integrated ssh and the webserver on a different port, adjust |
||||
the port section. It's common to just change the host port and keep the ports within |
||||
the container like they are. |
||||
|
||||
```diff |
||||
version: "2" |
||||
|
||||
services: |
||||
server: |
||||
image: gitea/gitea:latest-rootless |
||||
restart: always |
||||
volumes: |
||||
- ./data:/var/lib/gitea |
||||
- ./config:/etc/gitea |
||||
- /etc/timezone:/etc/timezone:ro |
||||
- /etc/localtime:/etc/localtime:ro |
||||
ports: |
||||
- - "3000:3000" |
||||
- - "2222:2222" |
||||
+ - "80:3000" |
||||
+ - "22:2222" |
||||
``` |
||||
|
||||
## MySQL database |
||||
|
||||
To start Gitea in combination with a MySQL database, apply these changes to the |
||||
`docker-compose.yml` file created above. |
||||
|
||||
```diff |
||||
version: "2" |
||||
|
||||
services: |
||||
server: |
||||
image: gitea/gitea:latest-rootless |
||||
+ environment: |
||||
+ - DB_TYPE=mysql |
||||
+ - DB_HOST=db:3306 |
||||
+ - DB_NAME=gitea |
||||
+ - DB_USER=gitea |
||||
+ - DB_PASSWD=gitea |
||||
restart: always |
||||
volumes: |
||||
- ./data:/var/lib/gitea |
||||
- ./config:/etc/gitea |
||||
- /etc/timezone:/etc/timezone:ro |
||||
- /etc/localtime:/etc/localtime:ro |
||||
ports: |
||||
- "3000:3000" |
||||
- "222:22" |
||||
+ depends_on: |
||||
+ - db |
||||
+ |
||||
+ db: |
||||
+ image: mysql:5.7 |
||||
+ restart: always |
||||
+ environment: |
||||
+ - MYSQL_ROOT_PASSWORD=gitea |
||||
+ - MYSQL_USER=gitea |
||||
+ - MYSQL_PASSWORD=gitea |
||||
+ - MYSQL_DATABASE=gitea |
||||
+ volumes: |
||||
+ - ./mysql:/var/lib/mysql |
||||
``` |
||||
|
||||
## PostgreSQL database |
||||
|
||||
To start Gitea in combination with a PostgreSQL database, apply these changes to |
||||
the `docker-compose.yml` file created above. |
||||
|
||||
```diff |
||||
version: "2" |
||||
|
||||
services: |
||||
server: |
||||
image: gitea/gitea:latest-rootless |
||||
environment: |
||||
+ - DB_TYPE=postgres |
||||
+ - DB_HOST=db:5432 |
||||
+ - DB_NAME=gitea |
||||
+ - DB_USER=gitea |
||||
+ - DB_PASSWD=gitea |
||||
restart: always |
||||
volumes: |
||||
- ./data:/var/lib/gitea |
||||
- ./config:/etc/gitea |
||||
- /etc/timezone:/etc/timezone:ro |
||||
- /etc/localtime:/etc/localtime:ro |
||||
ports: |
||||
- "3000:3000" |
||||
- "2222:2222" |
||||
+ depends_on: |
||||
+ - db |
||||
+ |
||||
+ db: |
||||
+ image: postgres:9.6 |
||||
+ restart: always |
||||
+ environment: |
||||
+ - POSTGRES_USER=gitea |
||||
+ - POSTGRES_PASSWORD=gitea |
||||
+ - POSTGRES_DB=gitea |
||||
+ volumes: |
||||
+ - ./postgres:/var/lib/postgresql/data |
||||
``` |
||||
|
||||
## Named volumes |
||||
|
||||
To use named volumes instead of host volumes, define and use the named volume |
||||
within the `docker-compose.yml` configuration. This change will automatically |
||||
create the required volume. You don't need to worry about permissions with |
||||
named volumes; Docker will deal with that automatically. |
||||
|
||||
```diff |
||||
version: "2" |
||||
|
||||
+volumes: |
||||
+ gitea: |
||||
+ driver: local |
||||
+ |
||||
services: |
||||
server: |
||||
image: gitea/gitea:latest-rootless |
||||
restart: always |
||||
volumes: |
||||
- - ./data:/var/lib/gitea |
||||
+ - gitea-data:/var/lib/gitea |
||||
- - ./config:/etc/gitea |
||||
+ - gitea-config:/etc/gitea |
||||
- /etc/timezone:/etc/timezone:ro |
||||
- /etc/localtime:/etc/localtime:ro |
||||
ports: |
||||
- "3000:3000" |
||||
- "2222:2222" |
||||
``` |
||||
|
||||
MySQL or PostgreSQL containers will need to be created separately. |
||||
|
||||
## Custom user |
||||
|
||||
You can choose to use a custom user (following --user flag definition https://docs.docker.com/engine/reference/run/#user). |
||||
As an example to clone the host user `git` definition use the command `id -u git` and add it to `docker-compose.yml` file: |
||||
Please make sure that the mounted folders are writable by the user. |
||||
|
||||
```diff |
||||
version: "2" |
||||
|
||||
services: |
||||
server: |
||||
image: gitea/gitea:latest-rootless |
||||
restart: always |
||||
+ user: 1001 |
||||
volumes: |
||||
- ./data:/var/lib/gitea |
||||
- ./config:/etc/gitea |
||||
- /etc/timezone:/etc/timezone:ro |
||||
- /etc/localtime:/etc/localtime:ro |
||||
ports: |
||||
- "3000:3000" |
||||
- "2222:2222" |
||||
``` |
||||
|
||||
## Start |
||||
|
||||
To start this setup based on `docker-compose`, execute `docker-compose up -d`, |
||||
to launch Gitea in the background. Using `docker-compose ps` will show if Gitea |
||||
started properly. Logs can be viewed with `docker-compose logs`. |
||||
|
||||
To shut down the setup, execute `docker-compose down`. This will stop |
||||
and kill the containers. The volumes will still exist. |
||||
|
||||
Notice: if using a non-3000 port on http, change app.ini to match |
||||
`LOCAL_ROOT_URL = http://localhost:3000/`. |
||||
|
||||
## Install |
||||
|
||||
After starting the Docker setup via `docker-compose`, Gitea should be available using a |
||||
favorite browser to finalize the installation. Visit http://server-ip:3000 and follow the |
||||
installation wizard. If the database was started with the `docker-compose` setup as |
||||
documented above, please note that `db` must be used as the database hostname. |
||||
|
||||
## Environments variables |
||||
|
||||
You can configure some of Gitea's settings via environment variables: |
||||
|
||||
(Default values are provided in **bold**) |
||||
|
||||
* `APP_NAME`: **"Gitea: Git with a cup of tea"**: Application name, used in the page title. |
||||
* `RUN_MODE`: **dev**: For performance and other purposes, change this to `prod` when deployed to a production environment. |
||||
* `SSH_DOMAIN`: **localhost**: Domain name of this server, used for the displayed clone URL in Gitea's UI. |
||||
* `SSH_PORT`: **2222**: SSH port displayed in clone URL. |
||||
* `SSH_LISTEN_PORT`: **%(SSH\_PORT)s**: Port for the built-in SSH server. |
||||
* `DISABLE_SSH`: **false**: Disable SSH feature when it's not available. |
||||
* `HTTP_PORT`: **3000**: HTTP listen port. |
||||
* `ROOT_URL`: **""**: Overwrite the automatically generated public URL. This is useful if the internal and the external URL don't match (e.g. in Docker). |
||||
* `LFS_START_SERVER`: **false**: Enables git-lfs support. |
||||
* `DB_TYPE`: **sqlite3**: The database type in use \[mysql, postgres, mssql, sqlite3\]. |
||||
* `DB_HOST`: **localhost:3306**: Database host address and port. |
||||
* `DB_NAME`: **gitea**: Database name. |
||||
* `DB_USER`: **root**: Database username. |
||||
* `DB_PASSWD`: **"\<empty>"**: Database user password. Use \`your password\` for quoting if you use special characters in the password. |
||||
* `INSTALL_LOCK`: **false**: Disallow access to the install page. |
||||
* `SECRET_KEY`: **""**: Global secret key. This should be changed. If this has a value and `INSTALL_LOCK` is empty, `INSTALL_LOCK` will automatically set to `true`. |
||||
* `DISABLE_REGISTRATION`: **false**: Disable registration, after which only admin can create accounts for users. |
||||
* `REQUIRE_SIGNIN_VIEW`: **false**: Enable this to force users to log in to view any page. |
||||
|
||||
# Customization |
||||
|
||||
Customization files described [here](https://docs.gitea.io/en-us/customizing-gitea/) should |
||||
be placed in `/var/lib/gitea/custom` directory. If using host volumes, it's quite easy to access these |
||||
files; for named volumes, this is done through another container or by direct access at |
||||
`/var/lib/docker/volumes/gitea_gitea/_/var_lib_gitea`. The configuration file will be saved at |
||||
`/etc/gitea/app.ini` after the installation. |
||||
|
||||
# Upgrading |
||||
|
||||
:exclamation::exclamation: **Make sure you have volumed data to somewhere outside Docker container** :exclamation::exclamation: |
||||
|
||||
To upgrade your installation to the latest release: |
||||
``` |
||||
# Edit `docker-compose.yml` to update the version, if you have one specified |
||||
# Pull new images |
||||
docker-compose pull |
||||
# Start a new container, automatically removes old one |
||||
docker-compose up -d |
||||
``` |
||||
|
||||
# Upgrading from standard image |
||||
|
||||
- Backup your setup |
||||
- Change volume mountpoint from /data to /var/lib/gitea |
||||
- If you used a custom app.ini move it to a new volume mounted to /etc/gitea |
||||
- Rename folder (inside volume) gitea to custom |
||||
- Edit app.ini if needed |
||||
- Set START_SSH_SERVER = true |
||||
- Use image gitea/gitea:latest-rootless |
||||
|
||||
# SSH Container Passthrough (not tested) |
||||
|
||||
This should be possible by forcing `authorized_keys` generation via `gitea admin regenerate keys`. |
||||
|
||||
We should use directly [SSH AuthorizedKeysCommand](https://docs.gitea.io/en-us/command-line/#keys) when it will be based on internal api. |
Loading…
Reference in new issue