mirror of
https://github.com/phusion/baseimage-docker.git
synced 2026-09-21 16:58:12 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6836d462fc | ||
|
|
f6eae18e51 | ||
|
|
c87dcdf546 | ||
|
|
9c9ffde394 | ||
|
|
b5c34e9776 | ||
|
|
e4ae9aac10 | ||
|
|
e97d8464b9 | ||
|
|
0dc0303a03 | ||
|
|
fc6672b4bb | ||
|
|
d616b3bafb | ||
|
|
89597c5bc5 | ||
|
|
36bd41108f | ||
|
|
386b8284d8 | ||
|
|
6d6395c58f | ||
|
|
4a3476b6a6 | ||
|
|
ad88ec9226 | ||
|
|
17a737f47b | ||
|
|
9d29b23db2 | ||
|
|
089258a746 | ||
|
|
4f65f0a270 | ||
|
|
14394bcb3f | ||
|
|
a9fdb8878d | ||
|
|
d0b150c5ef | ||
|
|
c18b511311 | ||
|
|
60e2cdd375 | ||
|
|
31fce7a874 | ||
|
|
55bb086681 | ||
|
|
dd699da614 | ||
|
|
1be96f1edf | ||
|
|
8be7395886 | ||
|
|
a9ae3334ed | ||
|
|
3b511622e0 | ||
|
|
fdc1008c17 | ||
|
|
ac37bcf2bd | ||
|
|
0d22512947 | ||
|
|
4e78e19a34 | ||
|
|
14d156ce73 | ||
|
|
10c7bbf3b4 | ||
|
|
b41f997b6c | ||
|
|
c14fecb3b1 | ||
|
|
3e62736510 | ||
|
|
8b50080470 | ||
|
|
dd336f2bf0 | ||
|
|
e8d48f3af4 | ||
|
|
d37f7aff3f | ||
|
|
f802be0dfe | ||
|
|
5493db5179 | ||
|
|
becf747182 | ||
|
|
0c9eaf3c43 | ||
|
|
673cd89f41 | ||
|
|
8cf2e208ff | ||
|
|
924f874d7e | ||
|
|
b89b718067 | ||
|
|
422781c7cf | ||
|
|
ed15d0d250 | ||
|
|
a018aba0c2 | ||
|
|
dd9d23f1ea | ||
|
|
d796c2e32c | ||
|
|
f936902c23 | ||
|
|
43791943e5 | ||
|
|
2f0e1ad0b8 | ||
|
|
92a357a41f | ||
|
|
996e31b743 | ||
|
|
cb8cd8ad82 | ||
|
|
69a8fc1246 | ||
|
|
12718e6954 | ||
|
|
be8fc49e52 | ||
|
|
14896d9181 | ||
|
|
9d63ae751c | ||
|
|
c5b6ed442d | ||
|
|
c40591ee2c | ||
|
|
be5d910bad | ||
|
|
db73c10615 | ||
|
|
733dac8706 | ||
|
|
768d4b4d3f | ||
|
|
b20ebe448c | ||
|
|
adf8fd7805 | ||
|
|
670f189553 | ||
|
|
e81e664a72 | ||
|
|
6b8be06bba | ||
|
|
efc5865789 | ||
|
|
300b96fb93 | ||
|
|
1bffe76e6a | ||
|
|
7a639692ab | ||
|
|
fdfe6b1937 | ||
|
|
90e411fec2 | ||
|
|
95d89dd251 | ||
|
|
06e2983ba9 | ||
|
|
5ab2367f76 | ||
|
|
61d585bce9 | ||
|
|
b77633463f | ||
|
|
9bb3117b0c | ||
|
|
338238d685 | ||
|
|
c5680a44b1 | ||
|
|
4468bb296e | ||
|
|
25d13ef2b8 | ||
|
|
4cb596bfc9 | ||
|
|
42c48d8465 | ||
|
|
18a10580e1 | ||
|
|
d765626688 | ||
|
|
69d1b96431 | ||
|
|
89389d5086 | ||
|
|
70b5c73902 | ||
|
|
7c7ab1a0a6 | ||
|
|
b05616332a | ||
|
|
421ca4ea05 | ||
|
|
c41f837f82 | ||
|
|
fcc1283c85 | ||
|
|
ffc1f6db05 | ||
|
|
6a774f2f48 | ||
|
|
c7efb776b8 | ||
|
|
2be1e6f407 | ||
|
|
2bb9d89325 | ||
|
|
8d7f3abd2d | ||
|
|
91363dcf37 | ||
|
|
0cf1fd05ac | ||
|
|
544511f883 | ||
|
|
0ad69ad848 | ||
|
|
39ad242428 | ||
|
|
a52c8d4ae0 | ||
|
|
1bd5b85eb1 | ||
|
|
1a235a13e1 | ||
|
|
0e15f28fb7 | ||
|
|
d6702be8c3 | ||
|
|
40bad74956 | ||
|
|
a6bf447f9e | ||
|
|
b57f08c71f | ||
|
|
a3faefd3d3 | ||
|
|
cd23614b27 | ||
|
|
914f0967b0 | ||
|
|
068b4534d4 | ||
|
|
2a8c9ebe38 | ||
|
|
7f77348a6b | ||
|
|
9f998e1a09 | ||
|
|
59d209cbe8 | ||
|
|
7022d31858 | ||
|
|
263b582139 | ||
|
|
f7dfb05850 | ||
|
|
8f7fcfec33 | ||
|
|
b2c329af51 | ||
|
|
f012793a75 | ||
|
|
d3af157387 | ||
|
|
9c934771ad | ||
|
|
7f7b164d20 | ||
|
|
06b065782d | ||
|
|
287e96c811 | ||
|
|
a6fd9f8b56 | ||
|
|
10d2364014 | ||
|
|
8af7692f62 | ||
|
|
ac382d47b8 | ||
|
|
a7b8b36359 | ||
|
|
41fbb91544 | ||
|
|
93477b34cc | ||
|
|
f706ea8d92 | ||
|
|
a5469e5572 | ||
|
|
3801457f3a | ||
|
|
079464dc43 | ||
|
|
8b99273eb6 | ||
|
|
3c0e09426d | ||
|
|
48d3f310ad | ||
|
|
45facca75e | ||
|
|
3a315a1590 | ||
|
|
59677e23c3 | ||
|
|
d2c7194aa4 | ||
|
|
00034a9965 | ||
|
|
ce6a9e0dfc | ||
|
|
17a5cede8c | ||
|
|
f7bba93be3 | ||
|
|
6216f70411 | ||
|
|
34408d8013 | ||
|
|
5d80f284b0 | ||
|
|
e3eeed2091 | ||
|
|
f9838ccce0 | ||
|
|
ce5038b2a7 | ||
|
|
c1d2b4bad8 | ||
|
|
8f33bcf3d2 | ||
|
|
ce2a25ddc0 | ||
|
|
7e02e426e5 | ||
|
|
cc1659b829 | ||
|
|
5205fa04f7 | ||
|
|
70e2551ca7 | ||
|
|
9fed983d80 | ||
|
|
2a9860b120 | ||
|
|
a09aae6dba | ||
|
|
8c842a35d7 | ||
|
|
e019d5fa11 | ||
|
|
75784205cf | ||
|
|
d9e762730a | ||
|
|
7ec5a0a65f | ||
|
|
5cc60221e6 | ||
|
|
15e27eefe6 | ||
|
|
1c6b9f11d1 | ||
|
|
e12eeb8083 | ||
|
|
d8a7ca7a4d | ||
|
|
96a2d92978 | ||
|
|
67a0c6d121 | ||
|
|
1811cb7530 | ||
|
|
fdda2d42bf | ||
|
|
4e5a7e91ce | ||
|
|
e89e07acb5 | ||
|
|
116cf0e2dd | ||
|
|
241c41e093 | ||
|
|
ffb22ecf60 | ||
|
|
7400c0b3b8 | ||
|
|
4e80b8540a | ||
|
|
9920d9d834 | ||
|
|
ac1211b0ed | ||
|
|
bb3fef5377 | ||
|
|
d3eceae5ef | ||
|
|
ecdbe62eca | ||
|
|
24b8bcebc8 | ||
|
|
096c0d4d2e | ||
|
|
ce8fc04b74 | ||
|
|
9001796aa8 | ||
|
|
c6cc1cb8e9 | ||
|
|
50db81d8be | ||
|
|
82862ec7f7 | ||
|
|
3edd5d1564 | ||
|
|
6d5518974f | ||
|
|
a81f293bfb | ||
|
|
c93a14391a | ||
|
|
1f39ac326f | ||
|
|
823ff30f36 | ||
|
|
e436d1c4af | ||
|
|
5f0849ba4b | ||
|
|
3fe0878edb | ||
|
|
ea6b0ace79 | ||
|
|
17eadef537 | ||
|
|
8ec76f25ca | ||
|
|
6052c7a3e7 | ||
|
|
bfd971a084 | ||
|
|
d141556910 | ||
|
|
19d67d820c | ||
|
|
14ec533a16 | ||
|
|
784d9837ee | ||
|
|
d3f2382c73 | ||
|
|
e053f04cf6 | ||
|
|
bbc639b372 | ||
|
|
f8c4992d03 | ||
|
|
567a53db24 | ||
|
|
850d7374c4 | ||
|
|
c1ed635f33 | ||
|
|
9adbd423d0 | ||
|
|
7425da2825 | ||
|
|
23d0a30e59 | ||
|
|
6ec9f8ca59 | ||
|
|
6b09bb736f | ||
|
|
06b010919b | ||
|
|
c56b1a332f | ||
|
|
afb0835328 | ||
|
|
a9e956d9f9 | ||
|
|
43af4a393e | ||
|
|
b72ef2eba3 | ||
|
|
404832ba47 | ||
|
|
ee56097511 | ||
|
|
f57320388c | ||
|
|
e575443aba | ||
|
|
9e65ebfbdc | ||
|
|
68a94437d9 | ||
|
|
f7beb9218c | ||
|
|
2761d369d3 | ||
|
|
196d44590f | ||
|
|
c5daad6a18 | ||
|
|
9089485fb6 | ||
|
|
e54970d76c | ||
|
|
b3232acad0 | ||
|
|
ffe8b447ca | ||
|
|
7bc3d1252d | ||
|
|
2a9cccff16 | ||
|
|
e1848ec817 | ||
|
|
a898aa51b9 | ||
|
|
cf48520dba | ||
|
|
1ab802c396 | ||
|
|
b931dc5a47 | ||
|
|
25f48b847d | ||
|
|
d04ad47930 | ||
|
|
45c57234d7 | ||
|
|
c983f03960 | ||
|
|
eb23de21d9 | ||
|
|
3a5afa485a | ||
|
|
efd9a67a79 | ||
|
|
5eeb176bd0 | ||
|
|
3678d6d92a | ||
|
|
795f12a554 | ||
|
|
4f52a9c6a4 | ||
|
|
1812fbf093 | ||
|
|
65e212f235 | ||
|
|
bc40f72c84 | ||
|
|
4a41a00697 | ||
|
|
d85b76dfd9 | ||
|
|
a0e2a13b0a | ||
|
|
c1c5e70dd5 | ||
|
|
6e55e3d515 | ||
|
|
0b2de757f5 | ||
|
|
9b08ea9cd4 | ||
|
|
2640bc7b03 | ||
|
|
a0a48d8fd3 | ||
|
|
d9023071e4 | ||
|
|
8f2877c806 | ||
|
|
19c2df66b3 | ||
|
|
ea56d35011 | ||
|
|
e77d34aedf | ||
|
|
81af926a78 | ||
|
|
c4385735af | ||
|
|
e54a443cca | ||
|
|
4db83076bd | ||
|
|
fc74a85e5d | ||
|
|
04173bb162 | ||
|
|
715a6eebde | ||
|
|
2d2c13b519 | ||
|
|
2135d2192e | ||
|
|
ae652517e8 | ||
|
|
212e080b58 | ||
|
|
97e256cc61 | ||
|
|
f0514872ea | ||
|
|
0de8640bac | ||
|
|
5e5794c528 | ||
|
|
9be2ee2916 | ||
|
|
a0d4877272 | ||
|
|
a06da035d0 | ||
|
|
d55fa363bf | ||
|
|
eb189e7864 | ||
|
|
7fd667bc1f | ||
|
|
5106ffd4b1 | ||
|
|
3526928ad9 | ||
|
|
9cf192ca02 | ||
|
|
25e8b1c535 | ||
|
|
2fa47a225b | ||
|
|
b9d75d899d | ||
|
|
1f38e2226e | ||
|
|
291b9aae02 | ||
|
|
75902437c9 | ||
|
|
73d900dece | ||
|
|
669435158f | ||
|
|
a32cbb7808 | ||
|
|
070245feb8 | ||
|
|
f58282d4d3 | ||
|
|
e6258b37b5 | ||
|
|
71ce2a6d9d | ||
|
|
08d5b93095 | ||
|
|
7d2bdfe67e | ||
|
|
d0e63da07b | ||
|
|
2beb0e253e | ||
|
|
0302713554 | ||
|
|
7ac6795aa5 | ||
|
|
feab2fce75 | ||
|
|
3019bbf09b | ||
|
|
18a7fe26ec | ||
|
|
b9d788611a | ||
|
|
1357e9399e | ||
|
|
ba1e1ffbf5 | ||
|
|
0b468fb61b | ||
|
|
9db4f43b74 | ||
|
|
5806f51ea3 | ||
|
|
c431f2d151 | ||
|
|
76100b639a | ||
|
|
ecf6e6b226 | ||
|
|
92c2ea22ed | ||
|
|
436be20ff0 | ||
|
|
f445cafe03 | ||
|
|
93572a5698 | ||
|
|
f5efca365c | ||
|
|
949bd1d89f | ||
|
|
2b339a3344 | ||
|
|
b665b78454 | ||
|
|
5b403fe06c | ||
|
|
1a6c43b8d7 | ||
|
|
0325abf74e | ||
|
|
22c3d60d94 | ||
|
|
b56693beb3 | ||
|
|
612b1504af | ||
|
|
7bde5d9993 | ||
|
|
af11b5e7b4 | ||
|
|
29d315891f | ||
|
|
5e0b1b6267 | ||
|
|
e0d3f5d1a4 | ||
|
|
03adf9b696 | ||
|
|
51748c3b1d | ||
|
|
895b145207 | ||
|
|
d3d4b6124a | ||
|
|
5cfdd42d4b | ||
|
|
6acfd8794d | ||
|
|
90ff4682df | ||
|
|
17f000b744 | ||
|
|
90262a0460 | ||
|
|
9f369b5ed7 | ||
|
|
2ba32b6172 | ||
|
|
c740ff2f4d | ||
|
|
5e2ee3838d | ||
|
|
8f9eefa1f6 | ||
|
|
5ae32384d5 | ||
|
|
f55fde8d99 | ||
|
|
0632b4865b | ||
|
|
7914d8ac55 | ||
|
|
73709ed0a0 | ||
|
|
dfaac83527 | ||
|
|
e11f2b8cfd | ||
|
|
fa3098206d | ||
|
|
ad347d91c8 | ||
|
|
55727c2f30 | ||
|
|
c8e79991b7 | ||
|
|
a03b58d94d | ||
|
|
ed89f20836 | ||
|
|
fd8a1273ad | ||
|
|
4094d20cec | ||
|
|
585932c74c | ||
|
|
3366687e86 | ||
|
|
b749352f1e | ||
|
|
25d9972c0b | ||
|
|
5b1b6e8364 | ||
|
|
0dab5aa4c8 | ||
|
|
2ef5fa1659 | ||
|
|
17cb4cebca | ||
|
|
ac7f9b0785 | ||
|
|
d06b177508 | ||
|
|
775ded05dc | ||
|
|
cc9847580d | ||
|
|
46334c7363 | ||
|
|
1684aa1448 | ||
|
|
367cddb201 | ||
|
|
27782aca39 | ||
|
|
4e60438c66 | ||
|
|
ec719ad255 | ||
|
|
23651ad5ff | ||
|
|
300adc0bf2 | ||
|
|
c0e872b3e3 | ||
|
|
87698aa223 | ||
|
|
68e4f5e8bf | ||
|
|
8cf30f326e | ||
|
|
9af37c0d58 | ||
|
|
095c1e715c | ||
|
|
aa46e10163 | ||
|
|
5e9f60b0ea | ||
|
|
139bc7b81e | ||
|
|
3d5a46482f | ||
|
|
6d1a12673b | ||
|
|
55efefa51b | ||
|
|
1443856c34 | ||
|
|
bf35ff2bf1 | ||
|
|
7bd55402b0 | ||
|
|
1c560d073d | ||
|
|
3eec5201da | ||
|
|
02c42206ec | ||
|
|
3125ec683b | ||
|
|
829d753a88 | ||
|
|
91a6b2d7a2 | ||
|
|
636444612f | ||
|
|
a131b126f5 | ||
|
|
cb700ed590 |
@@ -0,0 +1,21 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
machine: true
|
||||
steps:
|
||||
- checkout
|
||||
#- run:
|
||||
# name : Getting docker
|
||||
# command: curl https://get.docker.com | sh
|
||||
- run:
|
||||
name: Enabling qemu
|
||||
command: docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
- run:
|
||||
name: Building arm based image.
|
||||
command: docker build -t arm-test .
|
||||
- run:
|
||||
name: Listing built images
|
||||
command: docker images
|
||||
# - run:
|
||||
# name: Running arm based image.
|
||||
# command: docker run --rm arm-test
|
||||
@@ -0,0 +1,11 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
@@ -1,2 +1,3 @@
|
||||
.DS_Store
|
||||
.vagrant
|
||||
*.swp
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
sudo: required
|
||||
|
||||
language: c
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- docker-ce
|
||||
- qemu-user-static
|
||||
|
||||
env:
|
||||
global:
|
||||
# - VERSION=${TRAVIS_TAG}
|
||||
- VERSION=${TRAVIS_BRANCH}
|
||||
- DOCKER_CLI_EXPERIMENTAL=enabled
|
||||
- QEMU_VERSION=v4.0.0
|
||||
|
||||
matrix:
|
||||
# PLATFORM = Base image architecture to be used
|
||||
# QEMU_ARCH = qemu binary to be downloaded from https://github.com/multiarch/qemu-user-static/releases
|
||||
# TAG_ARCH = Tag to be applied to the image when upload to DockerHub
|
||||
- PLATFORM=amd64 QEMU_ARCH=amd64 TAG_ARCH=amd64
|
||||
- PLATFORM=arm64 QEMU_ARCH=aarch64 TAG_ARCH=arm64
|
||||
- PLATFORM=arm QEMU_ARCH=arm TAG_ARCH=arm
|
||||
|
||||
stage: Compile
|
||||
|
||||
before_script:
|
||||
- echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json
|
||||
- sudo service docker restart
|
||||
|
||||
script:
|
||||
- docker login -u "${DOCKER_USERNAME}" -p "${DOCKER_PASSWORD}";
|
||||
- make build test
|
||||
|
||||
- if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then
|
||||
make release;
|
||||
fi
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: deploy
|
||||
env:
|
||||
- ARCHS="amd64 arm64 arm"
|
||||
script:
|
||||
- echo $NAME:$VERSION_TAG
|
||||
- echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
|
||||
- make build_multiarch
|
||||
@@ -0,0 +1,52 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at Phusion Passenger:
|
||||
|
||||
[FloorD](https://github.com/floord) (she/her), floor@phusion.nl, English / Dutch / German
|
||||
|
||||
[Scarhand](https://github.com/scarhand) (he/his), niels@phusion.nl, English / Dutch
|
||||
|
||||
The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
@@ -0,0 +1,7 @@
|
||||
Hey, thanks for wanting to contribute to baseimage-docker. :)
|
||||
|
||||
If you have a question, please use the [discussion forum](https://groups.google.com/d/forum/passenger-docker). The Github issue tracker is only for **bug reports and feature requests**.
|
||||
|
||||
If you want to develop baseimage-docker, use the Vagrantfile in the repository. It will setup an Ubuntu VM with Docker installed in it. Use the Makefile to build the Docker image.
|
||||
|
||||
All development happens on the `next` branch. The `master` branch is supposed to point to the latest stable release, because users read documentation from the `master` branch.
|
||||
+1
-36
@@ -1,36 +1 @@
|
||||
## 0.9.6 (release date: 2014-02-17)
|
||||
|
||||
* Fixed a bug in `my_init`: child processes that have been adopted during execution of init scripts are now properly reaped.
|
||||
* Much improved `my_init`:
|
||||
* It is now possible to run and watch a custom command, possibly in addition to running runit. See "Running a one-shot command in the container" in the README.
|
||||
* It is now possible to skip running startup files such as /etc/rc.local.
|
||||
* Shutdown is not much faster. It previously took a few seconds, but it is now almost instantaneous.
|
||||
* It ensures that all processes in the container are properly shut down with SIGTERM, even those that are not direct child processes of `my_init`.
|
||||
* `setuser` now also sets auxilliary groups, as well as more environment variables such as `USER` and `UID`.
|
||||
|
||||
## 0.9.5 (release date: 2014-02-06)
|
||||
|
||||
* Environment variables are now no longer reset by runit. This is achieved by running `runsvdir` directly instead of through Debian's `runsvdir-start`.
|
||||
* The insecure SSH key is now disabled by default. You have to explicitly opt-in to use it.
|
||||
|
||||
## 0.9.4 (release date: 2014-02-03)
|
||||
|
||||
* Fixed syslog-ng startup problem.
|
||||
|
||||
## 0.9.3 (release date: 2014-01-31)
|
||||
|
||||
* It looks like Docker changed their Ubuntu 12.04 base image, thereby breaking our Dockerfile. This has been fixed.
|
||||
* The init system (`/sbin/my_init`) now supports running scripts during startup. You can put startup scripts `/etc/my_init.d`. `/etc/rc.local` is also run during startup.
|
||||
* To improve security, the base image no longer contains pregenerated SSH host keys. Instead, users of the base image are encouraged to regenerate one in their Dockerfile. If the user does not do that, then random SSH host keys are generated during container boot.
|
||||
|
||||
## 0.9.2 (release date: 2013-12-11)
|
||||
|
||||
* Fixed SFTP support. Thanks Joris van de Donk!
|
||||
|
||||
## 0.9.1 (release date: 2013-11-12)
|
||||
|
||||
* Improved init process script (`/sbin/my_init`): it now handles shutdown correctly. Previously, `docker stop` would not have any effect on `my_init`, causing the whole container to be killed with SIGKILL. The new init process script gracefully shuts down all runit services, then exits.
|
||||
|
||||
## 0.9.0 (release date: 2013-11-12)
|
||||
|
||||
* Initial release
|
||||
For the Changelog, please see [Releases](https://github.com/phusion/baseimage-docker/releases) on GitHub
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2014 Phusion
|
||||
Copyright (c) 2013-2015 Phusion Holding B.V.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,28 +1,58 @@
|
||||
NAME = phusion/baseimage
|
||||
VERSION = 0.9.6
|
||||
VERSION ?= 0.11
|
||||
ifdef BASE_IMAGE
|
||||
BUILD_ARG = --build-arg BASE_IMAGE=$(BASE_IMAGE)
|
||||
ifndef NAME
|
||||
NAME = phusion/baseimage-$(subst :,-,${BASE_IMAGE})
|
||||
endif
|
||||
else
|
||||
NAME ?= phusion/baseimage
|
||||
endif
|
||||
ifdef TAG_ARCH
|
||||
# VERSION_ARG = $(VERSION)-$(subst /,-,$(subst :,-,${BASE_IMAGE}))-$(TAG_ARCH)
|
||||
VERSION_ARG = $(VERSION)-$(TAG_ARCH)
|
||||
LATEST_VERSION = latest-$(TAG_ARCH)
|
||||
else
|
||||
# VERSION_ARG = $(VERSION)-$(subst /,-,$(subst :,-,${BASE_IMAGE}))
|
||||
VERSION_ARG = $(VERSION)
|
||||
LATEST_VERSION = latest
|
||||
endif
|
||||
VERSION_ARG ?= $(VERSION)
|
||||
|
||||
.PHONY: all build test tag_latest release ssh
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
docker build -t $(NAME):$(VERSION) -rm image
|
||||
./build.sh
|
||||
docker build --no-cache -t $(NAME):$(VERSION_ARG) $(BUILD_ARG) --build-arg QEMU_ARCH=$(QEMU_ARCH) --platform $(PLATFORM) --rm image
|
||||
|
||||
build_multiarch:
|
||||
env NAME=$(NAME) VERSION=$(VERSION_ARG) ./build-multiarch.sh
|
||||
|
||||
test:
|
||||
env NAME=$(NAME) VERSION=$(VERSION) ./test/runner.sh
|
||||
env NAME=$(NAME) VERSION=$(VERSION_ARG) ./test/runner.sh
|
||||
|
||||
tag_latest:
|
||||
docker tag $(NAME):$(VERSION) $(NAME):latest
|
||||
docker tag $(NAME):$(VERSION_ARG) $(NAME):$(LATEST_VERSION)
|
||||
|
||||
release: test tag_latest
|
||||
@if ! docker images phusion/baseimage | awk '{ print $$2 }' | grep -q -F $(VERSION); then echo "$(NAME) version $(VERSION) is not yet built. Please run 'make build'"; false; fi
|
||||
tag_multiarch_latest:
|
||||
env NAME=$(NAME) VERSION=$(VERSION) TAG_LATEST=true ./build-multiarch.sh
|
||||
|
||||
release: test
|
||||
@if ! docker images $(NAME) | awk '{ print $$2 }' | grep -q -F $(VERSION_ARG); then echo "$(NAME) version $(VERSION_ARG) is not yet built. Please run 'make build'"; false; fi
|
||||
docker push $(NAME)
|
||||
@echo "*** Don't forget to create a tag. git tag rel-$(VERSION) && git push origin rel-$(VERSION)"
|
||||
@echo "*** Don't forget to create a tag by creating an official GitHub release."
|
||||
|
||||
ssh: SSH_COMMAND?=
|
||||
ssh:
|
||||
chmod 600 image/insecure_key.pub
|
||||
@ID=$$(docker ps | grep -F "$(NAME):$(VERSION)" | awk '{ print $$1 }') && \
|
||||
ID=$$(docker ps | grep -F "$(NAME):$(VERSION_ARG)" | awk '{ print $$1 }') && \
|
||||
if test "$$ID" = ""; then echo "Container is not running."; exit 1; fi && \
|
||||
IP=$$(docker inspect $$ID | grep IPAddr | sed 's/.*: "//; s/".*//') && \
|
||||
echo "SSHing into $$IP" && \
|
||||
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i image/insecure_key root@$$IP
|
||||
tools/docker-ssh $$ID ${SSH_COMMAND}
|
||||
|
||||
test_release:
|
||||
echo test_release
|
||||
env
|
||||
|
||||
test_master:
|
||||
echo test_master
|
||||
env
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
# A minimal Ubuntu base image modified for Docker-friendliness
|
||||
|
||||
Baseimage-docker is a special [Docker](http://www.docker.io) image that is configured for correct use within Docker containers. It is Ubuntu, plus modifications for Docker-friendliness. You can use it as a base for your own Docker images.
|
||||
[](https://imagelayers.io/?images=phusion/baseimage:latest 'Get your own badge on imagelayers.io')
|
||||
[](https://travis-ci.org/phusion/baseimage-docker)
|
||||
|
||||
Baseimage-docker is available for pulling from [the Docker registry](https://index.docker.io/u/phusion/baseimage/)!
|
||||
_Baseimage-docker only consumes 8.3 MB RAM and is much more powerful than Busybox or Alpine. See why below._
|
||||
|
||||
Baseimage-docker is a special [Docker](https://www.docker.com) image that is configured for correct use within Docker containers. It is Ubuntu, plus:
|
||||
|
||||
* Modifications for Docker-friendliness.
|
||||
* Administration tools that are especially useful in the context of Docker.
|
||||
* Mechanisms for easily running multiple processes, [without violating the Docker philosophy](#docker_single_process).
|
||||
|
||||
You can use it as a base for your own Docker images.
|
||||
|
||||
Baseimage-docker is available for pulling from [the Docker registry](https://registry.hub.docker.com/u/phusion/baseimage/)!
|
||||
|
||||
### What are the problems with the stock Ubuntu base image?
|
||||
|
||||
Ubuntu is not designed to be run inside docker. Its init system, Upstart, assumes that it's running on either real hardware or virtualized hardware, but not inside a Docker container. But inside a container you don't want a full system anyway, you want a minimal system. But configuring that minimal system for use within a container has many strange corner cases that are hard to get right if you are not intimately familiar with the Unix system model. This can cause a lot of strange problems.
|
||||
Ubuntu is not designed to be run inside Docker. Its init system, Upstart, assumes that it's running on either real hardware or virtualized hardware, but not inside a Docker container. But inside a container you don't want a full system; you want a minimal system. Configuring that minimal system for use within a container has many strange corner cases that are hard to get right if you are not intimately familiar with the Unix system model. This can cause a lot of strange problems.
|
||||
|
||||
Baseimage-docker gets everything right. The "Contents" section describes all the things that it modifies.
|
||||
|
||||
@@ -16,7 +27,7 @@ Baseimage-docker gets everything right. The "Contents" section describes all the
|
||||
You can configure the stock `ubuntu` image yourself from your Dockerfile, so why bother using baseimage-docker?
|
||||
|
||||
* Configuring the base system for Docker-friendliness is no easy task. As stated before, there are many corner cases. By the time that you've gotten all that right, you've reinvented baseimage-docker. Using baseimage-docker will save you from this effort.
|
||||
* It reduces the time needed to write a correct Dockerfile. You won't have to worry about the base system and can focus on your stack and your app.
|
||||
* It reduces the time needed to write a correct Dockerfile. You won't have to worry about the base system and you can focus on the stack and the app.
|
||||
* It reduces the time needed to run `docker build`, allowing you to iterate your Dockerfile more quickly.
|
||||
* It reduces download time during redeploys. Docker only needs to download the base image once: during the first deploy. On every subsequent deploys, only the changes you make on top of the base image are downloaded.
|
||||
|
||||
@@ -35,14 +46,33 @@ You can configure the stock `ubuntu` image yourself from your Dockerfile, so why
|
||||
* [What's inside the image?](#whats_inside)
|
||||
* [Overview](#whats_inside_overview)
|
||||
* [Wait, I thought Docker is about running a single process in a container?](#docker_single_process)
|
||||
* [Does Baseimage-docker advocate "fat containers" or "treating containers as VMs"?](#fat_containers)
|
||||
* [Inspecting baseimage-docker](#inspecting)
|
||||
* [Using baseimage-docker as base image](#using)
|
||||
* [Getting started](#getting_started)
|
||||
* [Adding additional daemons](#adding_additional_daemons)
|
||||
* [Running scripts during container startup](#running_startup_scripts)
|
||||
* [Running a one-shot command in the container](#oneshot)
|
||||
* [Login to the container via SSH](#login)
|
||||
* [Environment variables](#environment_variables)
|
||||
* [Centrally defining your own environment variables](#envvar_central_definition)
|
||||
* [Environment variable dumps](#envvar_dumps)
|
||||
* [Modifying environment variables](#modifying_envvars)
|
||||
* [Security](#envvar_security)
|
||||
* [System logging](#logging)
|
||||
* [Upgrading the operating system inside the container](#upgrading_os)
|
||||
* [Container administration](#container_administration)
|
||||
* [Running a one-shot command in a new container](#oneshot)
|
||||
* [Running a command in an existing, running container](#run_inside_existing_container)
|
||||
* [Login to the container via `docker exec`](#login_docker_exec)
|
||||
* [Usage](#docker_exec)
|
||||
* [Login to the container via SSH](#login_ssh)
|
||||
* [Enabling SSH](#enabling_ssh)
|
||||
* [About SSH keys](#ssh_keys)
|
||||
* [Using the insecure key for one container only](#using_the_insecure_key_for_one_container_only)
|
||||
* [Enabling the insecure key permanently](#enabling_the_insecure_key_permanently)
|
||||
* [Using your own key](#using_your_own_key)
|
||||
* [The `docker-ssh` tool](#docker_ssh)
|
||||
* [Building the image yourself](#building)
|
||||
* [Removing optional services](#removing_optional_services)
|
||||
* [Conclusion](#conclusion)
|
||||
|
||||
-----------------------------------------
|
||||
@@ -57,30 +87,47 @@ You can configure the stock `ubuntu` image yourself from your Dockerfile, so why
|
||||
|
||||
| Component | Why is it included? / Remarks |
|
||||
| ---------------- | ------------------- |
|
||||
| Ubuntu 12.04 LTS | The base system. |
|
||||
| A **correct** init process | According to the Unix process model, [the init process](https://en.wikipedia.org/wiki/Init) -- PID 1 -- inherits all [orphaned child processes](https://en.wikipedia.org/wiki/Orphan_process) and must [reap them](https://en.wikipedia.org/wiki/Wait_(system_call). Most Docker containers do not have an init process that does this correctly, and as a result their containers become filled with [zombie processes](https://en.wikipedia.org/wiki/Zombie_process) over time. <br><br>Furthermore, `docker stop` sends SIGTERM to the init process, which is then supposed to stop all services. Unfortunately most init systems don't do this correctly within Docker since they're built for hardware shutdowns instead. This causes processes to be hard killed with SIGKILL, which doesn't give them a chance to correctly deinitialize things. This can cause file corruption. <br><br>Baseimage-docker comes with an init process `/sbin/my_init` that performs both of these tasks correctly. |
|
||||
| Ubuntu 18.04 LTS | The base system. |
|
||||
| A **correct** init process | _Main article: [Docker and the PID 1 zombie reaping problem](http://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/)._ <br><br>According to the Unix process model, [the init process](https://en.wikipedia.org/wiki/Init) -- PID 1 -- inherits all [orphaned child processes](https://en.wikipedia.org/wiki/Orphan_process) and must [reap them](https://en.wikipedia.org/wiki/Wait_(system_call)). Most Docker containers do not have an init process that does this correctly. As a result, their containers become filled with [zombie processes](https://en.wikipedia.org/wiki/Zombie_process) over time. <br><br>Furthermore, `docker stop` sends SIGTERM to the init process, which stops all services. Unfortunately most init systems don't do this correctly within Docker since they're built for hardware shutdowns instead. This causes processes to be hard killed with SIGKILL, which doesn't give them a chance to correctly deinitialize things. This can cause file corruption. <br><br>Baseimage-docker comes with an init process `/sbin/my_init` that performs both of these tasks correctly. |
|
||||
| Fixes APT incompatibilities with Docker | See https://github.com/dotcloud/docker/issues/1024. |
|
||||
| syslog-ng | A syslog daemon is necessary so that many services - including the kernel itself - can correctly log to /var/log/syslog. If no syslog daemon is running, a lot of important messages are silently swallowed. <br><br>Only listens locally. |
|
||||
| ssh server | Allows you to easily login to your container to inspect or administer things. <br><br>Password and challenge-response authentication are disabled by default. Only key authentication is allowed.<br>By default, it allows a predefined key, in order to make debugging easy. You should replace this ASAP. See instructions. |
|
||||
| syslog-ng | A syslog daemon is necessary so that many services - including the kernel itself - can correctly log to /var/log/syslog. If no syslog daemon is running, a lot of important messages are silently swallowed. <br><br>Only listens locally. All syslog messages are forwarded to "docker logs".<br><br>Why syslog-ng?<br>I've had bad experience with rsyslog. I regularly run into bugs with rsyslog, and once in a while it takes my log host down by entering a 100% CPU loop in which it can't do anything. Syslog-ng seems to be much more stable. |
|
||||
| logrotate | Rotates and compresses logs on a regular basis. |
|
||||
| SSH server | Allows you to easily login to your container to [inspect or administer](#login_ssh) things. <br><br>_SSH is **disabled by default** and is only one of the methods provided by baseimage-docker for this purpose. The other method is through [docker exec](#login_docker_exec). SSH is also provided as an alternative because `docker exec` comes with several caveats._<br><br>Password and challenge-response authentication are disabled by default. Only key authentication is allowed. |
|
||||
| cron | The cron daemon must be running for cron jobs to work. |
|
||||
| [runit](http://smarden.org/runit/) | Replaces Ubuntu's Upstart. Used for service supervision and management. Much easier to use than SysV init and supports restarting daemons when they crash. Much easier to use and more lightweight than Upstart. |
|
||||
| `setuser` | A tool for running a command as another user. Easier to use than `su`, has a smaller attack vector than `sudo`, and unlike `chpst` this tool sets `$HOME` correctly. Available as `/sbin/setuser`. |
|
||||
| `install_clean` | A tool for installing `apt` packages that automatically cleans up after itself. All arguments are passed to `apt-get -y install --no-install-recommends` and after installation the apt caches are cleared. To include recommended packages, add `--install-recommends`. |
|
||||
|
||||
Baseimage-docker is very lightweight: it only consumes 6 MB of memory.
|
||||
Baseimage-docker is very lightweight: it only consumes 8.3 MB of memory.
|
||||
|
||||
<a name="docker_single_process"></a>
|
||||
### Wait, I thought Docker is about running a single process in a container?
|
||||
|
||||
Absolutely not true. Docker runs fine with multiple processes in a container. In fact, there is no technical reason why you should limit yourself to one process - it only makes things harder for you and breaks all kinds of essential system functionality, e.g. syslog.
|
||||
The Docker developers advocate the philosophy of running a single *logical service* per container. A logical service can consist of multiple OS processes.
|
||||
|
||||
Baseimage-docker *encourages* multiple processes through the use of runit.
|
||||
Baseimage-docker only advocates running multiple OS processes inside a single container. We believe this makes sense because at the very least it would solve [the PID 1 problem](http://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/) and the "syslog blackhole" problem. By running multiple processes, we solve very real Unix OS-level problems, with minimal overhead and without turning the container into multiple logical services.
|
||||
|
||||
Splitting your logical service into multiple OS processes also makes sense from a security standpoint. By running processes as different users, you can limit the impact of vulnerabilities. Baseimage-docker provides tools to encourage running processes as different users, e.g. the `setuser` tool.
|
||||
|
||||
Do we advocate running multiple *logical services* in a single container? Not necessarily, but we do not prohibit it either. While the Docker developers are very opinionated and have very rigid philosophies about how containers *should* be built, Baseimage-docker is completely unopinionated. We believe in freedom: sometimes it makes sense to run multiple services in a single container, and sometimes it doesn't. It is up to you to decide what makes sense, not the Docker developers.
|
||||
|
||||
<a name="fat_containers"></a>
|
||||
### Does Baseimage-docker advocate "fat containers" or "treating containers as VMs"?
|
||||
|
||||
There are people who think that Baseimage-docker advocates treating containers as VMs because Baseimage-docker advocates the use of multiple processes. Therefore, they also think that Baseimage-docker does not follow the Docker philosophy. Neither of these impressions are true.
|
||||
|
||||
The Docker developers advocate running a single *logical service* inside a single container. But we are not disputing that. Baseimage-docker advocates running multiple *OS processes* inside a single container, and a single logical service can consist of multiple OS processes.
|
||||
|
||||
It follows that Baseimage-docker also does not deny the Docker philosophy. In fact, many of the modifications we introduce are explicitly in line with the Docker philosophy. For example, using environment variables to pass parameters to containers is very much the "Docker way", and providing [a mechanism to easily work with environment variables](#environment_variables) in the presence of multiple processes that may run as different users.
|
||||
|
||||
<a name="inspecting"></a>
|
||||
## Inspecting baseimage-docker
|
||||
|
||||
To look around in the image, run:
|
||||
|
||||
docker run -rm -t -i phusion/baseimage bash -l
|
||||
docker run --rm -t -i phusion/baseimage:<VERSION> /sbin/my_init -- bash -l
|
||||
|
||||
where `<VERSION>` is [one of the baseimage-docker version numbers](https://github.com/phusion/baseimage-docker/blob/master/Changelog.md).
|
||||
|
||||
You don't have to download anything manually. The above command will automatically pull the baseimage-docker image from the Docker registry.
|
||||
|
||||
@@ -97,68 +144,221 @@ The image is called `phusion/baseimage`, and is available on the Docker registry
|
||||
# See https://github.com/phusion/baseimage-docker/blob/master/Changelog.md for
|
||||
# a list of version numbers.
|
||||
FROM phusion/baseimage:<VERSION>
|
||||
|
||||
# Set correct environment variables.
|
||||
ENV HOME /root
|
||||
|
||||
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
|
||||
# have to do that yourself. You may also comment out this instruction; the
|
||||
# init system will auto-generate one during boot.
|
||||
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
|
||||
|
||||
|
||||
# Use baseimage-docker's init system.
|
||||
CMD ["/sbin/my_init"]
|
||||
|
||||
|
||||
# ...put your own build instructions here...
|
||||
|
||||
|
||||
# Clean up APT when done.
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
<a name="adding_additional_daemons"></a>
|
||||
### Adding additional daemons
|
||||
|
||||
You can add additional daemons (e.g. your own app) to the image by creating runit entries. You only have to write a small shell script which runs your daemon, and runit will keep it up and running for you, restarting it when it crashes, etc.
|
||||
A daemon is a program which runs in the background of its system, such
|
||||
as a web server.
|
||||
|
||||
The shell script must be called `run`, must be executable, and is to be placed in the directory `/etc/service/<NAME>`.
|
||||
You can add additional daemons (for example, your own app) to the image
|
||||
by creating runit service directories. You only have to write a small
|
||||
shell script which runs your daemon;
|
||||
[`runsv`](http://smarden.org/runit/runsv.8.html) will start your script,
|
||||
and - by default - restart it upon its exit, after waiting one second.
|
||||
|
||||
Here's an example showing you how to a memached server runit entry can be made.
|
||||
The shell script must be called `run`, must be executable, and is to be
|
||||
placed in the directory `/etc/service/<NAME>`. `runsv` will switch to
|
||||
the directory and invoke `./run` after your container starts.
|
||||
|
||||
### In memcached.sh (make sure this file is chmod +x):
|
||||
#!/bin/sh
|
||||
# `/sbin/setuser memcache` runs the given command as the user `memcache`.
|
||||
# If you omit that part, the command will be run as root.
|
||||
exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
|
||||
**Be certain that you do not start your container using interactive mode
|
||||
(`-it`) with another command, as `runit` must be the first process to run. If you do this, your runit service directories won't be started. For instance, `docker run -it <name> bash` will bring you to bash in your container, but you'll lose all your daemons.**
|
||||
|
||||
### In Dockerfile:
|
||||
RUN mkdir /etc/service/memcached
|
||||
ADD memcached.sh /etc/service/memcached/run
|
||||
Here's an example showing you how a `runit` service directory can be
|
||||
made for a `memcached` server.
|
||||
|
||||
Note that the shell script must run the daemon **without letting it daemonize/fork it**. Usually, daemons provide a command line flag or a config file option for that.
|
||||
In `memcached.sh`, or whatever you choose to name your file (make sure
|
||||
this file is chmod +x):
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# `/sbin/setuser memcache` runs the given command as the user `memcache`.
|
||||
# If you omit that part, the command will be run as root.
|
||||
exec /sbin/setuser memcache /usr/bin/memcached >>/var/log/memcached.log 2>&1
|
||||
```
|
||||
In an accompanying `Dockerfile`:
|
||||
|
||||
```Dockerfile
|
||||
RUN mkdir /etc/service/memcached
|
||||
COPY memcached.sh /etc/service/memcached/run
|
||||
RUN chmod +x /etc/service/memcached/run
|
||||
```
|
||||
A given shell script must run **without daemonizing or forking itself**;
|
||||
this is because `runit` will start and restart your script on its own.
|
||||
Usually, daemons provide a command line flag or a config file option for
|
||||
preventing such behavior - essentially, you just want your script to run
|
||||
in the foreground, not the background.
|
||||
|
||||
<a name="running_startup_scripts"></a>
|
||||
### Running scripts during container startup
|
||||
|
||||
The baseimage-docker init system, `/sbin/my_init`, runs the following scripts during startup, in the following order:
|
||||
|
||||
* All executable scripts in `/etc/my_init.d`, if this directory exists. The scripts are run during in lexicographic order.
|
||||
* All executable scripts in `/etc/my_init.d`, if this directory exists. The scripts are run in lexicographic order.
|
||||
* The script `/etc/rc.local`, if this file exists.
|
||||
|
||||
All scripts must exit correctly, e.g. with exit code 0. If any script exits with a non-zero exit code, the booting will fail.
|
||||
|
||||
**Important note:** If you are executing the container in interactive mode (i.e. when you run a container with `-it`), rather than daemon mode, you are sending stdout directly to the terminal (`-i` interactive `-t` terminal). If you are not calling `/sbin/my_init` in your run declaration, `/sbin/my_init` will not be executed, therefore your scripts will not be called during container startup.
|
||||
|
||||
The following example shows how you can add a startup script. This script simply logs the time of boot to the file /tmp/boottime.txt.
|
||||
|
||||
### In logtime.sh (make sure this file is chmod +x):
|
||||
In `logtime.sh`:
|
||||
|
||||
#!/bin/sh
|
||||
date > /tmp/boottime.txt
|
||||
|
||||
### In Dockerfile:
|
||||
In `Dockerfile`:
|
||||
|
||||
RUN mkdir -p /etc/my_init.d
|
||||
ADD logtime.sh /etc/my_init.d/logtime.sh
|
||||
COPY logtime.sh /etc/my_init.d/logtime.sh
|
||||
RUN chmod +x /etc/my_init.d/logtime.sh
|
||||
|
||||
<a name="environment_variables"></a>
|
||||
|
||||
#### Shutting down your process
|
||||
|
||||
`/sbin/my_init` handles termination of children processes at shutdown. When it receives a SIGTERM
|
||||
it will pass the signal onto the child processes for correct shutdown. If your process is started with
|
||||
a shell script, make sure you `exec` the actual process, otherwise the shell will receive the signal
|
||||
and not your process.
|
||||
|
||||
`/sbin/my_init` will terminate processes after a 5 second timeout. This can be adjusted by setting
|
||||
environment variables:
|
||||
|
||||
# Give children processes 5 minutes to timeout
|
||||
ENV KILL_PROCESS_TIMEOUT=300
|
||||
# Give all other processes (such as those which have been forked) 5 minutes to timeout
|
||||
ENV KILL_ALL_PROCESSES_TIMEOUT=300
|
||||
|
||||
Note: Prior to 0.11.1, the default values for `KILL_PROCESS_TIMEOUT` and `KILL_ALL_PROCESSES_TIMEOUT`
|
||||
were 5 seconds. In version 0.11.1+ the default process timeout has been adjusted to 30 seconds to
|
||||
allow more time for containers to terminate gracefully. The default timeout of your container runtime
|
||||
may supersede this setting, for example Docker currently applies a [10s timeout](https://docs.docker.com/engine/reference/commandline/stop/#options)
|
||||
by default before sending SIGKILL, upon `docker stop` or receiving SIGTERM.
|
||||
|
||||
### Environment variables
|
||||
|
||||
If you use `/sbin/my_init` as the main container command, then any environment variables set with `docker run --env` or with the `ENV` command in the Dockerfile, will be picked up by `my_init`. These variables will also be passed to all child processes, including `/etc/my_init.d` startup scripts, Runit and Runit-managed services. There are however a few caveats you should be aware of:
|
||||
|
||||
* Environment variables on Unix are inherited on a per-process basis. This means that it is generally not possible for a child process to change the environment variables of other processes.
|
||||
* Because of the aforementioned point, there is no good central place for defining environment variables for all applications and services. Debian has the `/etc/environment` file but it only works in some situations.
|
||||
* Some services change environment variables for child processes. Nginx is one such example: it removes all environment variables unless you explicitly instruct it to retain them through the `env` configuration option. If you host any applications on Nginx (e.g. using the [passenger-docker](https://github.com/phusion/passenger-docker) image, or using Phusion Passenger in your own image) then they will not see the environment variables that were originally passed by Docker.
|
||||
* We ignore HOME, SHELL, USER and a bunch of other environment variables on purpose, because _not_ ignoring them will break multi-user containers. See https://github.com/phusion/baseimage-docker/pull/86 -- A workaround for setting the `HOME` environment variable looks like this: `RUN echo /root > /etc/container_environment/HOME`. See https://github.com/phusion/baseimage-docker/issues/119
|
||||
|
||||
`my_init` provides a solution for all these caveats.
|
||||
|
||||
<a name="envvar_central_definition"></a>
|
||||
#### Centrally defining your own environment variables
|
||||
|
||||
During startup, before running any [startup scripts](#running_startup_scripts), `my_init` imports environment variables from the directory `/etc/container_environment`. This directory contains files named after the environment variable names. The file contents contain the environment variable values. This directory is therefore a good place to centrally define your own environment variables, which will be inherited by all startup scripts and Runit services.
|
||||
|
||||
For example, here's how you can define an environment variable from your Dockerfile:
|
||||
|
||||
RUN echo Apachai Hopachai > /etc/container_environment/MY_NAME
|
||||
|
||||
You can verify that it works, as follows:
|
||||
|
||||
$ docker run -t -i <YOUR_NAME_IMAGE> /sbin/my_init -- bash -l
|
||||
...
|
||||
*** Running bash -l...
|
||||
# echo $MY_NAME
|
||||
Apachai Hopachai
|
||||
|
||||
**Handling newlines**
|
||||
|
||||
If you've looked carefully, you'll notice that the 'echo' command actually prints a newline. Why does $MY_NAME not contain a newline then? It's because `my_init` strips the trailing newline. If you intended on the value having a newline, you should add *another* newline, like this:
|
||||
|
||||
RUN echo -e "Apachai Hopachai\n" > /etc/container_environment/MY_NAME
|
||||
|
||||
<a name="envvar_dumps"></a>
|
||||
#### Environment variable dumps
|
||||
|
||||
While the previously mentioned mechanism is good for centrally defining environment variables, itself does not prevent services (e.g. Nginx) from changing and resetting environment variables from child processes. However, the `my_init` mechanism does make it easy for you to query what the original environment variables are.
|
||||
|
||||
During startup, right after importing environment variables from `/etc/container_environment`, `my_init` will dump all its environment variables (that is, all variables imported from `container_environment`, as well as all variables it picked up from `docker run --env`) to the following locations, in the following formats:
|
||||
|
||||
* `/etc/container_environment`
|
||||
* `/etc/container_environment.sh` - a dump of the environment variables in Bash format. You can source the file directly from a Bash shell script.
|
||||
* `/etc/container_environment.json` - a dump of the environment variables in JSON format.
|
||||
|
||||
The multiple formats make it easy for you to query the original environment variables no matter which language your scripts/apps are written in.
|
||||
|
||||
Here is an example shell session showing you how the dumps look like:
|
||||
|
||||
$ docker run -t -i \
|
||||
--env FOO=bar --env HELLO='my beautiful world' \
|
||||
phusion/baseimage:<VERSION> /sbin/my_init -- \
|
||||
bash -l
|
||||
...
|
||||
*** Running bash -l...
|
||||
# ls /etc/container_environment
|
||||
FOO HELLO HOME HOSTNAME PATH TERM container
|
||||
# cat /etc/container_environment/HELLO; echo
|
||||
my beautiful world
|
||||
# cat /etc/container_environment.json; echo
|
||||
{"TERM": "xterm", "container": "lxc", "HOSTNAME": "f45449f06950", "HOME": "/root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "FOO": "bar", "HELLO": "my beautiful world"}
|
||||
# source /etc/container_environment.sh
|
||||
# echo $HELLO
|
||||
my beautiful world
|
||||
|
||||
<a name="modifying_envvars"></a>
|
||||
#### Modifying environment variables
|
||||
|
||||
It is even possible to modify the environment variables in `my_init` (and therefore the environment variables in all child processes that are spawned after that point in time), by altering the files in `/etc/container_environment`. After each time `my_init` runs a [startup script](#running_startup_scripts), it resets its own environment variables to the state in `/etc/container_environment`, and re-dumps the new environment variables to `container_environment.sh` and `container_environment.json`.
|
||||
|
||||
But note that:
|
||||
|
||||
* modifying `container_environment.sh` and `container_environment.json` has no effect.
|
||||
* Runit services cannot modify the environment like that. `my_init` only activates changes in `/etc/container_environment` when running startup scripts.
|
||||
|
||||
<a name="envvar_security"></a>
|
||||
#### Security
|
||||
|
||||
Because environment variables can potentially contain sensitive information, `/etc/container_environment` and its Bash and JSON dumps are by default owned by root, and accessible only to the `docker_env` group (so that any user added this group will have these variables automatically loaded).
|
||||
|
||||
If you are sure that your environment variables don't contain sensitive data, then you can also relax the permissions on that directory and those files by making them world-readable:
|
||||
|
||||
RUN chmod 755 /etc/container_environment
|
||||
RUN chmod 644 /etc/container_environment.sh /etc/container_environment.json
|
||||
|
||||
<a name="logging"></a>
|
||||
### System logging
|
||||
|
||||
Baseimage-docker uses syslog-ng to provide a syslog facility to the container. Syslog-ng is not managed as an runit service (see below). Syslog messages are forwarded to the console.
|
||||
|
||||
#### Log startup/shutdown sequence
|
||||
In order to ensure that all application log messages are captured by syslog-ng, syslog-ng is started separately before the runit supervisor process, and shutdown after runit exits. This uses the [startup script facility](#running_startup_scripts) provided by this image. This avoids a race condition which would exist if syslog-ng were managed as an runit service, where runit kills syslog-ng in parallel with the container's other services, causing log messages to be dropped during a graceful shutdown if syslog-ng exits while logs are still being produced by other services.
|
||||
|
||||
<a name="upgrading_os"></a>
|
||||
### Upgrading the operating system inside the container
|
||||
|
||||
Baseimage-docker images contain an Ubuntu operating system (see OS version at [Overview](#overview)). You may want to update this OS from time to time, for example to pull in the latest security updates. OpenSSL is a notorious example. Vulnerabilities are discovered in OpenSSL on a regular basis, so you should keep OpenSSL up-to-date as much as you can.
|
||||
|
||||
While we release Baseimage-docker images with the latest OS updates from time to time, you do not have to rely on us. You can update the OS inside Baseimage-docker images yourself, and it is recommended that you do this instead of waiting for us.
|
||||
|
||||
To upgrade the OS in the image, run this in your Dockerfile:
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y -o Dpkg::Options::="--force-confold"
|
||||
|
||||
<a name="container_administration"></a>
|
||||
## Container administration
|
||||
|
||||
One of the ideas behind Docker is that containers should be stateless, easily restartable, and behave like a black box. However, you may occasionally encounter situations where you want to login to a container, or to run a command inside a container, for development, inspection and debugging purposes. This section describes how you can administer the container for those purposes.
|
||||
|
||||
<a name="oneshot"></a>
|
||||
### Running a one-shot command in the container
|
||||
### Running a one-shot command in a new container
|
||||
|
||||
Normally, when you want to run a single command in a container, and exit immediately after the command, you invoke Docker like this:
|
||||
_**Note:** This section describes how to run a command insider a -new- container. To run a command inside an existing running container, see [Running a command in an existing, running container](#run_inside_existing_container)._
|
||||
|
||||
Normally, when you want to create a new container in order to run a single command inside it, and immediately exit after the command exits, you invoke Docker like this:
|
||||
|
||||
docker run YOUR_IMAGE COMMAND ARGUMENTS...
|
||||
|
||||
@@ -178,11 +378,6 @@ This will perform the following:
|
||||
For example:
|
||||
|
||||
$ docker run phusion/baseimage:<VERSION> /sbin/my_init -- ls
|
||||
*** Running /etc/my_init.d/00_regen_ssh_host_keys.sh...
|
||||
No SSH host key available. Generating one...
|
||||
Creating SSH2 RSA key; this may take some time ...
|
||||
Creating SSH2 DSA key; this may take some time ...
|
||||
Creating SSH2 ECDSA key; this may take some time ...
|
||||
*** Running /etc/rc.local...
|
||||
*** Booting runit daemon...
|
||||
*** Runit started as PID 80
|
||||
@@ -199,23 +394,142 @@ The following example runs `ls` without running the startup files and with less
|
||||
$ docker run phusion/baseimage:<VERSION> /sbin/my_init --skip-startup-files --quiet -- ls
|
||||
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
|
||||
|
||||
<a name="login"></a>
|
||||
### Login to the container via SSH
|
||||
<a name="run_inside_existing_container"></a>
|
||||
### Running a command in an existing, running container
|
||||
|
||||
You can use SSH to login to any container that is based on baseimage-docker.
|
||||
There are two ways to run a command inside an existing, running container.
|
||||
|
||||
The first thing that you need to do is to ensure that you have the right SSH keys installed inside the container. By default, no keys are installed, so you can't login. For convenience reasons, we provide [a pregenerated, insecure key](https://github.com/phusion/baseimage-docker/blob/master/image/insecure_key) that you easily enable. However, please be aware that using this key is for convenience only. It does not provide any insecurity because this key (both the public and the private side) are publicly available. In production environments, you should use your own keys.
|
||||
* Through the `docker exec` tool. This is builtin Docker tool, available since Docker 1.4. Internally, it uses Linux kernel system calls in order to execute a command within the context of a container. Learn more in [Login to the container, or running a command inside it, via `docker exec`](#login_docker_exec).
|
||||
* Through SSH. This approach requires running an SSH daemon inside the container, and requires you to setup SSH keys. Learn more in [Login to the container, or running a command inside it, via SSH](#login_ssh).
|
||||
|
||||
Edit your Dockerfile to install an SSH key:
|
||||
Both way have their own pros and cons, which you can learn in their respective subsections.
|
||||
|
||||
<a name="login_docker_exec"></a>
|
||||
### Login to the container, or running a command inside it, via `docker exec`
|
||||
|
||||
You can use the `docker exec` tool on the Docker host OS to login to any container that is based on baseimage-docker. You can also use it to run a command inside a running container. `docker exec` works by using Linux kernel system calls.
|
||||
|
||||
Here's how it compares to [using SSH to login to the container or to run a command inside it](#login_ssh):
|
||||
|
||||
* Pros
|
||||
* Does not require running an SSH daemon inside the container.
|
||||
* Does not require setting up SSH keys.
|
||||
* Works on any container, even containers not based on baseimage-docker.
|
||||
* Cons
|
||||
* If the `docker exec` process on the host is terminated by a signal (e.g. with the `kill` command or even with Ctrl-C), then the command that is executed by `docker exec` is *not* killed and cleaned up. You will either have to do that manually, or you have to run `docker exec` with `-t -i`.
|
||||
* Requires privileges on the Docker host to be able to access the Docker daemon. Note that anybody who can access the Docker daemon effectively has root access.
|
||||
* Not possible to allow users to login to the container without also letting them login to the Docker host.
|
||||
|
||||
<a name="docker_exec_usage"></a>
|
||||
#### Usage
|
||||
|
||||
Start a container:
|
||||
|
||||
docker run YOUR_IMAGE
|
||||
|
||||
Find out the ID of the container that you just ran:
|
||||
|
||||
docker ps
|
||||
|
||||
Now that you have the ID, you can use `docker exec` to run arbitrary commands in the container. For example, to run `echo hello world`:
|
||||
|
||||
docker exec YOUR-CONTAINER-ID echo hello world
|
||||
|
||||
To open a bash session inside the container, you must pass `-t -i` so that a terminal is available:
|
||||
|
||||
docker exec -t -i YOUR-CONTAINER-ID bash -l
|
||||
|
||||
<a name="login_ssh"></a>
|
||||
### Login to the container, or running a command inside it, via SSH
|
||||
|
||||
You can use SSH to login to any container that is based on baseimage-docker. You can also use it to run a command inside a running container.
|
||||
|
||||
Here's how it compares to [using `docker exec` to login to the container or to run a command inside it](#login_docker_exec):
|
||||
|
||||
* Pros
|
||||
* Does not require root privileges on the Docker host.
|
||||
* Allows you to let users login to the container, without letting them login to the Docker host. However, this is not enabled by default because baseimage-docker does not expose the SSH server to the public Internet by default.
|
||||
* Cons
|
||||
* Requires setting up SSH keys. However, baseimage-docker makes this easy for many cases through a pregenerated, insecure key. Read on to learn more.
|
||||
|
||||
<a name="enabling_ssh"></a>
|
||||
#### Enabling SSH
|
||||
|
||||
Baseimage-docker disables the SSH server by default. Add the following to your Dockerfile to enable it:
|
||||
|
||||
RUN rm -f /etc/service/sshd/down
|
||||
|
||||
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
|
||||
# have to do that yourself. You may also comment out this instruction; the
|
||||
# init system will auto-generate one during boot.
|
||||
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
|
||||
|
||||
Alternatively, to enable sshd only for a single instance of your container, create a folder with a [startup script](#running_startup_scripts). The contents of that should be
|
||||
|
||||
### In myfolder/enable_ssh.sh (make sure this file is chmod +x):
|
||||
#!/bin/sh
|
||||
rm -f /etc/service/sshd/down
|
||||
ssh-keygen -P "" -t dsa -f /etc/ssh/ssh_host_dsa_key
|
||||
|
||||
Then, you can start your container with
|
||||
|
||||
docker run -d -v `pwd`/myfolder:/etc/my_init.d my/dockerimage
|
||||
|
||||
This will initialize sshd on container boot. You can then access it with the insecure key as below, or using the methods to add a secure key. Further, you can publish the port to your machine with -p 2222:22 allowing you to ssh to 127.0.0.1:2222 instead of looking up the ip address of the container.
|
||||
|
||||
<a name="ssh_keys"></a>
|
||||
#### About SSH keys
|
||||
|
||||
First, you must ensure that you have the right SSH keys installed inside the container. By default, no keys are installed, so nobody can login. For convenience reasons, we provide [a pregenerated, insecure key](https://github.com/phusion/baseimage-docker/blob/master/image/services/sshd/keys/insecure_key) [(PuTTY format)](https://github.com/phusion/baseimage-docker/blob/master/image/services/sshd/keys/insecure_key.ppk) that you can easily enable. However, please be aware that using this key is for convenience only. It does not provide any security because this key (both the public and the private side) is publicly available. **In production environments, you should use your own keys**.
|
||||
|
||||
<a name="using_the_insecure_key_for_one_container_only"></a>
|
||||
#### Using the insecure key for one container only
|
||||
|
||||
You can temporarily enable the insecure key for one container only. This means that the insecure key is installed at container boot. If you `docker stop` and `docker start` the container, the insecure key will still be there, but if you use `docker run` to start a new container then that container will not contain the insecure key.
|
||||
|
||||
Start a container with `--enable-insecure-key`:
|
||||
|
||||
docker run YOUR_IMAGE /sbin/my_init --enable-insecure-key
|
||||
|
||||
Find out the ID of the container that you just ran:
|
||||
|
||||
docker ps
|
||||
|
||||
Once you have the ID, look for its IP address with:
|
||||
|
||||
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
|
||||
|
||||
Now that you have the IP address, you can use SSH to login to the container, or to execute a command inside it:
|
||||
|
||||
# Download the insecure private key
|
||||
curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/services/sshd/keys/insecure_key
|
||||
chmod 600 insecure_key
|
||||
|
||||
# Login to the container
|
||||
ssh -i insecure_key root@<IP address>
|
||||
|
||||
# Running a command inside the container
|
||||
ssh -i insecure_key root@<IP address> echo hello world
|
||||
|
||||
<a name="enabling_the_insecure_key_permanently"></a>
|
||||
#### Enabling the insecure key permanently
|
||||
|
||||
It is also possible to enable the insecure key in the image permanently. This is not generally recommended, but is suitable for e.g. temporary development or demo environments where security does not matter.
|
||||
|
||||
Edit your Dockerfile to install the insecure key permanently:
|
||||
|
||||
RUN /usr/sbin/enable_insecure_key
|
||||
|
||||
Instructions for logging into the container is the same as in section [Using the insecure key for one container only](#using_the_insecure_key_for_one_container_only).
|
||||
|
||||
<a name="using_your_own_key"></a>
|
||||
#### Using your own key
|
||||
|
||||
Edit your Dockerfile to install an SSH public key:
|
||||
|
||||
## Install an SSH of your choice.
|
||||
ADD your_key /tmp/your_key
|
||||
RUN cat /tmp/your_key >> /root/.ssh/authorized_keys && rm -f /tmp/your_key
|
||||
|
||||
## -OR-
|
||||
|
||||
## Uncomment this to enable the insecure key.
|
||||
# RUN /usr/sbin/enable_insecure_key
|
||||
COPY your_key.pub /tmp/your_key.pub
|
||||
RUN cat /tmp/your_key.pub >> /root/.ssh/authorized_keys && rm -f /tmp/your_key.pub
|
||||
|
||||
Then rebuild your image. Once you have that, start a container based on that image:
|
||||
|
||||
@@ -227,19 +541,37 @@ Find out the ID of the container that you just ran:
|
||||
|
||||
Once you have the ID, look for its IP address with:
|
||||
|
||||
docker inspect <ID> | grep IPAddress
|
||||
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
|
||||
|
||||
Now SSH into the container as follows:
|
||||
Now that you have the IP address, you can use SSH to login to the container, or to execute a command inside it:
|
||||
|
||||
# Login to the container
|
||||
ssh -i /path-to/your_key root@<IP address>
|
||||
|
||||
# -OR-
|
||||
# Running a command inside the container
|
||||
ssh -i /path-to/your_key root@<IP address> echo hello world
|
||||
|
||||
<a name="docker_ssh"></a>
|
||||
#### The `docker-ssh` tool
|
||||
|
||||
Looking up the IP of a container and running an SSH command quickly becomes tedious. Luckily, we provide the `docker-ssh` tool which automates this process. This tool is to be run on the *Docker host*, not inside a Docker container.
|
||||
|
||||
First, install the tool on the Docker host:
|
||||
|
||||
curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \
|
||||
tar xzf master.tar.gz && \
|
||||
sudo ./baseimage-docker-master/install-tools.sh
|
||||
|
||||
Then run the tool as follows to login to a container using SSH:
|
||||
|
||||
docker-ssh YOUR-CONTAINER-ID
|
||||
|
||||
You can lookup `YOUR-CONTAINER-ID` by running `docker ps`.
|
||||
|
||||
By default, `docker-ssh` will open a Bash session. You can also tell it to run a command, and then exit:
|
||||
|
||||
docker-ssh YOUR-CONTAINER-ID echo hello world
|
||||
|
||||
# If you're using the insecure key, download it and SSH
|
||||
# into the container using that key.
|
||||
curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/insecure_key
|
||||
chmod 700 insecure_key
|
||||
ssh -i insecure_key root@<IP address>
|
||||
|
||||
<a name="building"></a>
|
||||
## Building the image yourself
|
||||
@@ -265,13 +597,48 @@ If you want to call the resulting image something else, pass the NAME variable,
|
||||
|
||||
make build NAME=joe/baseimage
|
||||
|
||||
You can also change the `ubuntu` base-image to `debian` as these distributions are quite similar.
|
||||
|
||||
make build BASE_IMAGE=debian:stretch
|
||||
|
||||
The image will be: `phusion/baseimage-debian-stretch`. Use the `NAME` variable in combination with the `BASE_IMAGE` one to call it `joe/stretch`.
|
||||
|
||||
make build BASE_IMAGE=debian:stretch NAME=joe/stretch
|
||||
|
||||
To verify that the various services are started, when the image is run as a container, add `test` to the end of your make invocations, e.g.:
|
||||
|
||||
make build BASE_IMAGE=debian:stretch NAME=joe/stretch test
|
||||
|
||||
|
||||
<a name="removing_optional_services"></a>
|
||||
### Removing optional services
|
||||
|
||||
The default baseimage-docker installs `syslog-ng`, `cron` and `sshd` services during the build process.
|
||||
|
||||
In case you don't need one or more of these services in your image, you can disable its installation through the `image/buildconfig` that is sourced within `image/system_services.sh`. Do this at build time by passing a variable in with `--build-arg` as in `docker build --build-arg DISABLE_SYSLOG=1 image/`, or you may set the variable in `image/Dockerfile` with an ENV setting above the RUN directive.
|
||||
|
||||
These represent build-time configuration, so setting them in the shell env at build-time [will not have any effect](https://github.com/phusion/baseimage-docker/issues/459#issuecomment-439177442). Setting them in child images' Dockerfiles will also not have any effect.)
|
||||
|
||||
You can also set them directly as shown in the following example, to prevent `sshd` from being installed into your image, set `1` to the `DISABLE_SSH` variable in the `./image/buildconfig` file.
|
||||
|
||||
### In ./image/buildconfig
|
||||
# ...
|
||||
# Default services
|
||||
# Set 1 to the service you want to disable
|
||||
export DISABLE_SYSLOG=0
|
||||
export DISABLE_SSH=1
|
||||
export DISABLE_CRON=0
|
||||
|
||||
Then you can proceed with `make build` command.
|
||||
|
||||
<a name="conclusion"></a>
|
||||
## Conclusion
|
||||
|
||||
* Using baseimage-docker? [Tweet about us](https://twitter.com/share) or [follow us on Twitter](https://twitter.com/phusion_nl).
|
||||
* Having problems? Want to participate in development? Please post a message at [the discussion forum](https://groups.google.com/d/forum/passenger-docker).
|
||||
* Looking for a more complete base image, one that is ideal for Ruby, Python, Node.js and Meteor web apps? Take a look at [passenger-docker](https://github.com/phusion/passenger-docker).
|
||||
* Need a helping hand? Phusion also offers [consulting](https://www.phusion.nl/consultancy) on a wide range of topics, including Web Development, UI/UX Research & Design, Technology Migration and Auditing.
|
||||
|
||||
[<img src="http://www.phusion.nl/assets/logo.png">](http://www.phusion.nl/)
|
||||
[<img src="https://www.phusion.nl/images/mark_logotype.svg">](https://www.phusion.nl/)
|
||||
|
||||
Please enjoy baseimage-docker, a product by [Phusion](http://www.phusion.nl/). :-)
|
||||
|
||||
Vendored
+39
-16
@@ -1,31 +1,54 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
ROOT = File.dirname(File.expand_path(__FILE__))
|
||||
ROOT = File.dirname(File.absolute_path(__FILE__))
|
||||
|
||||
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
VAGRANTFILE_API_VERSION = '2'
|
||||
|
||||
# Default env properties which can be overridden
|
||||
# Example overrides:
|
||||
# echo "ENV['PASSENGER_DOCKER_PATH'] ||= '../../phusion/passenger-docker' " >> ~/.vagrant.d/Vagrantfile
|
||||
# echo "ENV['BASE_BOX_URL'] ||= 'd\:/dev/vm/vagrant/boxes/phusion/'" >> ~/.vagrant.d/Vagrantfile
|
||||
BASE_BOX_URL = ENV['BASE_BOX_URL'] || 'https://oss-binaries.phusionpassenger.com/vagrant/boxes/latest/'
|
||||
VAGRANT_BOX_URL = ENV['VAGRANT_BOX_URL'] || BASE_BOX_URL + 'ubuntu-14.04-amd64-vbox.box'
|
||||
VMWARE_BOX_URL = ENV['VMWARE_BOX_URL'] || BASE_BOX_URL + 'ubuntu-14.04-amd64-vmwarefusion.box'
|
||||
BASEIMAGE_PATH = ENV['BASEIMAGE_PATH' ] || '.'
|
||||
PASSENGER_DOCKER_PATH = ENV['PASSENGER_PATH' ] || '../passenger-docker'
|
||||
DOCKERIZER_PATH = ENV['DOCKERIZER_PATH'] || '../dockerizer'
|
||||
|
||||
$script = <<SCRIPT
|
||||
wget -q -O - https://get.docker.io/gpg | apt-key add -
|
||||
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
|
||||
apt-get update -qq
|
||||
apt-get install -q -y --force-yes lxc-docker
|
||||
usermod -a -G docker vagrant
|
||||
docker version
|
||||
su - vagrant -c 'echo alias d=docker >> ~/.bash_aliases'
|
||||
SCRIPT
|
||||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
config.vm.box = "phusion-open-ubuntu-12.04-amd64"
|
||||
config.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/ubuntu-12.04.3-amd64-vbox.box"
|
||||
config.vm.box = 'phusion-open-ubuntu-14.04-amd64'
|
||||
config.vm.box_url = VAGRANT_BOX_URL
|
||||
config.ssh.forward_agent = true
|
||||
if File.directory?("#{ROOT}/../passenger-docker")
|
||||
config.vm.synced_folder File.expand_path("#{ROOT}/../passenger-docker"),
|
||||
"/vagrant/passenger-docker"
|
||||
passenger_docker_path = File.absolute_path(PASSENGER_DOCKER_PATH, ROOT)
|
||||
if File.directory?(passenger_docker_path)
|
||||
config.vm.synced_folder passenger_docker_path, '/vagrant/passenger-docker'
|
||||
end
|
||||
baseimage_path = File.absolute_path(BASEIMAGE_PATH, ROOT)
|
||||
if File.directory?(baseimage_path)
|
||||
config.vm.synced_folder baseimage_path, "/vagrant/baseimage-docker"
|
||||
end
|
||||
dockerizer_path = File.absolute_path(DOCKERIZER_PATH, ROOT)
|
||||
if File.directory?(dockerizer_path)
|
||||
config.vm.synced_folder dockerizer_path, '/vagrant/dockerizer'
|
||||
end
|
||||
|
||||
config.vm.provider :vmware_fusion do |f, override|
|
||||
override.vm.box_url = "https://oss-binaries.phusionpassenger.com/vagrant/boxes/ubuntu-12.04.3-amd64-vmwarefusion.box"
|
||||
f.vmx["displayName"] = "baseimage-docker"
|
||||
override.vm.box_url = VMWARE_BOX_URL
|
||||
f.vmx['displayName'] = 'baseimage-docker'
|
||||
end
|
||||
|
||||
if Dir.glob("#{File.dirname(__FILE__)}/.vagrant/machines/default/*/id").empty?
|
||||
# Add lxc-docker package
|
||||
pkg_cmd = "wget -q -O - https://get.docker.io/gpg | apt-key add -;" \
|
||||
"echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list;" \
|
||||
"apt-get update -qq; apt-get install -q -y --force-yes lxc-docker; "
|
||||
# Add vagrant user to the docker group
|
||||
pkg_cmd << "usermod -a -G docker vagrant; "
|
||||
config.vm.provision :shell, :inline => pkg_cmd
|
||||
config.vm.provision :shell, :inline => $script
|
||||
end
|
||||
end
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
for arch in $ARCHS; do
|
||||
docker pull $NAME:$VERSION-${arch}
|
||||
|
||||
if [[ $TAG_LATEST != 'true' ]]; then
|
||||
docker manifest create --amend $NAME:$VERSION $NAME:$VERSION-${arch}
|
||||
docker manifest annotate $NAME:$VERSION $NAME:$VERSION-${arch} --arch ${arch}
|
||||
else
|
||||
docker manifest create --amend $NAME:latest $NAME:$VERSION-${arch}
|
||||
docker manifest annotate $NAME:latest $NAME:$VERSION-${arch} --arch ${arch}
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Push manifests"
|
||||
if [[ $TAG_LATEST != 'true' ]]; then
|
||||
docker manifest push $NAME:$VERSION
|
||||
else
|
||||
docker manifest push $NAME:latest
|
||||
fi
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# # Prepare qemu
|
||||
# if [ '$QEMU_ARCH' != 'amd64' ]; then
|
||||
# # docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
# fi
|
||||
|
||||
# Get qemu package
|
||||
echo "Getting qemu package for $QEMU_ARCH"
|
||||
|
||||
# Fake qemu for amd64 builds to avoid breaking COPY in Dockerfile
|
||||
if [ $QEMU_ARCH == 'amd64' ]; then
|
||||
touch x86_64_qemu-"$QEMU_ARCH"-static.tar.gz
|
||||
mv x86_64_qemu-${QEMU_ARCH}-static.tar.gz image
|
||||
else
|
||||
curl -L -o x86_64_qemu-"$QEMU_ARCH"-static.tar.gz https://github.com/multiarch/qemu-user-static/releases/download/"$QEMU_VERSION"/x86_64_qemu-"$QEMU_ARCH"-static.tar.gz
|
||||
mv x86_64_qemu-${QEMU_ARCH}-static.tar.gz image
|
||||
fi
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
if [[ ! -e /etc/ssh/ssh_host_rsa_key ]]; then
|
||||
echo "No SSH host key available. Generating one..."
|
||||
dpkg-reconfigure openssh-server
|
||||
fi
|
||||
+16
-10
@@ -1,14 +1,20 @@
|
||||
FROM ubuntu:12.04
|
||||
MAINTAINER Phusion <info@phusion.nl>
|
||||
ARG BASE_IMAGE=ubuntu:18.04
|
||||
FROM $BASE_IMAGE
|
||||
MAINTAINER Iwan <iwanpub.phusion_fr@mg.familleclement.space>
|
||||
|
||||
ENV HOME /root
|
||||
RUN mkdir /build
|
||||
ADD . /build
|
||||
ARG QEMU_ARCH
|
||||
ADD x86_64_qemu-${QEMU_ARCH}-static.tar.gz /usr/bin
|
||||
|
||||
RUN /build/prepare.sh && \
|
||||
/build/system_services.sh && \
|
||||
/build/utilities.sh && \
|
||||
/build/cleanup.sh
|
||||
COPY . /bd_build
|
||||
|
||||
RUN /bd_build/prepare.sh && \
|
||||
/bd_build/system_services.sh && \
|
||||
/bd_build/utilities.sh && \
|
||||
/bd_build/cleanup.sh
|
||||
|
||||
ENV DEBIAN_FRONTEND="teletype" \
|
||||
LANG="fr_FR.UTF-8" \
|
||||
LANGUAGE="fr_FR:fr" \
|
||||
LC_ALL="fr_FR.UTF-8"
|
||||
|
||||
CMD ["/sbin/my_init"]
|
||||
EXPOSE 22 80 443
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash -e
|
||||
# Apt installer helper for Docker images
|
||||
|
||||
ARGS="$*"
|
||||
NO_RECOMMENDS="--no-install-recommends"
|
||||
RECOMMENDS="--install-recommends"
|
||||
if [[ $ARGS =~ "$RECOMMENDS" ]]; then
|
||||
NO_RECOMMENDS=""
|
||||
ARGS=$(sed "s/$RECOMMENDS//g" <<<"$ARGS")
|
||||
fi
|
||||
|
||||
echo "Installing $ARGS"
|
||||
|
||||
apt-get -q update && apt-get -qy install $NO_RECOMMENDS $ARGS \
|
||||
&& apt-get -qy autoremove \
|
||||
&& apt-get clean \
|
||||
&& rm -r /var/lib/apt/lists/*
|
||||
Executable
+420
@@ -0,0 +1,420 @@
|
||||
#!/usr/bin/python3 -u
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import signal
|
||||
import stat
|
||||
import sys
|
||||
import time
|
||||
|
||||
ENV_INIT_DIRECTORY = os.environ.get('ENV_INIT_DIRECTORY', '/etc/my_init.d')
|
||||
|
||||
KILL_PROCESS_TIMEOUT = int(os.environ.get('KILL_PROCESS_TIMEOUT', 30))
|
||||
KILL_ALL_PROCESSES_TIMEOUT = int(os.environ.get('KILL_ALL_PROCESSES_TIMEOUT', 30))
|
||||
|
||||
LOG_LEVEL_ERROR = 1
|
||||
LOG_LEVEL_WARN = 1
|
||||
LOG_LEVEL_INFO = 2
|
||||
LOG_LEVEL_DEBUG = 3
|
||||
|
||||
SHENV_NAME_WHITELIST_REGEX = re.compile('\W')
|
||||
|
||||
log_level = None
|
||||
|
||||
terminated_child_processes = {}
|
||||
|
||||
_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search
|
||||
|
||||
|
||||
class AlarmException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def error(message):
|
||||
if log_level >= LOG_LEVEL_ERROR:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def warn(message):
|
||||
if log_level >= LOG_LEVEL_WARN:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def info(message):
|
||||
if log_level >= LOG_LEVEL_INFO:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def debug(message):
|
||||
if log_level >= LOG_LEVEL_DEBUG:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def ignore_signals_and_raise_keyboard_interrupt(signame):
|
||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
raise KeyboardInterrupt(signame)
|
||||
|
||||
|
||||
def raise_alarm_exception():
|
||||
raise AlarmException('Alarm')
|
||||
|
||||
|
||||
def listdir(path):
|
||||
try:
|
||||
result = os.stat(path)
|
||||
except OSError:
|
||||
return []
|
||||
if stat.S_ISDIR(result.st_mode):
|
||||
return sorted(os.listdir(path))
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def is_exe(path):
|
||||
try:
|
||||
return os.path.isfile(path) and os.access(path, os.X_OK)
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def import_envvars(clear_existing_environment=True, override_existing_environment=True):
|
||||
if not os.path.exists("/etc/container_environment"):
|
||||
return
|
||||
new_env = {}
|
||||
for envfile in listdir("/etc/container_environment"):
|
||||
name = os.path.basename(envfile)
|
||||
with open("/etc/container_environment/" + envfile, "r") as f:
|
||||
# Text files often end with a trailing newline, which we
|
||||
# don't want to include in the env variable value. See
|
||||
# https://github.com/phusion/baseimage-docker/pull/49
|
||||
value = re.sub('\n\Z', '', f.read())
|
||||
new_env[name] = value
|
||||
if clear_existing_environment:
|
||||
os.environ.clear()
|
||||
for name, value in new_env.items():
|
||||
if override_existing_environment or name not in os.environ:
|
||||
os.environ[name] = value
|
||||
|
||||
|
||||
def export_envvars(to_dir=True):
|
||||
if not os.path.exists("/etc/container_environment"):
|
||||
return
|
||||
shell_dump = ""
|
||||
for name, value in os.environ.items():
|
||||
if name in ['HOME', 'USER', 'GROUP', 'UID', 'GID', 'SHELL']:
|
||||
continue
|
||||
if to_dir:
|
||||
with open("/etc/container_environment/" + name, "w") as f:
|
||||
f.write(value)
|
||||
shell_dump += "export " + sanitize_shenvname(name) + "=" + shquote(value) + "\n"
|
||||
with open("/etc/container_environment.sh", "w") as f:
|
||||
f.write(shell_dump)
|
||||
with open("/etc/container_environment.json", "w") as f:
|
||||
f.write(json.dumps(dict(os.environ)))
|
||||
|
||||
|
||||
def shquote(s):
|
||||
"""Return a shell-escaped version of the string *s*."""
|
||||
if not s:
|
||||
return "''"
|
||||
if _find_unsafe(s) is None:
|
||||
return s
|
||||
|
||||
# use single quotes, and put single quotes into double quotes
|
||||
# the string $'b is then quoted as '$'"'"'b'
|
||||
return "'" + s.replace("'", "'\"'\"'") + "'"
|
||||
|
||||
|
||||
def sanitize_shenvname(s):
|
||||
"""Return string with [0-9a-zA-Z_] characters"""
|
||||
return re.sub(SHENV_NAME_WHITELIST_REGEX, "_", s)
|
||||
|
||||
|
||||
# Waits for the child process with the given PID, while at the same time
|
||||
# reaping any other child processes that have exited (e.g. adopted child
|
||||
# processes that have terminated).
|
||||
|
||||
def waitpid_reap_other_children(pid):
|
||||
global terminated_child_processes
|
||||
|
||||
status = terminated_child_processes.get(pid)
|
||||
if status:
|
||||
# A previous call to waitpid_reap_other_children(),
|
||||
# with an argument not equal to the current argument,
|
||||
# already waited for this process. Return the status
|
||||
# that was obtained back then.
|
||||
del terminated_child_processes[pid]
|
||||
return status
|
||||
|
||||
done = False
|
||||
status = None
|
||||
while not done:
|
||||
try:
|
||||
# https://github.com/phusion/baseimage-docker/issues/151#issuecomment-92660569
|
||||
this_pid, status = os.waitpid(pid, os.WNOHANG)
|
||||
if this_pid == 0:
|
||||
this_pid, status = os.waitpid(-1, 0)
|
||||
if this_pid == pid:
|
||||
done = True
|
||||
else:
|
||||
# Save status for later.
|
||||
terminated_child_processes[this_pid] = status
|
||||
except OSError as e:
|
||||
if e.errno == errno.ECHILD or e.errno == errno.ESRCH:
|
||||
return None
|
||||
else:
|
||||
raise
|
||||
return status
|
||||
|
||||
|
||||
def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_TIMEOUT):
|
||||
info("Shutting down %s (PID %d)..." % (name, pid))
|
||||
try:
|
||||
os.kill(pid, signo)
|
||||
except OSError:
|
||||
pass
|
||||
signal.alarm(time_limit)
|
||||
try:
|
||||
try:
|
||||
waitpid_reap_other_children(pid)
|
||||
except OSError:
|
||||
pass
|
||||
except AlarmException:
|
||||
warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid))
|
||||
try:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
waitpid_reap_other_children(pid)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
|
||||
def run_command_killable(*argv):
|
||||
filename = argv[0]
|
||||
status = None
|
||||
pid = os.spawnvp(os.P_NOWAIT, filename, argv)
|
||||
try:
|
||||
status = waitpid_reap_other_children(pid)
|
||||
except BaseException:
|
||||
warn("An error occurred. Aborting.")
|
||||
stop_child_process(filename, pid)
|
||||
raise
|
||||
if status != 0:
|
||||
if status is None:
|
||||
error("%s exited with unknown status\n" % filename)
|
||||
else:
|
||||
error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status)))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def run_command_killable_and_import_envvars(*argv):
|
||||
run_command_killable(*argv)
|
||||
import_envvars()
|
||||
export_envvars(False)
|
||||
|
||||
|
||||
def kill_all_processes(time_limit):
|
||||
info("Killing all processes...")
|
||||
try:
|
||||
os.kill(-1, signal.SIGTERM)
|
||||
except OSError:
|
||||
pass
|
||||
signal.alarm(time_limit)
|
||||
try:
|
||||
# Wait until no more child processes exist.
|
||||
done = False
|
||||
while not done:
|
||||
try:
|
||||
os.waitpid(-1, 0)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ECHILD:
|
||||
done = True
|
||||
else:
|
||||
raise
|
||||
except AlarmException:
|
||||
warn("Not all processes have exited in time. Forcing them to exit.")
|
||||
try:
|
||||
os.kill(-1, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
|
||||
def run_startup_files():
|
||||
# Run ENV_INIT_DIRECTORY/*
|
||||
for name in listdir(ENV_INIT_DIRECTORY):
|
||||
filename = os.path.join(ENV_INIT_DIRECTORY, name)
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable_and_import_envvars(filename)
|
||||
|
||||
# Run /etc/rc.local.
|
||||
if is_exe("/etc/rc.local"):
|
||||
info("Running /etc/rc.local...")
|
||||
run_command_killable_and_import_envvars("/etc/rc.local")
|
||||
|
||||
|
||||
def run_pre_shutdown_scripts():
|
||||
debug("Running pre-shutdown scripts...")
|
||||
|
||||
# Run /etc/my_init.pre_shutdown.d/*
|
||||
for name in listdir("/etc/my_init.pre_shutdown.d"):
|
||||
filename = "/etc/my_init.pre_shutdown.d/" + name
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable(filename)
|
||||
|
||||
|
||||
def run_post_shutdown_scripts():
|
||||
debug("Running post-shutdown scripts...")
|
||||
|
||||
# Run /etc/my_init.post_shutdown.d/*
|
||||
for name in listdir("/etc/my_init.post_shutdown.d"):
|
||||
filename = "/etc/my_init.post_shutdown.d/" + name
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable(filename)
|
||||
|
||||
|
||||
def start_runit():
|
||||
info("Booting runit daemon...")
|
||||
pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir",
|
||||
"-P", "/etc/service")
|
||||
info("Runit started as PID %d" % pid)
|
||||
return pid
|
||||
|
||||
|
||||
def wait_for_runit_or_interrupt(pid):
|
||||
status = waitpid_reap_other_children(pid)
|
||||
return (True, status)
|
||||
|
||||
|
||||
def shutdown_runit_services(quiet=False):
|
||||
if not quiet:
|
||||
debug("Begin shutting down runit services...")
|
||||
os.system("/usr/bin/sv -w %d force-stop /etc/service/* > /dev/null" % KILL_PROCESS_TIMEOUT)
|
||||
|
||||
|
||||
def wait_for_runit_services():
|
||||
debug("Waiting for runit services to exit...")
|
||||
done = False
|
||||
while not done:
|
||||
done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0
|
||||
if not done:
|
||||
time.sleep(0.1)
|
||||
# According to https://github.com/phusion/baseimage-docker/issues/315
|
||||
# there is a bug or race condition in Runit, causing it
|
||||
# not to shutdown services that are already being started.
|
||||
# So during shutdown we repeatedly instruct Runit to shutdown
|
||||
# services.
|
||||
shutdown_runit_services(True)
|
||||
|
||||
|
||||
def install_insecure_key():
|
||||
info("Installing insecure SSH key for user root")
|
||||
run_command_killable("/usr/sbin/enable_insecure_key")
|
||||
|
||||
|
||||
def main(args):
|
||||
import_envvars(False, False)
|
||||
export_envvars()
|
||||
|
||||
if args.enable_insecure_key:
|
||||
install_insecure_key()
|
||||
|
||||
if not args.skip_startup_files:
|
||||
run_startup_files()
|
||||
|
||||
runit_exited = False
|
||||
exit_code = None
|
||||
|
||||
if not args.skip_runit:
|
||||
runit_pid = start_runit()
|
||||
try:
|
||||
exit_status = None
|
||||
if len(args.main_command) == 0:
|
||||
runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid)
|
||||
if runit_exited:
|
||||
if exit_code is None:
|
||||
info("Runit exited with unknown status")
|
||||
exit_status = 1
|
||||
else:
|
||||
exit_status = os.WEXITSTATUS(exit_code)
|
||||
info("Runit exited with status %d" % exit_status)
|
||||
else:
|
||||
info("Running %s..." % " ".join(args.main_command))
|
||||
pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command)
|
||||
try:
|
||||
exit_code = waitpid_reap_other_children(pid)
|
||||
if exit_code is None:
|
||||
info("%s exited with unknown status." % args.main_command[0])
|
||||
exit_status = 1
|
||||
else:
|
||||
exit_status = os.WEXITSTATUS(exit_code)
|
||||
info("%s exited with status %d." % (args.main_command[0], exit_status))
|
||||
except KeyboardInterrupt:
|
||||
stop_child_process(args.main_command[0], pid)
|
||||
raise
|
||||
except BaseException:
|
||||
warn("An error occurred. Aborting.")
|
||||
stop_child_process(args.main_command[0], pid)
|
||||
raise
|
||||
sys.exit(exit_status)
|
||||
finally:
|
||||
if not args.skip_runit:
|
||||
run_pre_shutdown_scripts()
|
||||
shutdown_runit_services()
|
||||
if not runit_exited:
|
||||
stop_child_process("runit daemon", runit_pid)
|
||||
wait_for_runit_services()
|
||||
run_post_shutdown_scripts()
|
||||
|
||||
# Parse options.
|
||||
parser = argparse.ArgumentParser(description='Initialize the system.')
|
||||
parser.add_argument('main_command', metavar='MAIN_COMMAND', type=str, nargs='*',
|
||||
help='The main command to run. (default: runit)')
|
||||
parser.add_argument('--enable-insecure-key', dest='enable_insecure_key',
|
||||
action='store_const', const=True, default=False,
|
||||
help='Install the insecure SSH key')
|
||||
parser.add_argument('--skip-startup-files', dest='skip_startup_files',
|
||||
action='store_const', const=True, default=False,
|
||||
help='Skip running /etc/my_init.d/* and /etc/rc.local')
|
||||
parser.add_argument('--skip-runit', dest='skip_runit',
|
||||
action='store_const', const=True, default=False,
|
||||
help='Do not run runit services')
|
||||
parser.add_argument('--no-kill-all-on-exit', dest='kill_all_on_exit',
|
||||
action='store_const', const=False, default=True,
|
||||
help='Don\'t kill all processes on the system upon exiting')
|
||||
parser.add_argument('--quiet', dest='log_level',
|
||||
action='store_const', const=LOG_LEVEL_WARN, default=LOG_LEVEL_INFO,
|
||||
help='Only print warnings and errors')
|
||||
args = parser.parse_args()
|
||||
log_level = args.log_level
|
||||
|
||||
if args.skip_runit and len(args.main_command) == 0:
|
||||
error("When --skip-runit is given, you must also pass a main command.")
|
||||
sys.exit(1)
|
||||
|
||||
# Run main function.
|
||||
signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM'))
|
||||
signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT'))
|
||||
signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception())
|
||||
try:
|
||||
main(args)
|
||||
except KeyboardInterrupt:
|
||||
warn("Init system aborted.")
|
||||
exit(2)
|
||||
finally:
|
||||
if args.kill_all_on_exit:
|
||||
kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT)
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
'''
|
||||
Copyright (c) 2013-2015 Phusion Holding B.V.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
import pwd
|
||||
|
||||
|
||||
def abort(message):
|
||||
sys.stderr.write("setuser: %s\n" % message)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
'''
|
||||
A simple alternative to sudo that executes a command as a user by setting
|
||||
the user ID and user parameters to those described by the system and then
|
||||
using execvp(3) to execute the command without the necessity of a TTY
|
||||
'''
|
||||
|
||||
username = sys.argv[1]
|
||||
try:
|
||||
user = pwd.getpwnam(username)
|
||||
except KeyError:
|
||||
abort("user %s not found" % username)
|
||||
os.initgroups(username, user.pw_gid)
|
||||
os.setgid(user.pw_gid)
|
||||
os.setuid(user.pw_uid)
|
||||
os.environ['USER'] = username
|
||||
os.environ['HOME'] = user.pw_dir
|
||||
os.environ['UID'] = str(user.pw_uid)
|
||||
try:
|
||||
os.execvp(sys.argv[2], sys.argv[2:])
|
||||
except OSError as e:
|
||||
abort("cannot execute %s: %s" % (sys.argv[2], str(e)))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.stderr.write("Usage: /sbin/setuser USERNAME COMMAND [args..]\n")
|
||||
sys.exit(1)
|
||||
|
||||
main()
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
export LC_ALL=C
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
minimal_apt_get_install='apt-get install -y --no-install-recommends'
|
||||
|
||||
# Default services
|
||||
# Set 1 to the service you want to disable
|
||||
export DISABLE_SYSLOG=${DISABLE_SYSLOG:-0}
|
||||
export DISABLE_SSH=${DISABLE_SSH:-0}
|
||||
export DISABLE_CRON=${DISABLE_CRON:-0}
|
||||
|
||||
+7
-2
@@ -1,10 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /build/buildconfig
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
apt-get clean
|
||||
rm -rf /build
|
||||
find /bd_build/ -not \( -name 'bd_build' -or -name 'buildconfig' -or -name 'cleanup.sh' \) -delete
|
||||
rm -rf /tmp/* /var/tmp/*
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# clean up python bytecode
|
||||
find / -mount -name *.pyc -delete
|
||||
find / -mount -name *__pycache__* -delete
|
||||
|
||||
rm -f /etc/ssh/ssh_host_*
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
AUTHORIZED_KEYS=/root/.ssh/authorized_keys
|
||||
|
||||
if [[ -e "$AUTHORIZED_KEYS" ]] && grep -q baseimage-docker-insecure-key "$AUTHORIZED_KEYS"; then
|
||||
echo "Insecure key has already been added to $AUTHORIZED_KEYS."
|
||||
else
|
||||
DIR=`dirname "$AUTHORIZED_KEYS"`
|
||||
echo "Creating directory $DIR..."
|
||||
mkdir -p "$DIR"
|
||||
chmod 700 "$DIR"
|
||||
chown root:root "$DIR"
|
||||
echo "Editing $AUTHORIZED_KEYS..."
|
||||
cat /etc/insecure_key.pub > "$AUTHORIZED_KEYS"
|
||||
echo "Success: insecure key has been added to $AUTHORIZED_KEYS"
|
||||
fi
|
||||
-238
@@ -1,238 +0,0 @@
|
||||
#!/usr/bin/python2
|
||||
import os, sys, stat, signal, errno, argparse, time
|
||||
|
||||
KILL_PROCESS_TIMEOUT = 5
|
||||
KILL_ALL_PROCESSES_TIMEOUT = 5
|
||||
|
||||
LOG_LEVEL_ERROR = 1
|
||||
LOG_LEVEL_WARN = 1
|
||||
LOG_LEVEL_INFO = 2
|
||||
LOG_LEVEL_DEBUG = 3
|
||||
|
||||
log_level = None
|
||||
|
||||
class AlarmException(Exception):
|
||||
pass
|
||||
|
||||
def error(message):
|
||||
if log_level >= LOG_LEVEL_ERROR:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
def warn(message):
|
||||
if log_level >= LOG_LEVEL_WARN:
|
||||
print("*** %s" % message)
|
||||
|
||||
def info(message):
|
||||
if log_level >= LOG_LEVEL_INFO:
|
||||
print("*** %s" % message)
|
||||
|
||||
def debug(message):
|
||||
if log_level >= LOG_LEVEL_DEBUG:
|
||||
print("*** %s" % message)
|
||||
|
||||
def ignore_signals_and_raise_keyboard_interrupt(signame):
|
||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
raise KeyboardInterrupt(signame)
|
||||
|
||||
def raise_alarm_exception():
|
||||
raise AlarmException('Alarm')
|
||||
|
||||
def listdir(path):
|
||||
try:
|
||||
result = os.stat(path)
|
||||
except OSError:
|
||||
return []
|
||||
if stat.S_ISDIR(result.st_mode):
|
||||
return sorted(os.listdir(path))
|
||||
else:
|
||||
return []
|
||||
|
||||
def is_exe(path):
|
||||
try:
|
||||
return os.path.isfile(path) and os.access(path, os.X_OK)
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
def waitpid_reap_other_children(pid):
|
||||
done = False
|
||||
status = None
|
||||
while not done:
|
||||
this_pid, status = os.waitpid(-1, 0)
|
||||
done = this_pid == pid
|
||||
return status
|
||||
|
||||
def stop_child_process(name, pid, signo = signal.SIGTERM, time_limit = KILL_PROCESS_TIMEOUT):
|
||||
info("Shutting down %s (PID %d)..." % (name, pid))
|
||||
try:
|
||||
os.kill(pid, signo)
|
||||
except OSError:
|
||||
pass
|
||||
signal.alarm(time_limit)
|
||||
try:
|
||||
try:
|
||||
waitpid_reap_other_children(pid)
|
||||
except OSError:
|
||||
pass
|
||||
except AlarmException:
|
||||
warn("%s (PID %d) did not shut down in time. Forcing it to exit.")
|
||||
try:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
waitpid_reap_other_children(pid)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
def run_command_killable(*argv):
|
||||
filename = argv[0]
|
||||
status = None
|
||||
pid = os.spawnvp(os.P_NOWAIT, filename, argv)
|
||||
try:
|
||||
status = waitpid_reap_other_children(pid)
|
||||
except BaseException as s:
|
||||
warn("An error occurred. Aborting.")
|
||||
stop_child_process(filename, pid)
|
||||
raise
|
||||
if status != 0:
|
||||
error("%s failed with exit code %d\n" % (filename, status))
|
||||
sys.exit(1)
|
||||
|
||||
def kill_all_processes(time_limit):
|
||||
info("Killing all processes...")
|
||||
try:
|
||||
os.kill(-1, signal.SIGTERM)
|
||||
except OSError:
|
||||
pass
|
||||
signal.alarm(time_limit)
|
||||
try:
|
||||
# Wait until no more child processes exist.
|
||||
done = False
|
||||
while not done:
|
||||
try:
|
||||
os.waitpid(-1, 0)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ECHILD:
|
||||
done = True
|
||||
else:
|
||||
raise
|
||||
except AlarmException:
|
||||
warn("Not all processes have exited in time. Forcing them to exit.")
|
||||
try:
|
||||
os.kill(-1, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
def run_startup_files():
|
||||
# Run /etc/my_init.d/*
|
||||
for name in listdir("/etc/my_init.d"):
|
||||
filename = "/etc/my_init.d/" + name
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable(filename)
|
||||
|
||||
# Run /etc/rc.local.
|
||||
if is_exe("/etc/rc.local"):
|
||||
info("Running /etc/rc.local...")
|
||||
run_command_killable("/etc/rc.local")
|
||||
|
||||
def start_runit():
|
||||
info("Booting runit daemon...")
|
||||
pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir",
|
||||
"-P", "/etc/service", "log: %s" % ('.' * 395))
|
||||
info("Runit started as PID %d" % pid)
|
||||
return pid
|
||||
|
||||
def wait_for_runit_or_interrupt(pid):
|
||||
try:
|
||||
status = waitpid_reap_other_children(pid)
|
||||
return (True, status)
|
||||
except KeyboardInterrupt:
|
||||
return (False, None)
|
||||
|
||||
def shutdown_runit_services():
|
||||
debug("Begin shutting down runit services...")
|
||||
os.system("/usr/bin/sv down /etc/service/*")
|
||||
|
||||
def wait_for_runit_services():
|
||||
debug("Waiting for runit services to exit...")
|
||||
done = False
|
||||
while not done:
|
||||
done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0
|
||||
if not done:
|
||||
time.sleep(0.1)
|
||||
|
||||
def main(args):
|
||||
if not args.skip_startup_files:
|
||||
run_startup_files()
|
||||
|
||||
runit_exited = False
|
||||
exit_code = None
|
||||
|
||||
if not args.skip_runit:
|
||||
runit_pid = start_runit()
|
||||
try:
|
||||
if len(args.main_command) == 0:
|
||||
runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid)
|
||||
if runit_exited:
|
||||
info("Runit exited with code %d" % exit_code)
|
||||
else:
|
||||
info("Running %s..." % " ".join(args.main_command))
|
||||
pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command)
|
||||
try:
|
||||
exit_code = waitpid_reap_other_children(pid)
|
||||
info("%s exited with exit code %d." % (args.main_command[0], exit_code))
|
||||
except KeyboardInterrupt:
|
||||
stop_child_process(args.main_command[0], pid)
|
||||
except BaseException as s:
|
||||
warn("An error occurred. Aborting.")
|
||||
stop_child_process(args.main_command[0], pid)
|
||||
raise
|
||||
sys.exit(exit_code)
|
||||
finally:
|
||||
if not args.skip_runit:
|
||||
shutdown_runit_services()
|
||||
if not runit_exited:
|
||||
stop_child_process("runit daemon", runit_pid)
|
||||
wait_for_runit_services()
|
||||
|
||||
# Parse options.
|
||||
parser = argparse.ArgumentParser(description = 'Initialize the system.')
|
||||
parser.add_argument('main_command', metavar = 'MAIN_COMMAND', type = str, nargs = '*',
|
||||
help = 'The main command to run. (default: runit)')
|
||||
parser.add_argument('--skip-startup-files', dest = 'skip_startup_files',
|
||||
action = 'store_const', const = True, default = False,
|
||||
help = 'Skip running /etc/my_init.d/* and /etc/rc.local')
|
||||
parser.add_argument('--skip-runit', dest = 'skip_runit',
|
||||
action = 'store_const', const = True, default = False,
|
||||
help = 'Do not run runit services')
|
||||
parser.add_argument('--no-kill-all-on-exit', dest = 'kill_all_on_exit',
|
||||
action = 'store_const', const = False, default = True,
|
||||
help = 'Don\'t kill all processes on the system upon exiting')
|
||||
parser.add_argument('--quiet', dest = 'log_level',
|
||||
action = 'store_const', const = LOG_LEVEL_WARN, default = LOG_LEVEL_INFO,
|
||||
help = 'Only print warnings and errors')
|
||||
args = parser.parse_args()
|
||||
log_level = args.log_level
|
||||
|
||||
if args.skip_runit and len(args.main_command) == 0:
|
||||
error("When --skip-runit is given, you must also pass a main command.")
|
||||
sys.exit(1)
|
||||
|
||||
# Run main function.
|
||||
signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM'))
|
||||
signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT'))
|
||||
signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception())
|
||||
try:
|
||||
main(args)
|
||||
except KeyboardInterrupt:
|
||||
warn("Init system aborted.")
|
||||
exit(2)
|
||||
finally:
|
||||
if args.kill_all_on_exit:
|
||||
kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT)
|
||||
+43
-11
@@ -1,25 +1,57 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /build/buildconfig
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
## Enable Ubuntu Universe.
|
||||
echo deb http://archive.ubuntu.com/ubuntu precise main universe > /etc/apt/sources.list
|
||||
echo deb http://archive.ubuntu.com/ubuntu precise-updates main universe >> /etc/apt/sources.list
|
||||
apt-get update
|
||||
## Prevent initramfs updates from trying to run grub and lilo.
|
||||
## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/
|
||||
## http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594189
|
||||
export INITRD=no
|
||||
mkdir -p /etc/container_environment
|
||||
echo -n no > /etc/container_environment/INITRD
|
||||
|
||||
## Install HTTPS support for APT.
|
||||
$minimal_apt_get_install apt-transport-https
|
||||
## Enable Ubuntu Universe, Multiverse, and deb-src for main.
|
||||
sed -i 's/^#\s*\(deb.*main restricted\)$/\1/g' /etc/apt/sources.list
|
||||
sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
|
||||
sed -i 's/^#\s*\(deb.*multiverse\)$/\1/g' /etc/apt/sources.list
|
||||
apt-get update
|
||||
|
||||
## Fix some issues with APT packages.
|
||||
## See https://github.com/dotcloud/docker/issues/1024
|
||||
dpkg-divert --local --rename --add /sbin/initctl
|
||||
ln -sf /bin/true /sbin/initctl
|
||||
|
||||
## Replace the 'ischroot' tool to make it always return true.
|
||||
## Prevent initscripts updates from breaking /dev/shm.
|
||||
## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/
|
||||
## https://bugs.launchpad.net/launchpad/+bug/974584
|
||||
dpkg-divert --local --rename --add /usr/bin/ischroot
|
||||
ln -sf /bin/true /usr/bin/ischroot
|
||||
|
||||
# apt-utils fix for Ubuntu 16.04
|
||||
$minimal_apt_get_install apt-utils
|
||||
|
||||
## Install HTTPS support for APT.
|
||||
$minimal_apt_get_install apt-transport-https ca-certificates
|
||||
|
||||
## Install add-apt-repository
|
||||
$minimal_apt_get_install software-properties-common
|
||||
|
||||
## Upgrade all packages.
|
||||
echo "initscripts hold" | dpkg --set-selections
|
||||
apt-get upgrade -y --no-install-recommends
|
||||
apt-get dist-upgrade -y --no-install-recommends -o Dpkg::Options::="--force-confold"
|
||||
|
||||
## Fix locale.
|
||||
$minimal_apt_get_install language-pack-en
|
||||
locale-gen en_US
|
||||
case $(lsb_release -is) in
|
||||
Ubuntu)
|
||||
$minimal_apt_get_install language-pack-en language-pack-fr
|
||||
;;
|
||||
Debian)
|
||||
$minimal_apt_get_install locales locales-all
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
locale-gen fr_FR
|
||||
update-locale LANG=fr_FR.UTF-8 LC_CTYPE=fr_FR.UTF-8
|
||||
echo -n fr_FR.UTF-8 > /etc/container_environment/LANG
|
||||
echo -n fr_FR.UTF-8 > /etc/container_environment/LC_CTYPE
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
exec /usr/sbin/cron -f
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
exec syslog-ng -F -p /var/run/syslog-ng.pid
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Touch cron files to fix 'NUMBER OF HARD LINKS > 1' issue. See https://github.com/phusion/baseimage-docker/issues/198
|
||||
touch -c /var/spool/cron/crontabs/*
|
||||
touch -c /etc/crontab
|
||||
touch -c /etc/cron.d/* /etc/cron.daily/* /etc/cron.hourly/* /etc/cron.monthly/* /etc/cron.weekly/*
|
||||
|
||||
exec /usr/sbin/cron -f
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
$minimal_apt_get_install cron
|
||||
mkdir /etc/service/cron
|
||||
chmod 600 /etc/crontab
|
||||
cp /bd_build/services/cron/cron.runit /etc/service/cron/run
|
||||
# Fix cron issues in 0.9.19, see also #345: https://github.com/phusion/baseimage-docker/issues/345
|
||||
sed -i 's/^\s*session\s\+required\s\+pam_loginuid.so/# &/' /etc/pam.d/cron
|
||||
|
||||
## Remove useless cron entries.
|
||||
# Checks for lost+found and scans for mtab.
|
||||
rm -f /etc/cron.daily/standard
|
||||
rm -f /etc/cron.daily/upstart
|
||||
rm -f /etc/cron.daily/dpkg
|
||||
rm -f /etc/cron.daily/password
|
||||
rm -f /etc/cron.weekly/fstrim
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
if [[ ! -e /etc/service/sshd/down && ! -e /etc/ssh/ssh_host_rsa_key ]] || [[ "$1" == "-f" ]]; then
|
||||
echo "No SSH host key available. Generating one..."
|
||||
export LC_ALL=C
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
dpkg-reconfigure openssh-server
|
||||
fi
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
AUTHORIZED_KEYS=/root/.ssh/authorized_keys
|
||||
|
||||
if [[ -e "$AUTHORIZED_KEYS" ]] && grep -q baseimage-docker-insecure-key "$AUTHORIZED_KEYS"; then
|
||||
echo "Insecure key has already been added to $AUTHORIZED_KEYS."
|
||||
else
|
||||
DIR=`dirname "$AUTHORIZED_KEYS"`
|
||||
echo "Creating directory $DIR..."
|
||||
mkdir -p "$DIR"
|
||||
chmod 700 "$DIR"
|
||||
chown root:root "$DIR"
|
||||
echo "Editing $AUTHORIZED_KEYS..."
|
||||
cat /etc/insecure_key.pub >> "$AUTHORIZED_KEYS"
|
||||
echo "Success: insecure key has been added to $AUTHORIZED_KEYS"
|
||||
cat <<-EOF
|
||||
|
||||
+------------------------------------------------------------------------------+
|
||||
| Insecure SSH key installed |
|
||||
| |
|
||||
| DO NOT expose port 22 on the Internet unless you know what you are doing! |
|
||||
| |
|
||||
| Use the private key below to connect with user root |
|
||||
+------------------------------------------------------------------------------+
|
||||
|
||||
EOF
|
||||
cat /etc/insecure_key
|
||||
echo -e "\n\n"
|
||||
fi
|
||||
@@ -0,0 +1,26 @@
|
||||
PuTTY-User-Key-File-2: ssh-rsa
|
||||
Encryption: none
|
||||
Comment: imported-openssh-key
|
||||
Public-Lines: 6
|
||||
AAAAB3NzaC1yc2EAAAADAQABAAABAQDVmzBG5v7cO9IScGLIzlhGlHNFhXzy87Vf
|
||||
aPzru7qnIIdQ1e9FEKvtqEws8hVixnCUdviwX5lvcMk4Ef4Tbrmj3dyF0zFtYbji
|
||||
TSyl/XQlF68DQlc2sTAdHy96wJHvh7ky511tKJzzyWwSqeef4WjeVK28TqcGnq1u
|
||||
p0S7saFO0dJh6OfDAg2cDmhyweR3VgT0vZJyrDV7hte95MBCdK+Gp7fdCyEZcWm3
|
||||
S1DBFaeBqHzzt/Y/njAVKbYL9TIVPum8iMg0rMiLi9ShfP+dT5Xud5Oa3dcN2OWh
|
||||
iDfJw5pfhFJWd44cJ/uGRwQpvNs/PNKsYABhgLlTMUH4iawhu1Xb
|
||||
Private-Lines: 14
|
||||
AAABAQCjROxgtX2Gft7yIx8Ol9IXmK6HLCI2XZt7ovb3hFWGGzHy0qMBql2P2Tzo
|
||||
ed1o038Hq+woe9n+uTnEdtQ6rD6PByzgyW2VSsWTjCOdeJ5HH9Qw7ItXDZZWHBkh
|
||||
fYHOkXI4e2oI3qshGAtYNLALn7KVhioJriCyyaSM2KOLx5khcY+EJ1inQfwQJKqP
|
||||
GsdKc72liz07T8ifRj+mNLKtwrxlK3IXYfIdgLp/1pCKdrC80DhprMsD4xvNgq4p
|
||||
CR9jd4FoqM9t/Up5ppTm+p6A/bDwdIPh6cFFeyMP+G3+bTlW1Gg7RLoNCc6qh53W
|
||||
WVgEOQqdLHcQ8Ge4RLmbwLUmnRuRAAAAgQD312H46T2YvKzyEKbsddwbO8WktfxW
|
||||
vVqqxH6z6bRXVFR3hQhmPKjlFXsD74h3W7NJwe9WJ5Pf3vemoBWIo0Hak0M1Z6WC
|
||||
OIvBohpOYDzIgdlGHifx2ZiAd47Vsn+mfxjtISdWupl9Fw98yRjahWosKmmIHTtR
|
||||
cIfYHB9ztpR8owAAAIEA3KNMYMFgenE+7q4pwat4t3RKA7rU8SPto5I1+sEHY8rz
|
||||
cD7ONkIVlEhaqN+uTEYbr5rZa4dsQe4Ia+7ZXmO4djFsAP/fyJX+VCX/bHK83V5H
|
||||
9toTdRLTqqfqJ3GOeZ41kPIN6UDHVEa4S8tfVM0DMNPEHBjLMfdbZGkoBQAPXWkA
|
||||
AACBAJV/Bxr1jJohvmURQf/9y6MvO2wcRpTdKVLQhEnGm2cXQdh5CPVae2K+u0CG
|
||||
d8u0/PDIZMGpueCQo4lft02W0skTDo5Kn+1IUwmQuoRzanVJ5ab+GyVnlouRLp/J
|
||||
bWMQZ3pjXNkBsQOK/igrKYvqUb1jRsy9zxVQRl4i7JjjLpe/
|
||||
Private-MAC: ef1e472b5254ae2c5319a522d39ad31d432dde75
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
SSHD_BUILD_PATH=/bd_build/services/sshd
|
||||
|
||||
## Install the SSH server.
|
||||
$minimal_apt_get_install openssh-server
|
||||
mkdir /var/run/sshd
|
||||
mkdir /etc/service/sshd
|
||||
touch /etc/service/sshd/down
|
||||
cp $SSHD_BUILD_PATH/sshd.runit /etc/service/sshd/run
|
||||
cp $SSHD_BUILD_PATH/sshd_config /etc/ssh/sshd_config
|
||||
cp $SSHD_BUILD_PATH/00_regen_ssh_host_keys.sh /etc/my_init.d/
|
||||
|
||||
## Install default SSH key for root and app.
|
||||
mkdir -p /root/.ssh
|
||||
chmod 700 /root/.ssh
|
||||
chown root:root /root/.ssh
|
||||
cp $SSHD_BUILD_PATH/keys/insecure_key.pub /etc/insecure_key.pub
|
||||
cp $SSHD_BUILD_PATH/keys/insecure_key /etc/insecure_key
|
||||
chmod 644 /etc/insecure_key*
|
||||
chown root:root /etc/insecure_key*
|
||||
cp $SSHD_BUILD_PATH/enable_insecure_key /usr/sbin/
|
||||
@@ -84,8 +84,8 @@ ChallengeResponseAuthentication no
|
||||
#GSSAPIStrictAcceptorCheck yes
|
||||
#GSSAPIKeyExchange no
|
||||
|
||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
# Set this to 'yes' to enable PAM authentication, account processing,
|
||||
# and session processing. If this is enabled, PAM authentication will
|
||||
# be allowed through the ChallengeResponseAuthentication and
|
||||
# PasswordAuthentication. Depending on your PAM configuration,
|
||||
# PAM authentication via ChallengeResponseAuthentication may bypass
|
||||
@@ -101,7 +101,7 @@ ChallengeResponseAuthentication no
|
||||
#AllowAgentForwarding yes
|
||||
#AllowTcpForwarding yes
|
||||
#GatewayPorts no
|
||||
#X11Forwarding no
|
||||
X11Forwarding yes
|
||||
#X11DisplayOffset 10
|
||||
#X11UseLocalhost yes
|
||||
#PrintMotd yes
|
||||
@@ -123,13 +123,10 @@ ChallengeResponseAuthentication no
|
||||
#Banner none
|
||||
|
||||
# override default of no subsystems
|
||||
Subsystem sftp /usr/lib/sftp-server
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
|
||||
# Example of overriding settings on a per-user basis
|
||||
#Match User anoncvs
|
||||
# X11Forwarding no
|
||||
# AllowTcpForwarding no
|
||||
# ForceCommand cvs server
|
||||
|
||||
# XAuthLocation added by XQuartz (http://xquartz.macosforge.org)
|
||||
XAuthLocation /opt/X11/bin/xauth
|
||||
@@ -0,0 +1,36 @@
|
||||
# see "man logrotate" for details
|
||||
# rotate log files weekly
|
||||
weekly
|
||||
|
||||
# use the syslog group by default, since this is the owning group
|
||||
# of /var/log/syslog.
|
||||
# su root syslog
|
||||
|
||||
# keep 4 weeks worth of backlogs
|
||||
rotate 4
|
||||
|
||||
# create new (empty) log files after rotating old ones
|
||||
create
|
||||
|
||||
# uncomment this if you want your log files compressed
|
||||
#compress
|
||||
|
||||
# packages drop log rotation information into this directory
|
||||
include /etc/logrotate.d
|
||||
|
||||
# no packages own wtmp, or btmp -- we'll rotate them here
|
||||
/var/log/wtmp {
|
||||
missingok
|
||||
monthly
|
||||
create 0664 root utmp
|
||||
rotate 1
|
||||
}
|
||||
|
||||
/var/log/btmp {
|
||||
missingok
|
||||
monthly
|
||||
create 0660 root utmp
|
||||
rotate 1
|
||||
}
|
||||
|
||||
# system-specific logs may be configured here
|
||||
@@ -0,0 +1,39 @@
|
||||
/var/log/syslog {
|
||||
rotate 7
|
||||
daily
|
||||
missingok
|
||||
notifempty
|
||||
delaycompress
|
||||
compress
|
||||
postrotate
|
||||
if [ -f /var/run/syslog-ng.pid ]; then
|
||||
kill -HUP `cat /var/run/syslog-ng.pid`
|
||||
fi
|
||||
endscript
|
||||
}
|
||||
|
||||
/var/log/mail.info
|
||||
/var/log/mail.warn
|
||||
/var/log/mail.err
|
||||
/var/log/mail.log
|
||||
/var/log/daemon.log
|
||||
/var/log/kern.log
|
||||
/var/log/auth.log
|
||||
/var/log/user.log
|
||||
/var/log/lpr.log
|
||||
/var/log/cron.log
|
||||
/var/log/debug
|
||||
/var/log/messages {
|
||||
rotate 4
|
||||
weekly
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
delaycompress
|
||||
sharedscripts
|
||||
postrotate
|
||||
if [ -f /var/run/syslog-ng.pid ]; then
|
||||
kill -HUP `cat /var/run/syslog-ng.pid`
|
||||
fi
|
||||
endscript
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
@version: 3.13
|
||||
@include "scl.conf"
|
||||
|
||||
# Syslog-ng configuration file, compatible with default Debian syslogd
|
||||
# installation.
|
||||
|
||||
# First, set some global options.
|
||||
options { chain_hostnames(off); flush_lines(0); use_dns(no); use_fqdn(no);
|
||||
owner("root"); group("adm"); perm(0640); stats_freq(0);
|
||||
bad_hostname("^gconfd$");
|
||||
};
|
||||
|
||||
########################
|
||||
# Sources
|
||||
########################
|
||||
# This is the default behavior of sysklogd package
|
||||
# Logs may come from unix stream, but not from another machine.
|
||||
#
|
||||
source s_src {
|
||||
unix-dgram("/dev/log");
|
||||
internal();
|
||||
};
|
||||
|
||||
# If you wish to get logs from remote machine you should uncomment
|
||||
# this and comment the above source line.
|
||||
#
|
||||
#source s_net { tcp(ip(127.0.0.1) port(1000)); };
|
||||
|
||||
########################
|
||||
# Destinations
|
||||
########################
|
||||
# First some standard logfile
|
||||
#
|
||||
destination d_auth { file("/var/log/auth.log"); };
|
||||
destination d_cron { file("/var/log/cron.log"); };
|
||||
destination d_daemon { file("/var/log/daemon.log"); };
|
||||
destination d_kern { file("/var/log/kern.log"); };
|
||||
destination d_lpr { file("/var/log/lpr.log"); };
|
||||
destination d_mail { file("/var/log/mail.log"); };
|
||||
destination d_syslog { file("/var/log/syslog"); };
|
||||
destination d_user { file("/var/log/user.log"); };
|
||||
destination d_uucp { file("/var/log/uucp.log"); };
|
||||
|
||||
# This files are the log come from the mail subsystem.
|
||||
#
|
||||
destination d_mailinfo { file("/var/log/mail.info"); };
|
||||
destination d_mailwarn { file("/var/log/mail.warn"); };
|
||||
destination d_mailerr { file("/var/log/mail.err"); };
|
||||
|
||||
# Logging for INN news system
|
||||
#
|
||||
destination d_newscrit { file("/var/log/news/news.crit"); };
|
||||
destination d_newserr { file("/var/log/news/news.err"); };
|
||||
destination d_newsnotice { file("/var/log/news/news.notice"); };
|
||||
|
||||
# Some 'catch-all' logfiles.
|
||||
#
|
||||
destination d_debug { file("/var/log/debug"); };
|
||||
destination d_error { file("/var/log/error"); };
|
||||
destination d_messages { file("/var/log/messages"); };
|
||||
|
||||
# The named pipe /dev/xconsole is for the nsole' utility. To use it,
|
||||
# you must invoke nsole' with the -file' option:
|
||||
#
|
||||
# $ xconsole -file /dev/xconsole [...]
|
||||
#
|
||||
destination d_xconsole { pipe("/dev/xconsole"); };
|
||||
|
||||
# Send the messages to an other host
|
||||
#
|
||||
#destination d_net { tcp("127.0.0.1" port(1000) log_fifo_size(1000)); };
|
||||
|
||||
# Debian only
|
||||
destination d_ppp { file("/var/log/ppp.log"); };
|
||||
|
||||
# stdout for docker
|
||||
destination d_stdout { ##SYSLOG_OUTPUT_MODE_DEV_STDOUT##("/dev/stdout"); };
|
||||
|
||||
########################
|
||||
# Filters
|
||||
########################
|
||||
# Here's come the filter options. With this rules, we can set which
|
||||
# message go where.
|
||||
|
||||
filter f_dbg { level(debug); };
|
||||
filter f_info { level(info); };
|
||||
filter f_notice { level(notice); };
|
||||
filter f_warn { level(warn); };
|
||||
filter f_err { level(err); };
|
||||
filter f_crit { level(crit .. emerg); };
|
||||
|
||||
filter f_debug { level(debug) and not facility(auth, authpriv, news, mail); };
|
||||
filter f_error { level(err .. emerg) ; };
|
||||
filter f_messages { level(info,notice,warn) and
|
||||
not facility(auth,authpriv,cron,daemon,mail,news); };
|
||||
|
||||
filter f_auth { facility(auth, authpriv) and not filter(f_debug); };
|
||||
filter f_cron { facility(cron) and not filter(f_debug); };
|
||||
filter f_daemon { facility(daemon) and not filter(f_debug); };
|
||||
filter f_kern { facility(kern) and not filter(f_debug); };
|
||||
filter f_lpr { facility(lpr) and not filter(f_debug); };
|
||||
filter f_local { facility(local0, local1, local3, local4, local5,
|
||||
local6, local7) and not filter(f_debug); };
|
||||
filter f_mail { facility(mail) and not filter(f_debug); };
|
||||
filter f_news { facility(news) and not filter(f_debug); };
|
||||
filter f_syslog3 { not facility(auth, authpriv, mail) and not filter(f_debug); };
|
||||
filter f_user { facility(user) and not filter(f_debug); };
|
||||
filter f_uucp { facility(uucp) and not filter(f_debug); };
|
||||
|
||||
filter f_cnews { level(notice, err, crit) and facility(news); };
|
||||
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };
|
||||
|
||||
filter f_ppp { facility(local2) and not filter(f_debug); };
|
||||
filter f_console { level(warn .. emerg); };
|
||||
|
||||
########################
|
||||
# Log paths
|
||||
########################
|
||||
log { source(s_src); filter(f_auth); destination(d_auth); };
|
||||
log { source(s_src); filter(f_cron); destination(d_cron); };
|
||||
log { source(s_src); filter(f_daemon); destination(d_daemon); };
|
||||
log { source(s_src); filter(f_kern); destination(d_kern); };
|
||||
log { source(s_src); filter(f_lpr); destination(d_lpr); };
|
||||
log { source(s_src); filter(f_syslog3); destination(d_syslog); destination(d_stdout); };
|
||||
log { source(s_src); filter(f_user); destination(d_user); };
|
||||
log { source(s_src); filter(f_uucp); destination(d_uucp); };
|
||||
|
||||
log { source(s_src); filter(f_mail); destination(d_mail); };
|
||||
#log { source(s_src); filter(f_mail); filter(f_info); destination(d_mailinfo); };
|
||||
#log { source(s_src); filter(f_mail); filter(f_warn); destination(d_mailwarn); };
|
||||
#log { source(s_src); filter(f_mail); filter(f_err); destination(d_mailerr); };
|
||||
|
||||
log { source(s_src); filter(f_news); filter(f_crit); destination(d_newscrit); };
|
||||
log { source(s_src); filter(f_news); filter(f_err); destination(d_newserr); };
|
||||
log { source(s_src); filter(f_news); filter(f_notice); destination(d_newsnotice); };
|
||||
#log { source(s_src); filter(f_cnews); destination(d_console_all); };
|
||||
#log { source(s_src); filter(f_cother); destination(d_console_all); };
|
||||
|
||||
#log { source(s_src); filter(f_ppp); destination(d_ppp); };
|
||||
|
||||
log { source(s_src); filter(f_debug); destination(d_debug); };
|
||||
log { source(s_src); filter(f_error); destination(d_error); };
|
||||
log { source(s_src); filter(f_messages); destination(d_messages); };
|
||||
|
||||
# All messages send to a remote site
|
||||
#
|
||||
#log { source(s_src); destination(d_net); };
|
||||
|
||||
###
|
||||
# Include all config files in /etc/syslog-ng/conf.d/
|
||||
###
|
||||
@include "/etc/syslog-ng/conf.d/*.conf"
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
set -em
|
||||
|
||||
# If /dev/log is either a named pipe or it was placed there accidentally,
|
||||
# e.g. because of the issue documented at https://github.com/phusion/baseimage-docker/pull/25,
|
||||
# then we remove it.
|
||||
if [ ! -S /dev/log ]; then rm -f /dev/log; fi
|
||||
if [ ! -S /var/lib/syslog-ng/syslog-ng.ctl ]; then rm -f /var/lib/syslog-ng/syslog-ng.ctl; fi
|
||||
|
||||
# determine output mode on /dev/stdout because of the issue documented at https://github.com/phusion/baseimage-docker/issues/468
|
||||
if [ -p /dev/stdout ]; then
|
||||
sed -i 's/##SYSLOG_OUTPUT_MODE_DEV_STDOUT##/pipe/' /etc/syslog-ng/syslog-ng.conf
|
||||
else
|
||||
sed -i 's/##SYSLOG_OUTPUT_MODE_DEV_STDOUT##/file/' /etc/syslog-ng/syslog-ng.conf
|
||||
fi
|
||||
|
||||
# If /var/log is writable by another user logrotate will fail
|
||||
/bin/chown root:root /var/log
|
||||
/bin/chmod 0755 /var/log
|
||||
|
||||
PIDFILE="/var/run/syslog-ng.pid"
|
||||
SYSLOGNG_OPTS=""
|
||||
|
||||
[ -r /etc/default/syslog-ng ] && . /etc/default/syslog-ng
|
||||
|
||||
syslogng_wait() {
|
||||
if [ "$2" -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
RET=1
|
||||
for i in $(seq 1 30); do
|
||||
status=0
|
||||
syslog-ng-ctl stats >/dev/null 2>&1 || status=$?
|
||||
if [ "$status" != "$1" ]; then
|
||||
RET=0
|
||||
break
|
||||
fi
|
||||
sleep 1s
|
||||
done
|
||||
return $RET
|
||||
}
|
||||
|
||||
/usr/sbin/syslog-ng --pidfile "$PIDFILE" -F $SYSLOGNG_OPTS &
|
||||
syslogng_wait 1 $?
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
SYSLOG_NG_BUILD_PATH=/bd_build/services/syslog-ng
|
||||
|
||||
## Install a syslog daemon.
|
||||
$minimal_apt_get_install syslog-ng-core
|
||||
cp $SYSLOG_NG_BUILD_PATH/syslog-ng.init /etc/my_init.d/10_syslog-ng.init
|
||||
cp $SYSLOG_NG_BUILD_PATH/syslog-ng.shutdown /etc/my_init.post_shutdown.d/10_syslog-ng.shutdown
|
||||
mkdir -p /var/lib/syslog-ng
|
||||
cp $SYSLOG_NG_BUILD_PATH/syslog_ng_default /etc/default/syslog-ng
|
||||
touch /var/log/syslog
|
||||
chmod u=rw,g=r,o= /var/log/syslog
|
||||
cp $SYSLOG_NG_BUILD_PATH/syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
|
||||
|
||||
## Install logrotate.
|
||||
$minimal_apt_get_install logrotate
|
||||
cp $SYSLOG_NG_BUILD_PATH/logrotate.conf /etc/logrotate.conf
|
||||
cp $SYSLOG_NG_BUILD_PATH/logrotate_syslogng /etc/logrotate.d/syslog-ng
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
PIDFILE="/var/run/syslog-ng.pid"
|
||||
|
||||
syslogng_wait() {
|
||||
if [ "$2" -ne 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
RET=1
|
||||
for i in $(seq 1 30); do
|
||||
status=0
|
||||
syslog-ng-ctl stats >/dev/null 2>&1 || status=$?
|
||||
if [ "$status" != "$1" ]; then
|
||||
RET=0
|
||||
break
|
||||
fi
|
||||
sleep 1s
|
||||
done
|
||||
return $RET
|
||||
}
|
||||
|
||||
if [ -f "$PIDFILE" ]; then
|
||||
kill $(cat "$PIDFILE")
|
||||
fi
|
||||
|
||||
syslogng_wait 0 $?
|
||||
@@ -0,0 +1,12 @@
|
||||
# If a variable is not set here, then the corresponding
|
||||
# parameter will not be changed.
|
||||
# If a variables is set, then every invocation of
|
||||
# syslog-ng's init script will set them using dmesg.
|
||||
|
||||
# log level of messages which should go to console
|
||||
# see syslog(3) for details
|
||||
#
|
||||
#CONSOLE_LOG_LEVEL=1
|
||||
|
||||
# Command line options to syslog-ng
|
||||
SYSLOGNG_OPTS="--no-caps"
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/usr/bin/python2
|
||||
import sys, os, pwd
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.stderr.write("Usage: /sbin/setuser USERNAME COMMAND [args..]\n")
|
||||
sys.exit(1)
|
||||
|
||||
def abort(message):
|
||||
sys.stderr.write("setuser: %s\n" % message)
|
||||
sys.exit(1)
|
||||
|
||||
username = sys.argv[1]
|
||||
try:
|
||||
user = pwd.getpwnam(username)
|
||||
except KeyError:
|
||||
abort("user %s not found" % username)
|
||||
os.initgroups(username, user.pw_gid)
|
||||
os.setgid(user.pw_gid)
|
||||
os.setuid(user.pw_uid)
|
||||
os.environ['USER'] = username
|
||||
os.environ['HOME'] = user.pw_dir
|
||||
os.environ['UID'] = str(user.pw_uid)
|
||||
try:
|
||||
os.execvp(sys.argv[2], sys.argv[2:])
|
||||
except OSError as e:
|
||||
abort("cannot execute %s: %s" % (sys.argv[2], str(e)))
|
||||
+17
-25
@@ -1,39 +1,31 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /build/buildconfig
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
## Install init process.
|
||||
cp /build/my_init /sbin/
|
||||
cp /bd_build/bin/my_init /sbin/
|
||||
mkdir -p /etc/my_init.d
|
||||
mkdir -p /etc/my_init.pre_shutdown.d
|
||||
mkdir -p /etc/my_init.post_shutdown.d
|
||||
mkdir -p /etc/container_environment
|
||||
touch /etc/container_environment.sh
|
||||
touch /etc/container_environment.json
|
||||
chmod 700 /etc/container_environment
|
||||
|
||||
groupadd -g 8377 docker_env
|
||||
chown :docker_env /etc/container_environment.sh /etc/container_environment.json
|
||||
chmod 640 /etc/container_environment.sh /etc/container_environment.json
|
||||
ln -s /etc/container_environment.sh /etc/profile.d/
|
||||
|
||||
## Install runit.
|
||||
$minimal_apt_get_install runit
|
||||
|
||||
## Install a syslog daemon.
|
||||
$minimal_apt_get_install syslog-ng-core
|
||||
mkdir /etc/service/syslog-ng
|
||||
cp /build/runit/syslog-ng /etc/service/syslog-ng/run
|
||||
mkdir -p /var/lib/syslog-ng
|
||||
## Install a syslog daemon and logrotate.
|
||||
[ "$DISABLE_SYSLOG" -eq 0 ] && /bd_build/services/syslog-ng/syslog-ng.sh || true
|
||||
|
||||
## Install the SSH server.
|
||||
$minimal_apt_get_install openssh-server
|
||||
mkdir /var/run/sshd
|
||||
mkdir /etc/service/sshd
|
||||
cp /build/runit/sshd /etc/service/sshd/run
|
||||
cp /build/config/sshd_config /etc/ssh/sshd_config
|
||||
cp /build/00_regen_ssh_host_keys.sh /etc/my_init.d/
|
||||
|
||||
## Install default SSH key for root and app.
|
||||
mkdir -p /root/.ssh
|
||||
chmod 700 /root/.ssh
|
||||
chown root:root /root/.ssh
|
||||
cp /build/insecure_key.pub /etc/insecure_key.pub
|
||||
chmod 644 /etc/insecure_key.pub
|
||||
chown root:root /etc/insecure_key.pub
|
||||
cp /build/enable_insecure_key /usr/sbin/
|
||||
[ "$DISABLE_SSH" -eq 0 ] && /bd_build/services/sshd/sshd.sh || true
|
||||
|
||||
## Install cron daemon.
|
||||
$minimal_apt_get_install cron
|
||||
mkdir /etc/service/cron
|
||||
cp /build/runit/cron /etc/service/cron/run
|
||||
[ "$DISABLE_CRON" -eq 0 ] && /bd_build/services/cron/cron.sh || true
|
||||
|
||||
+7
-3
@@ -1,10 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source /build/buildconfig
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
## Often used tools.
|
||||
$minimal_apt_get_install curl less nano vim psmisc
|
||||
$minimal_apt_get_install curl less vim-tiny psmisc gpg-agent dirmngr
|
||||
ln -s /usr/bin/vim.tiny /usr/bin/vim
|
||||
|
||||
## This tool runs a command as another user and sets $HOME.
|
||||
cp /build/setuser /sbin/setuser
|
||||
cp /bd_build/bin/setuser /sbin/setuser
|
||||
|
||||
## This tool allows installation of apt packages with automatic cache cleanup.
|
||||
cp /bd_build/bin/install_clean /sbin/install_clean
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
dir=`dirname "$0"`
|
||||
cd "$dir"
|
||||
|
||||
set -x
|
||||
cp tools/docker-bash /usr/local/bin/
|
||||
cp tools/docker-ssh /usr/local/bin/
|
||||
cp tools/baseimage-docker-nsenter /usr/local/bin/
|
||||
mkdir -p /usr/local/share/baseimage-docker
|
||||
cp image/services/sshd/keys/insecure_key /usr/local/share/baseimage-docker/
|
||||
chmod 644 /usr/local/share/baseimage-docker/insecure_key
|
||||
Regular → Executable
+14
-18
@@ -12,31 +12,27 @@ function cleanup()
|
||||
echo " --> Stopping container"
|
||||
docker stop $ID >/dev/null
|
||||
docker rm $ID >/dev/null
|
||||
docker rmi baseimage_test >/dev/null 2>/dev/null
|
||||
}
|
||||
|
||||
PWD=`pwd`
|
||||
|
||||
echo " --> Preparing container"
|
||||
ID=`docker run -d $NAME:$VERSION enable_insecure_key`
|
||||
docker wait $ID >/dev/null
|
||||
docker commit $ID baseimage_test >/dev/null
|
||||
docker rm $ID >/dev/null
|
||||
|
||||
echo " --> Starting container"
|
||||
ID=`docker run -d -v $PWD/test:/test baseimage_test /sbin/my_init`
|
||||
echo " --> Starting insecure container"
|
||||
ID=`docker run -d -p 22 $NAME:$VERSION /sbin/my_init --enable-insecure-key`
|
||||
sleep 1
|
||||
|
||||
echo " --> Obtaining IP"
|
||||
IP=`docker inspect $ID | grep IPAddress | sed -e 's/.*: "//; s/".*//'`
|
||||
if [[ "$IP" = "" ]]; then
|
||||
abort "Unable to obtain container IP"
|
||||
echo " --> Obtaining SSH port number"
|
||||
SSHPORT=`docker inspect --format='{{(index (index .NetworkSettings.Ports "22/tcp") 0).HostPort}}' "$ID"`
|
||||
if [[ "$SSHPORT" = "" ]]; then
|
||||
abort "Unable to obtain container SSH port number"
|
||||
fi
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
echo " --> Enabling SSH in the container"
|
||||
docker exec $ID /etc/my_init.d/00_regen_ssh_host_keys.sh -f
|
||||
docker exec $ID rm /etc/service/sshd/down
|
||||
docker exec $ID sv start /etc/service/sshd
|
||||
sleep 1
|
||||
|
||||
echo " --> Logging into container and running tests"
|
||||
chmod 600 image/insecure_key
|
||||
sleep 1 # Give container some more time to start up.
|
||||
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i image/insecure_key root@$IP \
|
||||
/bin/bash /test/test.sh
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
tools/docker-ssh $ID bash < test/test.sh
|
||||
|
||||
Regular → Executable
@@ -0,0 +1 @@
|
||||
baseimage-docker-nsenter is the nsenter tool taken from https://github.com/jpetazzo/nsenter, commit 10ce18a7a32. It has been stripped in order to make it smaller.
|
||||
Executable
BIN
Binary file not shown.
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
SELFDIR=`dirname "$0"`
|
||||
SELFDIR=`cd "$SELFDIR" && pwd`
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "Usage: docker-bash <CONTAINER_ID> [COMMAND...]"
|
||||
echo "Login to a Baseimage-based Docker container using nsenter." \
|
||||
"If COMMAND is not given, opens an interactive shell." \
|
||||
"Otherwise, runs COMMAND inside the container."
|
||||
}
|
||||
|
||||
if test $# = 0; then
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
CONTAINER_ID="$1"
|
||||
shift
|
||||
|
||||
PID=`docker inspect -f "{{ .State.Pid }}" "$CONTAINER_ID"`
|
||||
if test $# = 0; then
|
||||
exec "$SELFDIR/baseimage-docker-nsenter" --target "$PID" --mount --uts --ipc --net --pid -- /bin/bash -l
|
||||
else
|
||||
exec "$SELFDIR/baseimage-docker-nsenter" --target "$PID" --mount --uts --ipc --net --pid -- "$@"
|
||||
fi
|
||||
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
KNOWN_HOSTS_FILE=
|
||||
IP=
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "Usage: docker-ssh <CONTAINER_ID> [COMMAND...]"
|
||||
echo "Login to a Baseimage-based Docker container using SSH." \
|
||||
"If COMMAND is not given, opens an interactive shell." \
|
||||
"Otherwise, runs COMMAND inside the container."
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
local pids=`jobs -p`
|
||||
if test "$pids" != ""; then
|
||||
kill $pids
|
||||
fi
|
||||
|
||||
if test "$KNOWN_HOSTS_FILE" != ""; then
|
||||
rm -f "$KNOWN_HOSTS_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
if test $# = 0; then
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
CONTAINER_ID="$1"
|
||||
shift
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
if ! test -e ~/.baseimage_docker_insecure_key; then
|
||||
if test -e /usr/local/share/baseimage-docker/insecure_key; then
|
||||
cp /usr/local/share/baseimage-docker/insecure_key ~/.baseimage_docker_insecure_key
|
||||
else
|
||||
dir=`dirname "$0"`
|
||||
dir=`cd "$dir/.." && pwd`
|
||||
if test -e "$dir/image/services/sshd/keys/insecure_key"; then
|
||||
cp "$dir/image/services/sshd/keys/insecure_key" ~/.baseimage_docker_insecure_key
|
||||
else
|
||||
echo "*** ERROR ***: Baseimage-docker insecure key not found." >&2
|
||||
echo "You probably didn't install docker-ssh properly. Please reinstall it:" >&2
|
||||
echo "" >&2
|
||||
echo " curl --fail -L -O https://github.com/phusion/baseimage-docker/archive/master.tar.gz && \\" >&2
|
||||
echo " tar xzf master.tar.gz && \\" >&2
|
||||
echo " sudo ./baseimage-docker-master/install-tools.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
chown "`whoami`": ~/.baseimage_docker_insecure_key
|
||||
chmod 600 ~/.baseimage_docker_insecure_key
|
||||
fi
|
||||
|
||||
KNOWN_HOSTS_FILE=`mktemp /tmp/docker-ssh.XXXXXXXXX`
|
||||
IP=`docker inspect -f "{{ .NetworkSettings.IPAddress }}" "$CONTAINER_ID"`
|
||||
PORT=`docker inspect -f '{{(index (index .NetworkSettings.Ports "22/tcp") 0).HostPort}}' "$CONTAINER_ID"`
|
||||
if test "`uname`" = "Darwin"; then
|
||||
IP="127.0.0.1"
|
||||
else
|
||||
PORT=22
|
||||
fi
|
||||
echo "SSHing into $IP:$PORT"
|
||||
|
||||
# Prevent SSH from warning about adding a host to the known_hosts file.
|
||||
ssh-keyscan "$IP" >"$KNOWN_HOSTS_FILE" 2>&1
|
||||
|
||||
if ! ssh -i ~/.baseimage_docker_insecure_key \
|
||||
-o UserKnownHostsFile="$KNOWN_HOSTS_FILE" \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o PasswordAuthentication=no \
|
||||
-o KbdInteractiveAuthentication=no \
|
||||
-o ChallengeResponseAuthentication=no \
|
||||
-p $PORT \
|
||||
"root@$IP" "$@"
|
||||
then
|
||||
STATUS=$?
|
||||
if test $# = 0; then
|
||||
echo "----------------"
|
||||
echo "It appears that login to the Docker container failed. This could be caused by the following reasons:"
|
||||
echo "- The Docker container you're trying to login to is not based on Baseimage-docker. The docker-ssh tool only works with Baseimage-docker-based containers."
|
||||
echo "- You did not enable the the insecure key inside the container. Please read https://github.com/phusion/baseimage-docker/blob/master/README.md#login to learn how to enable the insecure key."
|
||||
fi
|
||||
exit $STATUS
|
||||
fi
|
||||
Reference in New Issue
Block a user